◎筱米加步枪◎.Blog

Happy coding

Java操作Excel文件之使用JXL 学习笔记

百科上对于JXL的说明:

通过java操作excel表格的工具类库   

支持Excel 95-2000的所有版本   

生成Excel 2000标准格式   

支持字体、数字、日期操作   

能够修饰单元格属性   

支持图像和图表   

应该说以上功能已经能够大致满足我们的需要。最关键的是这套API是纯Java的,并不依赖Windows系统,即使运行在Linux下,它同样能够正确的处理Excel文件。另外需要说明的是,这套API对图形和图表的支持很有限,而且仅仅识别PNG格式。

前几天学习了下,总结备忘下:贴个关于Excel操作类的代码:(需要加入jxl.jar包)

/**
 * 
 * <pre>
 * MS Office Excel 文件操作对象
 * 注:利用第三方包jxl.jar进行操作
 * 注:暂不支持excel2007版本新格式xlsx后缀名
 * 提供操作内容:
 * 1.创建Excel文件
 * 2.读取Excel文件
 * 3.导出(写入)Excel文件
 * 4.判断是否为Excel文件
 * </pre>
 *
 * @author 陈书挺
 * @create 2010-6-12
 * @version v1.0
 *
 * <pre>
 * 修改时间    修改人   修改原因
 * 2010-6-12  陈书挺   新建类
 * 2010-6-13  陈书挺   修改createExcel(String)方法 | 增加createExcel(String, String...)方法
 * </pre>
 *
 */
public class ExcelOperator {
	
	/*
	 * Excel文件后缀名
	 */
	private static final String EXCEL_POSTFIX = ".xls";
	
	/**
	 * 创建指定的文件路径的一个Excel文件<br>
	 * 默认创建3个工作表分别为:Sheet1|Sheet2|Sheet3<br>
	 * 注:只支持xls格式的文件
	 * @param filePath    文件路径
	 * @throws Exception
	 */
	public void createExcel(String filePath) throws Exception{
		this.createExcel(filePath, "Sheet1" , "Sheet2" , "Sheet3");
	}
	
	/**
	 * 创建指定的文件路径的一个Excel文件,并指定工作表名<br>
	 * 注:只支持xls格式的文件
	 * @param filePath    文件路径
	 * @param sheetNames  工作表名数组
	 * @throws Exception
	 */
	public void createExcel(String filePath , String...sheetNames) throws Exception{
		if(!this.isExcel(filePath)){
			throw new Exception("对不起,文件必须是Excel文件,必须是xls格式的文件");
		}
		File file = new File(filePath);
		//工厂方法创建一个可写入的工作薄(WorkBook)
		WritableWorkbook workBook = Workbook.createWorkbook(file);
		//创建一个可写入的工作表(Sheet) 得到的对象为WritableSheet对象              
		//工作表名   工作表在工作簿中的位置
		for (int i = 0; i < sheetNames.length; i++) {
			workBook.createSheet(sheetNames[i], i);
		}
		workBook.write();
		workBook.close();
	}
	
	/**
	 * 读取指定文件路径的Excel文件,以集合方式返回<br>
	 * 说明:读取所有工作表的内容
	 * @param filePath  文件路径
	 * @return  List集合,List集合中的元素表示一个工作表
	 * 			List中存储String[][]数组,一个数组表示存储工作表的内容
	 *          返回文件中的所有内容
	 * @throws Exception
	 */
	public List<String [][]> readExcel(String filePath) throws Exception{
		if(!this.isExcel(filePath)){
			throw new Exception("对不起,文件必须是Excel文件,必须是xls格式的文件");
		}
		List<String [][]> contents = new ArrayList<String[][]>();
		File file = new File(filePath);
		//创建工作薄
		Workbook workBook = Workbook.getWorkbook(file);
		//获取工作表
		Sheet [] sheets = workBook.getSheets();
		if(sheets!=null && sheets.length>0){
			for (int i = 0; i < sheets.length; i++) {
				String[][] content = this.readExcel(filePath, i);
				contents.add(content);
			}
		}
		workBook.close();
		return contents;
	}
	
