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 类
备注并引以为戒。
.userlibraries文件技巧与用法
.userlibraries文件,顾名思义,就是用户库的意思。记载了所包含的用户库的信息。
如果我们工程很多,而且引用的包很多,而且很多工程都共用很多包,那不是很麻烦。?
使用.userlibraries文件可以帮助我们管理这些包,使用MyEclipse可以通过这个.userlibraries文件把相关的用户库给引用进来。无须导入很多包。
举个例子:
<?xml version="1.0" encoding="UTF-8"?> <eclipse-userlibraries version="2"> <library name="struts" systemlibrary="false"> <archive path="E:/lib/esim65/lib/struts/commons-codec.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-collections.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-dbutils-1.1.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-digester.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-fileupload.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-httpclient.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-io-1.2.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-lang-2.0.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-net-1.4.1.jar"/> <archive path="E:/lib/esim65/lib/struts/commons-validator.jar"/> <archive path="E:/lib/esim65/lib/struts/struts.jar"/> <archive path="E:/lib/esim65/lib/struts/Struts-Layout.jar"/> <archive path="E:/lib/esim65/lib/struts/struts-legacy.jar"/> </library> </eclipse-userlibraries>
比如我们记录一个struts包,里面包含了struts中的包,每个工程用到strust的时候,我们可以直接导入这个文件来把strust库中的包引进来。
以上library节点的name属性就是存放这些包的文件夹名,archive节点的path属性是存放包的物理路径。
很幸运的MyEclipse可以帮我们生成这个文件。
右键工程>>【Build Path】>>【Configure Build Path】>>选择【Libraries】>>【Add Libraries】>>【User Libraries】>>【next】>>【User Libraries】>>【Export】>>选中要导出的库,和指定对应的文件即可。
如图,
要使用这个文件的时候,【Import】>>选中指定的文件即可。如图:
完毕~~
Cannot find ActionMappings or ActionFormBeans collection错误
今天,将一个工程改成EJB时候,使用Struts的Action访问,出现Cannot find ActionMappings or ActionFormBeans collection错误。
百度之~~得:可能少了Struts的包,于是将Struts的包再重新导入一次,解决问题。
网上说,这类问题可能还可能有如下问题所导致:备忘下~~
①Web.xml未初始化问题 |
远程连接Oracle10g数据库
百度之~在问问上搜到的答案并解决。
要进行远程连接Oracle数据库,首先需要对远程连接进行设置。具体做法如下:
【开始】>>【所有程序】>>【Oracle-OraDb10g_home1】>>【配置和移植工具】>>【Net Configuration Assistant】
选择【本地Net服务名配置】>>【添加】之后根据要连接的远程 数据库的IP 和 服务名 即可。之后就可以用PLSQL Developer进行登陆了。
具体操作可见下图:
1.选择Net Configuration Assistant
2.配置服务名
3.配置主机名
4.PLSQL Developer登录
迭代器模式--回答历史性问题
记得以前春哥问我:为什么迭代器都能够遍历多种数据结构,是怎么实现的呢。?
今天有空,看了迭代器模式,研究了几个小时的JDK~~总结如下:
先来看看一个例子:
List<String> list=new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); Iterator<String> iter=list.iterator(); while(iter.hasNext()){ System.out.println(iter.next()); } //遍历Vector List<String> vec=new Vector<String>(); vec.add("d"); vec.add("e"); vec.add("f"); Iterator<String> iterv=vec.iterator(); while(iterv.hasNext()){ System.out.println(iterv.next()); }
为什么一个方法能够遍历不同集合呢。?
看下它们的关系图就可以知道原理了,而且使用的是迭代器模式。
纯粹是纪念下午的研究结果~~
状态模式
定义摘自《head first》中:
状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
对于使用者来说看起来好像是能够修改自己的类,实际上是委托状态对象来改变相关操作。
状态模式类图如下(截图于《head first》):
对于状态模式,我自己举了例子:描述一个人经过外界时间的影响,心情状态会有不同的变化。
例如:一个人捡到钱了,当然是很高兴,钱丢了当然就不高兴也就是悲伤了,当丢的钱又捡回来了,于是就从悲伤变成高兴了。
看下面状态图:
使用状态模式实现,代码如下:
1.状态接口
/** * 状态接口 * * @author ChenST * * @create 2010-3-25 */ public abstract class State { /** 状态名 */ private String name; /** * 捡到钱了 */ public abstract void pickMoney(); /** * 丢钱了 */ public abstract void loseMoney(); /** * 钱捡回来了 */ public abstract void backMoney(); public String getName() { return name; } public void setName(String name) { this.name = name; } }
2.正常状态
/** * 正常状态 * * @author Administrator * * @create 2010-3-25 */ public class NormalState extends State { /** 该状态所发生的实体 */ private Person person; public NormalState(Person person) { this.person=person; this.setName("正常"); } public void loseMoney() { //丢钱了,很悲伤,状态转变 System.out.println("钱丢啦!"); person.setCurrent(person.getSad()); } public void pickMoney() { System.out.println("捡到钱了!"); person.setCurrent(person.getHappy()); } public void backMoney() { //无状态改变 } }
3.高兴状态
/** * 高兴的状态 * * @author ChenST * * @create 2010-3-25 */ public class HappyState extends State { /** 该状态所发生的实体 */ private Person person; public HappyState(Person person) { this.person=person; this.setName("高兴"); } public void backMoney() { //无任何状态改变 } public void loseMoney() { //无任何状态改变 } public void pickMoney() { //无任何状态改变 } }
4.悲伤状态
/** * 悲伤状态 * * @author ChenST * * @create 2010-3-25 */ public class SadState extends State { /** 该状态所发生的实体 */ private Person person; public SadState(Person person) { this.person=person; this.setName("悲伤"); } public void backMoney() { //丢失的钱失而复得,很高兴 System.out.println("捡回来了,原来丢在这儿了"); person.setCurrent(person.getHappy()); } public void loseMoney() { //无状态改变 } public void pickMoney() { //无状态改变 } }
5.人类,状态存在的实体
/** * 一个人的类 * * @author ChenST * * @create 2010-3-25 */ public class Person extends State{ /** 高兴的状态 */ private State happy; /** 悲伤的状态 */ private State sad; /** 正常的状态 */ private State normal; /** 当前的状态 */ private State current; public Person(){ this.happy=new HappyState(this); this.sad=new SadState(this); this.normal=new NormalState(this); //当前状态为正常状态 this.current=this.normal; } /** * 显示打印当前状态 */ public void showCurrentState(){ System.out.println(current.getName()); } /** * 重新设置状态,回复默认状态 */ public void resetState(){ this.current=this.normal; } // //委托给状态对象去执行操作 // public void backMoney() { current.backMoney(); } public void loseMoney() { current.loseMoney(); } public void pickMoney() { current.pickMoney(); } public State getCurrent() { return current; } public void setCurrent(State current) { this.current = current; } public State getHappy() { return happy; } public void setHappy(State happy) { this.happy = happy; } public State getNormal() { return normal; } public void setNormal(State normal) { this.normal = normal; } public State getSad() { return sad; } public void setSad(State sad) { this.sad = sad; } }
6.测试类
/** * 测试类 * * @author ChenST * * @create 2010-3-25 */ public class Test { public static void main(String[] args) { //今天詹姆斯出去买东西 Person james=new Person(); james.pickMoney(); //今天运气好,捡到钱了 james.showCurrentState();//查看下詹姆斯的心情 james.resetState(); //于是不买东西了回家了.(恢复默认状态) james.showCurrentState();//查看下詹姆斯的心情 //第二天詹姆斯又出去买东西 james.loseMoney(); //今天运气不好,丢钱了 james.showCurrentState();//查看下詹姆斯的心情 james.backMoney(); //今天运气还不算很差,钱捡回来了。 james.showCurrentState();//查看下詹姆斯的心情 } }
7.运行结果
捡到钱了! 高兴 正常 钱丢啦! 悲伤 捡回来了,原来丢在这儿了 高兴
OK~~完毕~可以看到,如果对状态的增加或者修改,或者对行为的增加或修改,都可以很好的扩展和维护。只要在人的类里面增加相应的状态和方法即可改变,而不需要改变整体结构,用增加类来代替if 的条件判断。
外观模式
今天,做完了公司的课题,无聊之余总结下之前的【外观模式】,看了这个模式的具体内容,很早以前就有用这样的思想了,只是不知道它叫外观模式。外观模式:实际上是提供一个经常使用的接口,这个接口他执行了许多子系统中的许多操作,使得用户不需要了解子系统中的具体操作,只需使用接口。这种例子是很常见的。
例如:我们知道用户、角色、权限三者关系,在早期,还没有角色的概念,只有用户和权限的概念,是直接讲权限赋予用户,但是后来为了方便管理,才引入角色的概念,把权限赋予角色,再把角色赋予用户。而角色就是我们外观模式中说的经常使用的接口,权限就是子系统,用户就是客户。
看下面的两个等价图:
1.有角色参与:
2.无角色参与:
可以看到,使用外观模式使的客户使用更方便,不需要了解子系统的过程,整个层次也更清晰。
无聊的实现了下这个代码:贴个纪念~~
1.权限类
/** * 权限类 * * @author ChenST * * @create 2010-3-24 */ public class Right { /** 【添加】的权限 */ public final static String ADD_RIGHT="【添加】"; /** 【删除】的权限 */ public final static String DELETE_RIGHT="【删除】"; /** 【更新】的权限 */ public final static String UPDATE_RIGHT="【更新】"; /** 【查看】的权限 */ public final static String SEE_RIGHT="【查看】"; }
2.角色抽象类
/** * 角色抽象类 * * @author ChenST * * @create 2010-3-24 */ public abstract class Role { /** 角色拥有的权限*/ private Set<String> rights; public Role(){ this.rights=new HashSet<String>(); //赋权操作 this.addRight(); } /** * 添加权限 */ public abstract void addRight(); public Set<String> getRights() { return rights; } }
3.管理员角色
/** * 超级管理员角色 * * @author ChenST * * @create 2010-3-24 */ public class Admin extends Role{ /* * 添加全部的权限 * (non-Javadoc) * @see facade.Role#addRight() */ @Override public void addRight() { this.getRights().add(Right.ADD_RIGHT); this.getRights().add(Right.DELETE_RIGHT); this.getRights().add(Right.SEE_RIGHT); this.getRights().add(Right.UPDATE_RIGHT); } }
4.会员用户
/** * 会员用户 * * @author ChenST * * @create 2010-3-24 */ public class Vip extends Role { /* * 会员用户拥有【添加】权限 * (non-Javadoc) * @see facade.Role#addRight() */ @Override public void addRight() { this.getRights().add(Right.ADD_RIGHT); } }
5.普通用户角色
/** * 普通用户角色 * * @author ChenST * * @create 2010-3-24 */ public class CommonUser extends Role{ /* * 普通用户只拥有【查看】的权限 * (non-Javadoc) * @see facade.Role#addRight() */ @Override public void addRight() { this.getRights().add(Right.SEE_RIGHT); } }
5.用户类
/** * 用户 * * @author ChenST * * @create 2010-3-24 */ public class User { /** 用户姓名 */ private String name; /** 用户所拥有的角色 */ private Set<Role> roles; public User(String name){ this.name=name; roles=new HashSet<Role>(); } /** * 添加权限 * @param role */ public void addRole(Role role){ this.roles.add(role); } /** * 查看用户所拥有的权限 */ public void lookRight(){ System.out.println(this.name+"权限有:"+this.getRights()); } /** * 获取用户所拥有的权限 * @return */ public Set<String> getRights() { Set<String> rights=new HashSet<String>(); for (Role role : roles) { for (String right: role.getRights()) { rights.add(right); } } return rights; } }
6.测试类
/** * 测试类 * * @author ChenST * * @create 2010-3-24 */ public class Test { public static void main(String[] args) { //创建用户james和green User james=new User("james"); User green=new User("green"); User joe=new User("joe"); //创建三个角色 超级管理员,普通管理员,普通用户 Role admin=new Admin(); Role vip=new Vip(); Role commonUser=new CommonUser(); //给james赋予角色,赋予管理员和普通用户 james.addRole(admin); james.addRole(commonUser); //给green赋予角色,赋予管理员 green.addRole(admin); //给joe赋予角色,赋予管理员和会员 joe.addRole(vip); joe.addRole(admin); //查看拥有的权限 james.lookRight(); green.lookRight(); joe.lookRight(); } }
运行结果:
james权限有:[【删除】, 【更新】, 【查看】, 【添加】] green权限有:[【删除】, 【更新】, 【查看】, 【添加】] joe权限有:[【删除】, 【更新】, 【查看】, 【添加】]
可以看到,对于角色很好扩展和维护,对于权限的分配也可以很好维护,例如,会员用户要添加一个新的权限,那么则只要修改会员用户的权限,而不需要把相关的用户全部修改。OK~~
IE中网页字体变小的解决方案
前些天就遇到这类问题(网页字体变得很小)了,我知道可以用鼠标滚轴来调节,但是调节的总是没有原先默认的好。今日百度了下,得解决方案:
打开【运行】输入【regedit】进入注册表。
在 【HKEY_CURRENT_USER】>>【Software】 >>【Microsoft】 >> 【Internet Explorer】 >> 【International】 >> 【Scripts】 >> 【26/3】下的IEFontSize文件,
修改它的值为02,00,00,00即可(02为默认值,00为最小字号,01为较小字号,03较大字号,04为最大字号)
适配器模式
适配器模式:顾名思义,就是由一个中间介质,实现一种接口到另外一种接口的转化。两种接口都不用改变其中任何一个接口的结构。
适配器模式成为【类适配器】和【对象适配器】,这里用java实现,因此只讨论【对象适配器】,结构看下图:
举个例子,今天插在笔记本的鼠标坏了,叫小妹去买个鼠标,可是买回来才发现,她居然买了个PS2接口的鼠标,可是我笔记本是USB接口的呀,这要怎么用啊。?
如果再买个USB的鼠标,那么这个就浪费了,很明显我是不想换鼠标。更不想把笔记本给换成台式的吧~,于是这个时候我们就想到了用转换器,即实现USB到PS2的转换,代码实现如下:
1.USB接口
/** * USB接口 * * @author ChenST * * @create 2010-3-23 */ public interface USB { /** 产品描述 */ public void describe(); }
2.PS2接口
/** * PS2接口【鼠标圆孔接口】 * * @author ChenST * * @create 2010-3-23 */ public interface PS2 { /** 产品描述 */ public void describe(); }
3.鼠标类
/** * 鼠标类,实现了PS2接口,即【圆孔的鼠标】 * * @author ChenST * * @create 2010-3-23 */ public class Mouse implements PS2 { public void describe() { System.out.println("用的是PS2接口"); } }
4.适配器(USB和PS2的转换器)
/** * 接口适配器,拥有USB接口 * * @author ChenST * * @create 2010-3-23 */ public class Adapter implements USB{ /** PS2接口 */ private PS2 ps2; public Adapter(PS2 ps2) { this.ps2=ps2; } public void describe() { ps2.describe(); } }
5.测试类
/** * 测试类 * 买了一个圆孔鼠标想要插笔记本上,却发现笔记本上没有圆孔, * 只有USB接口,这个鼠标好贵啊,再买个圆孔鼠标经济上是不可行的, * 更不能扔了笔记本而换台式的电脑把。于是想到使用USB和PS2转化器 * 将转化器插在笔记本电脑上,于是笔记本USB接口就变成了PS2接口了, * 此时鼠标就可以接入了。 * * @author ChenST * * @create 2010-3-23 */ public class Test { public static void main(String[] args) { //圆孔鼠标 PS2 mouse=new Mouse(); //适配器,把他变成鼠标要用的接口 Adapter adapter=new Adapter(mouse); //现在查看下原来是USB的接口的适配器用的是什么接口 adapter.describe(); } }
运行结果:
用的是PS2接口
从结果可以看出,适配器已经实现了从USB接口到PS2接口的转换了~~OK~又学习了一个新模式