	/**
	 * 将指定内容写入指定的Excel文件,并指定相应的工作表名
	 * @param filePath   文件路径
	 * @param contents   数据内容
	 * @param sheetName  工作表名
	 * @throws Exception
	 */
	public void writeExcel(String filePath , String [][] contents ,String sheetName) throws Exception{
		if(!this.isExcel(filePath)){
			throw new Exception("对不起,文件必须是Excel文件,必须是xls格式的文件");
		}
		File file = new File(filePath);
		//工厂方法创建一个可写入的工作薄(WorkBook)
		WritableWorkbook workBook = Workbook.createWorkbook(file);
		WritableSheet sheet = workBook.createSheet(sheetName, 0);
		for (int i = 0; i < contents.length; i++) {
			for (int j = 0; j < contents[i].length; j++) {
				sheet.addCell(new Label(j,i,contents[i][j]));
			}
		}
		workBook.write();
		workBook.close();
	}
	
	/**
	 * 将指定内容写入指定的Excel文件,并指定相应的工作表名
	 * @param filePath   文件路径
	 * @param contents   数据内容
	 * @param sheetName  工作表名
	 * @throws Exception
	 */
	public void writeExcel(String filePath , Vector<Vector<String>> contents , String sheetName) throws Exception{
		this.writeExcel(filePath, StringUtils.toStringArray(contents), sheetName);
	}
	
	/**
	 * 读取指定文件路径、指定工作表索引的Excel文件
	 * 
	 * @param filePath   Excel文件路径
	 * @param sheetIndex 工作表索引 从0开始
	 * @return 与Excel结构相似的二维数组,二维数组中存储的是表格中的内容
	 * @throws Exception
	 */
	public String [][] readExcel(String filePath , int sheetIndex) throws Exception{
		if(!this.isExcel(filePath)){
			throw new Exception("文件必须是Excel文件,必须是xls格式的文件");
		}
		File file = new File(filePath);
		//创建工作薄
		Workbook workBook = Workbook.getWorkbook(file);
		//获取工作表
		Sheet [] sheets = workBook.getSheets();
		if(sheetIndex>sheets.length-1){
			throw new Exception("工作表索引["+sheetIndex+"]超出范围");
		}
		
		//获取指定工作表
		Sheet sheet = sheets[sheetIndex];
		//获取当前工作薄的行数
		int rows = sheet.getRows();
		//获取当前工作薄的列数
		int columns = sheet.getColumns();
		//存储Excel中的数据
		String [][] content = new String[rows][columns];
		this.initArrays(content);
		for (int i = 0; i < rows; i++) {
			//得到当前行的所有单元格
			Cell [] cells = sheet.getRow(i);
			if(cells!=null && cells.length>0){
				for (int j= 0; j < cells.length; j++) {
					String cellContent = cells[j].getContents();
					content[i][j]=cellContent;
				}
			}
		}
		workBook.close();
		return content;
	}
	
	/**
	 * 判断指定文件的路径是否是Excel文件
	 * @param filePath  文件的路径 
	 * @return   是否是Excel文件
	 * 			true:是Excel文件
	 * 			false:不是Excel文件
	 */
	public boolean isExcel(String filePath){
		//获取文件后缀名
		String postfix = FileUtils.getPostfix(filePath);
		if(!postfix.equals(ExcelOperator.EXCEL_POSTFIX)){
			return false;
		}
		return true;
	}
	
	/*
	 * 初始化二维数组内容为"" 
	 * @param arrays 要初始化二维数组
	 */
	private void initArrays(String [][] arrays){
		for (int i = 0; i < arrays.length; i++) {
			for (int j = 0; j < arrays[i].length; j++) {
				arrays[i][j]="";
			}
		}
	}
}

使用iText5.x创建PDF中文处理问题

今天无意中在网上看到iText这个东东,iText 是利用Java 来操作PDF 操作的一种开源API

简单说明下使用该API创建PDF文件的过程

PS:使用的是iText5.x版本

/**
	 * 创建PDF文件
	 * @param filePath  文件路径
	 * @param content   需要写入的内容
	 * @throws DocumentException
	 * @throws IOException
	 */
	public void createPdf(String filePath ,String content) throws DocumentException, IOException{
		//1.创建Document对象
		Document document = new Document();
		FileOutputStream fos = new FileOutputStream(filePath);
		//2.创建一个PdfWriter实例
		PdfWriter.getInstance(document, fos);
		//3.打开文档
		document.open();
		Paragraph graph = new Paragraph(content);
		//4.加入段落
		document.add(graph);
		//5.关闭文档
		document.close();
	}

利用上述程序,运行结果。发现,只有英文部分被写入,中文部分无法被写入。百度得到结论:

需要加入itextasian.jar包,itextasian.jar包有实现了对中文字体的支持。因此加载itextasian.jar到classpath下。

在上述代码中加入如下代码:

BaseFont baseFontChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
		Font fontChinese =  new  Font(baseFontChinese , 12 , Font.NORMAL);
		Paragraph graph = new Paragraph(content , fontChinese);

运行,得到如下异常:

Font 'STSong-Light' with 'UniGB-UCS2-H' is not recognized

还是不行,继续研究,在网上前辈们说如下原因:

  iText5.x版本以上中的font和encoding文件都是从String RESOURCE_PATH = "com/itextpdf/text/pdf/fonts/"加载的,而老itextasian.jar的包名是com.lowagie.text.pdf.fonts, 包名不一致导致路径错误,。

具体解决方法就是修改包的路径了,详细方法如下:

1.解压iTextAsian.jar
  得到如下目录:
  iTextAsian
     --com
        --lowagie
          --text
            --pdf
              --fonts
                --...(字体属性文件)
2.将解压后的com目录下的包名lowagie更改为itextpdf
3.在命令行转至iTextAsian目录,重新打包为iTextAsian.jar文件
4.打包命令如下:
  jar cvf iTextAsian.jar com/itextpdf/text/pdf/fonts/*
5.执行后,将新的iTextAsian.jar加入classpath路径

运行结果,OK,解决问题。

最终代码如下:

/**
	 * 创建PDF文件
	 * @param filePath  文件路径
	 * @param content   需要写入的内容
	 * @throws DocumentException
	 * @throws IOException
	 */
	public void createPdf(String filePath ,String content) throws DocumentException, IOException{
		//1.创建Document对象
		Document document = new Document();
		FileOutputStream fos = new FileOutputStream(filePath);
		//2.创建一个PdfWriter实例
		PdfWriter.getInstance(document, fos);
		//3.打开文档
		document.open();
		BaseFont baseFontChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
		Font fontChinese =  new  Font(baseFontChinese , 12 , Font.NORMAL);
		Paragraph graph = new Paragraph(content , fontChinese);
		document.add(graph);
		document.close();
	}

 继续研究ing~~

Spring中抽象类不能注入属性

昨天做项目的时候,因为注入用的很爽,自然而然的在什么类下都用注入,结果出问题,注入的属性都是为null,查了一下,会不会是抽象类的问题呢,百度之,得下面的答案:

抽象类不能生成实例对象,spring无法注入 。
因为spring的原理是启动服务器时读取配置文件,取得类名后利用反射机制在spring上下文中生成一个单例的对象,由spring注入属性并维护此对象的状态,抽象类在反射生成对象时就已经失败了,后面的不会进行。

初学Hibernate一对多关联

今天,花了些时间去了解了Hibernate的一对多关联,做的例子是

描述一个用户拥有多个角色。实现一个添加用户,从而在数据库中添加用户和角色记录

角色记录由Hibernate完成。

贴个代码:(只贴出主要部分)

1.SQL脚本

--用户表
create table users
(
   userID number primary key, --用户ID
   name varchar(20)  -- not null--真实姓名
);

--角色表
create table roles
(
    roleID number primary key, --角色ID
    roleName varchar2(20),    --角色名称
    userID number
);

alter table roles add constraint fk_role_re_user 
foreign key(userID) references users(userID);

1.POJO-用户对象

/**
 * 用户对象
 * @author ChenST
 */
public class Users implements java.io.Serializable {

	//用户ID
	private Long userid;

	//姓名
	private String name;

	//角色列表
	private Set roleses = new HashSet(0);

	// Constructors
	/** default constructor */
	public Users() {
	}
	
	////setter和getter方法略
}

2.POJO-角色对象

/**
 * 角色对象
 * @author ChenST
 */
public class Roles implements java.io.Serializable {

	//角色ID
	private Long roleid;

	//所属于用户
	private Users users;

	//角色名
	private String rolename;

	//所属于用户ID
	private Long userid;

	// Constructors
	/** default constructor */
	public Roles() {
	}
	
	///setter和getter方法略
}

3.HBM-用户映射文件

<hibernate-mapping>
    <class name="com.shine.pojo.Users" table="USERS" schema="CST">
        <id name="userid" type="java.lang.Long">
            <column name="USERID" precision="22" scale="0" />
            <!-- 
                    如果非自动增长列,可以设置成assigned 
                    不能设置成sequence
            -->
            <generator  class="assigned"/>
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" length="20" />
        </property>
        <!-- 
              此处的cascade要设置成save-update,
              否则无法级联更新(插入)
            cascade的值
                 sava-update:级联保存、更新
                 delete:级联删除
                 none:不级联,默认值
                 all:级联保存、更新、删除
            inverse属性表示是否把对Set的改动反应到数据库中去
            inverse=true不反应  inverse=false反应(默认)
            =false表示会去维护中间表 =true表示不会去维护中间表
         -->
        <set name="roleses" inverse="false" cascade="save-update">
            <key>
                <column name="ROLEID" precision="22" scale="0" 
                        not-null="true" unique="true" />
            </key>
            <one-to-many class="com.shine.pojo.Roles" />
        </set>
    </class>
</hibernate-mapping>

4.HBM-角色映射文件

<hibernate-mapping>
    <class name="com.shine.pojo.Roles" table="ROLES" schema="CST">
        <id name="roleid" type="java.lang.Long">
            <column name="ROLEID" precision="22" scale="0" />
            <!-- 
                    如果非自动增长列,可以设置成assigned 
                    不能设置成sequence
            -->
            <generator class="assigned" />
        </id>
        <many-to-one name="users" class="com.shine.pojo.Users" 
                     update="false" insert="false" fetch="select">
            <column name="ROLEID" precision="22" scale="0" 
                    not-null="true" unique="true" />
        </many-to-one>
        <property name="rolename" type="java.lang.String">
            <column name="ROLENAME" length="20" />
        </property>
        <property name="userid" type="java.lang.Long">
            <column name="USERID" precision="22" scale="0" />
        </property>
    </class>
</hibernate-mapping>

5.DAO-用户DAO实现类

/**
 * 用户Dao的实现类
 * @author ChenST
 *
 */
public class UserDaoImpl implements IUserDao {

	/**
	 * 保存对象
	 */
	public void save(Users user) {
		//Session对象负责执行被持久化对象的CURD操作
		Session session=null;
		//Transaction对象负责事务上的
		Transaction trans=null;
		try{
			//获取session对象
			session=HibernateSessionFactory.getSession();
			//获取事务
			trans=session.beginTransaction();
			session.saveOrUpdate(user);
			trans.commit();
		}catch (Exception e) {
			e.printStackTrace();
			trans.rollback();
		}finally{
			//关闭Session
			HibernateSessionFactory.closeSession();
		}
	}
}

6.JUNIT-用户Dao测试

/**
 * 测试UserDao
 * @author ChenST
 */
public class UserDaoTest extends TestCase {
	
	/**
	 * 测试保存方法
	 */
	public void testSave(){
		IUserDao userDao=new UserDaoImpl();
		Users user=new Users(3L,"cst",new HashSet());
		Roles role1=new Roles(3L,user,"a",3L);
		user.getRoleses().add(role1);
		userDao.save(user);
	}
}

 完毕。。。

Ant学习笔记

看Hibernate的时候发现Ant这个东东,花了3个小时查了些资料,并总结如下:

Ant是用来编译/运行/测试java程序

Ant可用于项目管理。

Ant还提供了打包,生成API文档等多功能。

总之,Ant可提高程序员的开发效率。

使用MyEcipse创建build.xml文件(如果自己写比较麻烦的话,可以用工具帮你生成,不过感觉有挺多垃圾信息)

具体方法如下:

【项目右键】>>【Export】>>【General】>>【 Ant Buildfiles】>>【 next】>>【 finish】即可

贴个下午写的一个 build.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
    <!--  
          <project>构建文件对应的一个项目
            属性介绍:
                 basedir表示项目的基准目录
                 basedir="."表示基准目录为src目录 
                 default表示默认的运行目标(必须)
                 name表示项目名
      -->
	<project basedir="." default="build" name="Ant">
    <property environment="env"/>
	<!-- 
	     <property>定义属性以及于其对应的值
	     通常:src存放java源代码文件
	         classes存放java编译后的文件
	         lib存放要用到的第三方jar包
	         dist存放打包后的jar包
	         doc存放API文档
	  -->
    <property name="src.dir" value="src/com/shine/ant"/>
    <property name="classes.dir" value="bin/com/shine/ant"/>
    <property name="lib.dir" value="lib"/>
    <property name="dist.dir" value="dist"/>
	<property name="doc.dir" value="doc"/>
	
	<!--
	    <path>定义类路径,其中值指向classes.dir
	-->
    <path id="Ant.classpath">
        <pathelement location="${classes.dir}"/>
    </path>
		
	<!-- 初始化操作 -->
    <target name="init">
    	<!--
    	     <delete>标签表示删除一个或一组文件
    	      属性介绍:
    	         dir表示要删除的目录
    	  -->

    	<delete dir="${classes.dir}" />
    	<!--
    	     <mkdir>标签表示创建目录
    	      属性介绍:
    	          dir表示要创建的目录
    	  -->
        <mkdir dir="${classes.dir}"/>
    	<!--
    	     <copy>标签用于文件或文件集的拷贝
    	     属性介绍:
    	           includeemptydirs表示制定是否拷贝空目录
    	           				    默认值为拷贝,此处不拷贝
    	           todir表示目标目录
    	-->
        <copy includeemptydirs="false" todir="${classes.dir}">
            <!--
               <fileset>表示了一组文件信息
                        属性介绍:
                        dir表示基目录
                        excludes表示需要派出的文件模式的文件列表
            -->
        	<fileset dir="${src.dir}" 
        		     excludes="**/*.launch,**/*.java"/>
        </copy>
    </target>
	<!-- 清除操作 -->
    <target name="clean">
        <delete dir="${classes.dir}"/>
    </target>
	<!--
	    <target>标签表示你要做的操作
	      		属性name表示目标的名字,起到识别作用
	      		depends表示依赖,就是要先执行clean才可以执行
	  -->
	<!-- 清除所有 -->
    <target depends="clean" name="cleanall"/>
	
    <target depends="build-project" name="build"/>
	<!-- 建立工程 -->
    <target depends="init" name="build-project">
    	<!--
    	    <javac>标签用于编译一个或一组java文件
    	             属性介绍:
    	               debug表示包含的调试信息
    	               srcdir表示源文件
    	               destdir表示class文件的输出目录
    	-->
        <javac debug="true" 
        	   srcdir="${src.dir}"  
        	   destdir="bin" >
        </javac>
    </target>
	
	<!-- 打包成jar包 -->
	<target name="pack">
		<mkdir dir="${dist.dir}"/>
		<!--
		   <jar>文件用来生成一个jar文件
		   属性介绍:
		        destfile表示生成的jar文件名
		        basedir表示被打包的文件名
		-->
		<jar destfile="${dist.dir}/ant.jar" 
			 basedir="${classes.dir}">
		    <!--
		        <exclude>表示被排除的文件
		      -->
			<exclude name="**/*.java"/>
		</jar>
    </target>
	
	<!-- 生成API文档 -->
	<target name="doc">
		<delete dir="${doc.dir}"/>
		<mkdir dir="${doc.dir}"/>
		<!--
		     <javadoc>标签用于生成javadoc-API文档
		      属性介绍:
		         destdir表示要输出的目录
		  -->
		<javadoc destdir="${doc.dir}">
			<!-- 
			    指定要被包含的文件 为src/com/shine/ant下的所有类 
			-->
			<packageset dir="src" defaultexcludes="yes">
			    <include name="com/shine/ant/**"/>
			</packageset>
		</javadoc>
	</target>
</project>

完毕~~~

Spring2.5常用注解

公司代码很多Spring注解,下午花了点时间学习了下。贴个小案例来使用这些注解:

学习的注解列表

@Component
@Service
@Repository
@Controller
@Autowired
@Qualifier
@Resource
@PostConstruct
 @PreDestroy

1.水果接口

/**
 * 水果接口
 * 
 * @author ChenST
 *
 */
public interface Fruit {
	/**
	 * 获取水果的名字
	 * @return
	 */
	public String getName();
}

2.苹果类

/**
 * 苹果
 * @author ChenST
 *
 */
@Service
public class Apple implements Fruit {

	/*
	 * (non-Javadoc)
	 * @see com.spring.annotation.Fruit#getName()
	 */
	public String getName() {
		return "苹果";
	}
}

3.梨类

/**
 * 梨
 * @author ChenST
 *
 */
@Service
public class Pear implements Fruit {

	public String getName() {
		return "梨";
	}
}

4.人类

/**
 * 人,拥有水果
 * @author ChenST
 *
 */
/*
 * @Service表示定义个Bean对象默认Bean的名字为
 * 类的第一个字母小写名字,例如Human为human
 * @Service("name")也可以自己指定名字name
 * ----------以下四种注解是等效的,只是意义不同
 * @Component 比较中立的类进行注释
 * @Service   表示服务层
 * @Repository表示持久层
 * @Controller表示控制层
 */
@Service
public class Human {
	
	/** 表示拥有水果 */
	/*@Autowired(required = false)表示不确定
	 *Spring容器中拥有某个类的Bean时候,这样Spring
	 *找不到这个Bean时也不报错
	 *
	 *@Autowired注解表示自动注入对象。在配置文件中需要配置
	 *<context:annotation-config />
     *<context:component-scan base-package="*"/>
     *
     *@Qualifier("apple")表示当这个fruit有两个实现类时
     *指定其中一个。负责会报错
     *
     *@Resource注释与Autowired差不多,Resource可以通过
     *name和type来指明要注入的类
	 */
	//@Autowired
	//@Qualifier("apple")
	//@Resource(name="apple")
	@Resource(type=Apple.class)
	private Fruit fruit;
	
	public void setFruit(Fruit fruit) {
		this.fruit = fruit;
	}

	/**
	 * 吃水果
	 */
	public void eat(){
		System.out.println("我在吃"+this.fruit.getName());
	}
	
	/*
	 * @PostConstruct表示Spring容器初始化后调用
	 */
	@PostConstruct
	public void eatBegin(){
		System.out.println("我要开始吃了");
	}
	
	/*
	 * @PreDestroy表示Spring容器销毁之前调用
	 */
	@PreDestroy
	public void eatFinish(){
		System.out.println("吃完了");
	}
}

5.测试类

/**
 * 测试类
 * 
 * @author ChenST
 *
 */
public class Test {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		Human human=(Human) ctx.getBean("human");
		human.eat();
	}
}

5.applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	
    <!-- 自动注解配置 -->
    <context:annotation-config />
    <context:component-scan base-package="*" />
</beans>

6.运行结果

我要开始吃了
我在吃苹果
吃完了

Spring中进行测试-Junit框架的扩展

利用Spring来进行测试。首先看看下面几个类。【参照网上的资料】

1.AbstractSpringContextTests 类是针对所有测试情景的类,一般不使用,而是使用他们的之类。

2.AbstractDependencyInjectionSpringContextTests 类继承了AbstractSpringContextTests是一个针对所有测试的超类,具体依赖于Spring上下文。可支持依赖注入

3.AbstractTransactionalSpringContextTests 类继承了AbstractDependencyInjectionSpringContextTests,继承该类的测试用例在spring管理的事务中进行,测试完后对数据库的记录不会造成任何影响。你对数据库进行一些操作后,它会自动把数据库回滚,这样就保证了你的测试对于环境没有任何影响。

测试用例需实现protected abstract String[] getConfigLocations()方法来获取上下文。

1.创建一个测试类的基类

/**
 * Spring测试的基类
 * 
 * @author ChenST
 *
 */
public abstract class BaseSpringTest extends AbstractDependencyInjectionSpringContextTests {
	
	/**
	 * 获取上下文spring context,该路径是在classpath下的路径
	 */
	public String[] getConfigLocations() {
		String[] configLocations = { "applicationContext.xml" };
		return configLocations;
	}
}

2.测试用例

/**
 * 测试用例,测试Dao的方法getUserInfo(String userCode)
 * 
 * @author ChenST
 *
 */
public class UsersDaoTest extends BaseSpringTest {
	
	/** 用户Dao,注入实现 */
	private UsersDAO userDao;
	
	public void setUserDao(UsersDAO userDao) {
		this.userDao = userDao;
	}

	/**
	 * 测试getUserInfo()方法,需要以test开头
	 */
	public void testGetUserInfo(){
		Users user=userDao.getUserInfo("004");
	    System.out.println(user.getDepartment().getDepName());
	}
}

可通过MyEclipse中的Outline透视图中进行单个方法的测试或者整个类的测试。

Bean属性拷贝出现java.lang.ExceptionInInitializerError可能原因

前些天,进行使用PropertyUtils工具进行Bean的属性拷贝,总出现:java.lang.ExceptionInInitializerError错误,明明字段啥的都一样啊。。许久才发现。原来我包引错了~~闷~

我引用的是 com.sun.org.apache.commons.beanutils.PropertyUtils 类。

正确的是引用 org.apache.commons.beanutils.PropertyUtils

备注并引以为戒。

Cannot find ActionMappings or ActionFormBeans collection错误

今天,将一个工程改成EJB时候,使用Struts的Action访问,出现Cannot find ActionMappings or ActionFormBeans collection错误。

百度之~~得:可能少了Struts的包,于是将Struts的包再重新导入一次,解决问题。

网上说,这类问题可能还可能有如下问题所导致:备忘下~~

①Web.xml未初始化问题
少了一个<load-on-startup>0</load-on-startup>
这样开始是没有加载这个类,就没有初始化struts-config.xml,所以找不到actionmappings actionformbeans collection。
②struts-config.xml问题
③jar包不全或版本不对
也有可能导致这个问题,从stuts例子里面拷过来就好了。struts1.x自带共10个jar包。
④编译问题
有可能Action和Formbean没有编译,也会有这个问题,检查一下有没有对应的class文件就好。class路径不对可能也会导致这个问题。
⑤版本问题
用的servlet容器和struts版本不对或这两个版本协调有问题。

Strust异常:JasperException①NestedWriteNestingTei

昨日,基于公司的框架,并使用了Struts进行了开发和配置信息,结果访问时出现如下异常:

Failed to load or instantiate TagExtraInfo class: 
org.apache.struts.taglib.nested.NestedWriteNestingTei

网上说是因为包冲突问题,于是乎得到解决方案如下:

只要删除掉部署后的 /WEB-INF/lib 下的 jsp-api.jarservlet-api.jar 包即可~~