|
引用 http://blog.joycode.com/joe/archive/2005/09/06/63068.aspx http://www.itlearner.com/article/2006/3325.shtml使用方法: js
//获得Cookie解码后的值 function GetCookieVal(offset){ var endstr = document.cookie.indexOf (";", offset); if (endstr == -1) endstr = document.cookie.length; return unescape(document.cookie.substring(offset, endstr)); }
//设定Cookie值 function SetCookie(name, value){ var expdate = new Date(); var argv = SetCookie.arguments; var argc = SetCookie.arguments.length; var expires = (argc > 2) ? argv[2] : null; var path = (argc > 3) ? argv[3] : null; var domain = (argc > 4) ? argv[4] : null; var secure = (argc > 5) ? argv[5] : false; if(expires!=null) expdate.setTime(expdate.getTime() + ( expires * 1000 )); document.cookie = name + "=" + escape (value) +((expires == null) ? "" : ("; expires="+ expdate.toGMTString())) +((path == null) ? "" : ("; path=" + path)) +((domain == null) ? "" : ("; domain=" + domain)) +((secure == true) ? "; secure" : ""); }
//删除Cookie function DelCookie(name){ var exp = new Date(); exp.setTime (exp.getTime() - 1); var cval = GetCookie (name); document.cookie = name + "=" + cval + "; expires="+ exp.toGMTString(); }
//获得Cookie的原始值 function GetCookie(name){ var arg = name + "="; var alen = arg.length; var clen = document.cookie.length; var i = 0; while (i < clen) { var j = i + alen; if (document.cookie.substring(i, j) == arg) return GetCookieVal (j); i = document.cookie.indexOf(" ", i) + 1; if (i == 0) break; } return null; }
jsunit <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=BIG5"> <title>x</title> <script type="text/javascript" src="test.js"></script> <script type="text/javascript" src="lib/jsUnitCore.js"></script> <script type="text/javascript"> function testValidArgs() { // 测试的函式要以test名称作为开头 SetCookie('li','gg'); assertEquals("cookie get err", 'gg', GetCookie('li') ); assertEquals("cookie getVal err", 'li=gg', GetCookieVal('li') ); DelCookie("li"); assertEquals("cookie del err ",null, GetCookie('li') ); }
</script> </head> <body> </body> </html>
运行 Jsunit-> testRunner.html 通过测试
环境:
private
SessionFactory sessionFactory;
protected
void
setUp()
throws
Exception {
super
.setUp();
//
利用java反射得到 HibernateSessionFactory ->
//
private static org.hibernate.SessionFactory sessionFactory;
//
要模拟 并发 要 HibernateSessionFactory 得出的 有 threadLocal 不行
//
要
HibernateSessionFactory.currentSession(); HibernateSessionFactory.closeSession(); Field field
=
HibernateSessionFactory.
class
.getDeclaredField(
"
sessionFactory
"
); field.setAccessible(
true
); sessionFactory
=
(SessionFactory) field.get(HibernateSessionFactory.
class
); }
protected
void
tearDown()
throws
Exception {
super
.tearDown(); }
悲观锁:
/**
悲观锁问题 线程模拟 并发 * Table -> T1oo(id,name) * +----+------+ * | id | name | * +----+------+ * | 4 | xx1 | * +----+------+
*/
public
void
ctestLock()
throws
Exception {
//
insert test Data 测试数据
Session seInsert
=
sessionFactory.openSession(); Transaction tr
=
seInsert.beginTransaction(); T1oo testUse
=
testUse
=
new
T1oo(); testUse.setName(
"
liukaiyi_test
"
); seInsert.save(testUse); tr.commit(); System.out.println(
"
**************Test Use Bean : insert*******************
"
); seInsert.close(); Integer testId
=
testUse.getId(); //并发模拟 Session session1
=
sessionFactory.openSession(); Session session2
=
sessionFactory.openSession();
final
Transaction tr1
=
session1.beginTransaction(); Transaction tr2
=
session2.beginTransaction(); Query qu1
=
session1.createQuery(
"
from T1oo t1oo where t1oo.name='liukaiyi_test'
"
); Query qu2
=
session2.createQuery(
"
from T1oo t1oo where t1oo.name='liukaiyi_test'
"
); //加悲观锁 qu1.setLockMode(
"
t1oo
"
,LockMode.UPGRADE);
final
Object bean1
=
qu1.uniqueResult(); Object bean2
=
qu2.uniqueResult();
T1oo t1oo2
=
(T1oo)bean2; t1oo2.setName(
"
run1
"
);
new
Thread(
new
Runnable(){
public
void
run() {
try
{ System.out.println(
"
********解锁准备*********
"
); Thread.sleep(
10
*
1000
); T1oo t1oo1
=
(T1oo)bean1; t1oo1.setName(
"
run2
"
); tr1.commit(); System.out.println(
"
********解锁成功t*********
"
); }
catch
(InterruptedException e) {e.printStackTrace();} } } ).start();
/
/这里会 等待十秒后 tr1解锁 /
tr2.commit(); session1.close(); session2.close();
//
delete Test Date 删除测试数据
Session seDelete
=
sessionFactory.openSession(); Transaction trD
=
seDelete.beginTransaction(); Object obj
=
seDelete.createQuery(
"
from T1oo t where t.id=:id
"
). setInteger(
"
id
"
,testId.intValue()). uniqueResult(); seDelete.delete(obj); trD.commit(); System.out.println(
"
**************Test Use Bean : delete**************
"
); seDelete.close(); }
乐观锁:
/**
乐观锁问题 * Table -> T1oo(id,name) * T2oo.hbn.xml <class> +> optimistic-lock="version" * id下面 +> <version name="version" type="integer" column="version" /> * +---------+---------+------+ * | Field | Type | Null | * +---------+---------+------+ * | id | int(11) | | * | avg | int(11) | | * | aid | int(11) | YES | * | version | int(11) | YES | * +---------+---------+------+ * 注意:要在数据库中多加一列 * mysql> alter table T2OO add version int;
*/
public
void
testOpLock()
throws
Exception{ //添加测试数据 Session session
=
sessionFactory.openSession(); Transaction trI
=
session.beginTransaction(); Connection conn
=
session.connection(); T2oo t2oo
=
new
T2oo(); T1oo t1oo
=
new
T1oo(
"
t1ooOpLock
"
); t1oo.setT2ooSet(
new
HashSet()); t2oo.setAvg(
new
Integer(
23
)); t2oo.setT1oo(t1oo); t1oo.getT2ooSet().add(t2oo); session.save(t2oo); trI.commit(); session.clear(); session.close();
//并发模拟 Session se1
=
sessionFactory.openSession(); Session se2
=
sessionFactory.openSession(); Transaction tr1
=
se1.beginTransaction(); Transaction tr2
=
se2.beginTransaction(); T1oo obj1
=
(T1oo)se1.load(T1oo.
class
,
new
Integer(
1
)); T1oo obj2
=
(T1oo)se2.load(T1oo.
class
,
new
Integer(
1
)); ((T2oo)obj1.getT2ooSet().iterator().next()).setAvg(
new
Integer(
9
)); ((T2oo)obj2.getT2ooSet().iterator().next()).setAvg(
new
Integer(
10
)); tr1.commit();
try
{ tr2.commit(); }
catch
(Exception e) { se2.clear(); tr2.commit();
//
tr2报错
}
finally
{ se1.close(); se2.close(); } //测试数据删除 Session dele
=
sessionFactory.openSession(); Transaction tr
=
dele.beginTransaction(); dele.delete(obj1); tr.commit(); dele.close(); HibernateSessionFactory.closeSession(); }
inverse 使用
说明约定-如:
1.表属性 :T1oo->id,name
T2oo->id,avg,aid(
外键
),version
2.代码过程是:Save->t1oo对象(T1oo 外键 T2oo) T1oo t1oo = new T1oo(); t1oo.setName("xx"); t1oo.setT2ooSet(new HashSet()); T2oo t2oo2 = new T2oo(24); //t2oo2.setT1oo(t1oo); (在下面的本用例表中的第3属性 ) t1oo.getT2ooSet().add(t2oo2);
(在下面的本用例表中的第2属性 )
session.save(t1oo);
3.本例表使用:
T1oo.hbm.xml -> <set name="t2ooSet" inverse="true" cascade = "all" >
(在下面的本用例表中的第1,2属性 )
<key column="aid"/> <one-to-many class="T2oo"/> </set>
T2oo.hbm.xml -> <many-to-one name="t1oo" column="aid" class="T1oo" cascade="all" />
(在下面的本用例表中的第1,2属性 )
结合上面说明得表为:
+-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | all | | | +-------+-------+-------+ true | false | | t2oo | | all | | | +-------+-------+-------+----------+----------+
4.执行
Hibernate语句
:
Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) 5.结果为: mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 2 | 24 | NULL | 0 | //主要就是看 aid属性 +----+-----+------+---------+ 1 row in set (0.00 sec)
mysql> select * from t1oo; //
因为
T1oo总是可以 Save 下面就不再提了
+----+------+ | id | name | +----+------+ | 2 | xx | +----+------+ 1 row in set (0.00 sec)
可改项: +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | 可改4 | 可改2 | | | +-------+-------+-------+ | 可改1 | | t2oo | | 可改3 | | | +-------+-------+-------+----------+----------+
主本: +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | all | | | +-------+-------+-------+ true | true | | t2oo | | all | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 1 | 24 | 1 | 0 | +----+-----+------+---------+ 1 row in set (0.00 sec)
改1 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | all | | | +-------+-------+-------+ true | false | | t2oo | | all | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 1 | 24 | NULL| 0 | +----+-----+------+---------+ 1 row in set (0.00 sec)
改2 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | | | | +-------+-------+-------+ true | true | | t2oo | | all | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?)
Empty set (0.00 sec)
改2 改1 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | | | | +-------+-------+-------+ true | false | | t2oo | | all | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?)
Empty set (0.00 sec)
改3
+-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | all | | | +-------+-------+-------+ true | true | | t2oo | | | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 1 | 24 | 1 | 0 | +----+-----+------+---------+ 1 row in set (0.00 sec)
改3 改2 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | | | | +-------+-------+-------+ true | true | | t2oo | | | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?)
Empty set (0.00 sec)
改3 改1
+-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | all | | | +-------+-------+-------+ true | false | | t2oo | | | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 1 | 24 | NULL | 0 | +----+-----+------+---------+ 1 row in set (0.00 sec)
改3 改2 改1 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | true | | | | +-------+-------+-------+ true | false | | t2oo | | | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Empty set (0.00 sec)
改4 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | false | all | | | +-------+-------+-------+ true | true | | t2oo | | all | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) Hibernate: update t2oo set aid=? where id=? mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 1 | 24 | 1 | 0 | +----+-----+------+---------+ 1 row in set (0.02 sec)
改4 改1 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | false | all | | | +-------+-------+-------+ true | false | | t2oo | | all | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) Hibernate: update t2oo set aid=? where id=? mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 1 | 24 | 1 | 0 | +----+-----+------+---------+ 1 row in set (0.00 sec)
改4 改2 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | false | | | | +-------+-------+-------+ true | true | | t2oo | | all | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: update t2oo set aid=? where id=? Empty set (0.00 sec)
改4 改3 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | false | all | | | +-------+-------+-------+ true | true | | t2oo | | | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) Hibernate: update t2oo set aid=? where id=? mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 1 | 24 | 1 | 0 | +----+-----+------+---------+ 1 row in set (0.00 sec)
改4 改3 改2 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | false | | | | +-------+-------+-------+ true | true | | t2oo | | | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: update t2oo set aid=? where id=? Empty set (0.00 sec)
改4 改1 改2 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | false | | | | +-------+-------+-------+ true | false | | t2oo | | all | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: update t2oo set aid=? where id=?
Empty set (0.00 sec)
改4 改1 改3 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | false | all | | | +-------+-------+-------+ true | false | | t2oo | | | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (version, avg, aid, id) values (?, ?, ?, ?) Hibernate: update t2oo set aid=? where id=? mysql> select * from t2oo; +----+-----+------+---------+ | id | avg | aid | version | +----+-----+------+---------+ | 1 | 24 | 1 | 0 | +----+-----+------+---------+ 1 row in set (0.02 sec)
改4 改3 改2 改1 +-------+-------+-------+----------+----------+ |hbn.xml|inverse|cascade|t1oo->t2oo|t2oo->t1oo| +-------+-------+-------+----------+----------+ | t1oo | false | | | | +-------+-------+-------+ true | false | | t2oo | | | | | +-------+-------+-------+----------+----------+ Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: update t2oo set aid=? where id=? Empty set (0.00 sec)
缓存问题:
/**
使用 Query.executeUpdate() 缓存中数据不同步 解决办法 * Table -> T1oo(id,name) * Table -> T2oo(id,avg,aid) * 外键 T1oo.id->T2oo.aid * Session.createQuery("delete T1oo") -> Query.executeUpdate()
*/
public
void
testExecuteUpdate(){ System.out.println(
"
\r\n\r\n********************ExecuteUpdate************************
"
); T1oo t1oo
=
new
T1oo(); t1oo.setName(
"
liukaiyi
"
); HibernateSessionFactory.closeSession(); Session session
=
HibernateSessionFactory.currentSession(); Transaction tr1
=
session.beginTransaction();
//
t1 成为 持久状态 一级缓存中 加载
session.saveOrUpdate(t1oo);
//
直接一条语句删除T1oo,缓存无法同步
//
一级缓存中还有 t1
Query qu
=
session.createQuery(
"
delete T1oo
"
);
try
{ qu.executeUpdate(); }
catch
(Exception e) { System.out.println(
"
//err: 有级联 单使用 delete T1oo 还要delete T2oo.aid = T1oo.id//
"
); List list
=
session.createQuery(
"
from T1oo
"
).list();
for
(Iterator it
=
list.iterator();it.hasNext();){ Query t2qu
=
session.createQuery(
"
delete T2oo where aid=:id
"
); t2qu.setInteger(
"
id
"
, ((T1oo)it.next()).getId().intValue()); t2qu.executeUpdate(); } qu.executeUpdate(); } tr1.commit(); Transaction tr2
=
session.beginTransaction();
//
这直接通过一级缓存中加载t2,但DB中以没有此条数据
t1oo
=
(T1oo)session.load(T1oo.
class
,t1oo.getId()); t1oo.setName(
"
google
"
);
try
{ tr2.commit(); }
catch
(Exception e) { System.out.println(
"
//err: update(t1oo)->DB 中数据库中没有 t1oo //
"
); }
System.out.println(
"
一级缓存清空前
"
+
session.get(T1oo.
class
,t1oo.getId()) ); session.evict(t1oo); System.out.println(
"
一级缓存清空后
"
+
session.get(T1oo.
class
,t1oo.getId()) );
//
不把t1oo id 为空,否则当在saveOrUpdate时候就会以为是游离态 update了
t1oo.setId(
null
);
//
id=null insert 调用
session.saveOrUpdate(t1oo); tr2.commit(); Transaction tr3
=
session.beginTransaction(); session.delete(t1oo); tr3.commit(); session.close(); HibernateSessionFactory.closeSession(); }
结果是: ********************ExecuteUpdate************************ log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment). log4j:WARN Please initialize the log4j system properly. Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: delete from t1oo //err: 有级联 单使用 delete T1oo 还要delete T2oo.aid = T1oo.id// Hibernate: select t1oo0_.id as id, t1oo0_.name as name0_ from t1oo t1oo0_ Hibernate: delete from t2oo where aid=? Hibernate: delete from t2oo where aid=? Hibernate: delete from t2oo where aid=? Hibernate: delete from t1oo Hibernate: update t1oo set name=? where id=? //err: update(t1oo)->DB 中数据库中没有 t1oo // 一级缓存清空前 hbn.bean.T1oo@287 Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=? 一级缓存清空后 null Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: delete from t1oo where id=?
Get Load 区别 : /** Get Load 区别 (在commit前要 session.flush()) * Table -> T1oo(id,name) * 1.如果未能发现符合条件的记录,get方法返回null,而load方法会抛出异常 * 2.Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。 * 3.load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找, * 如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。 */ public void testGetLoad() throws Exception { System.out.println("\r\n\r\n********************Get<>Load************************"); Session session = HibernateSessionFactory.currentSession(); // 数据准备 T1oo t1oo = new T1oo(); t1oo.setName("liu"); Transaction t1 = session.beginTransaction(); session.saveOrUpdate(t1oo); // 为什么这会错? //session.evict(t1oo); //session.flush(); t1.commit(); session.evict(t1oo); Transaction t2 = session.beginTransaction(); System.out.println("一级缓存是否有t1oo(load)->"+session.contains(t1oo)); //这时候t1oo为 CGlib生成的代理类 t1oo = (T1oo)session.load(T1oo.class,t1oo.getId()); System.out.println(" 延迟加载出现:select.. t1oo0_.id=? 表的其他属性加载 "); t1oo.setName("load list"); //后在 update t2.commit(); session.evict(t1oo); Transaction t3 = session.beginTransaction(); System.out.println("一级缓存是否有t1oo(get)->"+session.contains(t1oo)); //这时候t1oo为 CGlib生成的代理类 t1oo = (T1oo)session.get(T1oo.class,t1oo.getId()); System.out.println(" 没有延迟加载出现"); t1oo.setName("get list"); //后在 update t3.commit(); session.evict(t1oo); Transaction tr3 = session.beginTransaction(); session.delete(t1oo); tr3.commit(); session.close(); HibernateSessionFactory.closeSession(); }
结果 ********************Get<>Load************************ Hibernate: insert into t1oo (name, id) values (?, ?) 一级缓存是否有t1oo(load)->false 延迟加载出现:select.. t1oo0_.id=? 表的其他属性加载 Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=? Hibernate: update t1oo set name=? where id=? 一级缓存是否有t1oo(get)->false Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=? 没有延迟加载出现 Hibernate: update t1oo set name=? where id=? Hibernate: select t2ooset0_.aid as aid1_, t2ooset0_.id as id1_, t2ooset0_.id as id0_, t2ooset0_.avg as avg1_0_, t2ooset0_.aid as aid1_0_ from t2oo t2ooset0_ where t2ooset0_.aid=? Hibernate: delete from t1oo where id=?
Set 集合的识别:
/** Set 集合的识别 * Table -> T1oo(id,name) * Table -> T2oo(id,avg,aid) * 外键 T1oo.id->T2oo.aid * T1oo <set name="t2ooSet" inverse="false" cascade = "all" > * T2oo <many-to-one name="t1oo" column="aid" class="T1oo" /> * cascade='insert' 是一定要的 * 当 T1oo没有 inverse="true" 主动权的时候,要双项关联 * t1oo.getT2ooSet().add(t2oo1); * t1oo.getT2ooSet().add(t2oo2); * t2oo1.setT1oo(t1oo); * t2oo2.setT1oo(t1oo); * 要不后sql为: * Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?) * Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?) * +----+-----+------+ * | id | avg | aid | * +----+-----+------+ * | 1 | 24 | NULL | * | 2 | 23 | NULL | * +----+-----+------+ * 当 T1oo有 inverse="false"主动权的时候 * t1oo.getT2ooSet().add(t2oo1); * t1oo.getT2ooSet().add(t2oo2); * Sql语句为: * Hibernate: insert into t1oo (name, id) values (?, ?) * Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?) * Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?) * Hibernate: update t2oo set aid=? where id=? * Hibernate: update t2oo set aid=? where id=? * | 3 | 24 | 12 | * | 4 | 23 | 12 | * +----+-----+------+ */ public void testSet(){ System.out.println("\r\n\r\n********************Set************************"); T1oo t1oo = new T1oo(); t1oo.setName("list"); T2oo t2oo1 = new T2oo(); t2oo1.setAvg(new Integer(23)); T2oo t2oo2 = new T2oo(); t2oo2.setAvg(new Integer(24)); Session session = HibernateSessionFactory.currentSession(); Transaction tr1 = session.beginTransaction(); session.save(t1oo); t1oo = (T1oo) session.load(T1oo.class,t1oo.getId());
t1oo.setT2ooSet(new HashSet()) ; t1oo.getT2ooSet().add(t2oo1); t1oo.getT2ooSet().add(t2oo2); System.out.println( t1oo.getT2ooSet().size()+"" ); tr1.commit(); System.out.println(); T2oo t2oo3 = new T2oo(); t2oo3.setAvg(new Integer(25)); T1oo t1oo2 = new T1oo(); t1oo2.setName("mz"); t2oo3.setT1oo(t1oo2); Transaction tr2 = session.beginTransaction(); session.save(t2oo3); try { tr2.commit(); } catch (Exception e) { System.out.println("//err: 没有主动权 cascade = 'all' 不可以级联save t1oo //"); } session.close(); HibernateSessionFactory.closeSession(); }
结果是: ********************Set************************ 2 Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?) Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?) Hibernate: update t2oo set aid=? where id=? Hibernate: update t2oo set aid=? where id=?
//err: 没有主动权 cascade = 'all' 不可以级联save t1oo //
学习: http://visualjquery.com/1.1.2.htmlDOM Attributes 1.attr(key, value) $("img").attr("title", "xx"); 也是对属性的添加但可以动态 eg: 在每次给title时 动态了开始 <img title="pic" /><img title="pic" /><img title="pic" /> 通过$("img").attr("title", function(index) { return this.title + (i + 1); }); <img title="pic 1" /><img title="pic 2" /><img title="pic 3" /> 2. html 内容取、赋值 取 <div><input/></div> ->> $("div").html(); ->> 结果:<input/> 赋 $("div").html("<b>new stuff</b>"); ->><div><b>new stuff</b></div> 通过这 ajax 就很简单了。^_^ Manipulation1.位置调换 after, append、before $("p").after("<b>Hello</b>"); <p>后 添加 <b>.. $("p").after( $("#foo")[0] ); 把id为foo的标签移动到<p>后 $("input[@name='butt1']").clone().prependTo("form"); //clone in form
参考: http://visualjquery.com/1.1.2.html
1.定位
$( 'xx' )
$("p[a]").hide(); $("p:eq(0)").show(); $("div:visible").hide(); $("ul/li") /* valid too: $("ul > li") */ $("p.foo[a]"); $("input[@name=bar]").val(); $("input[@type=radio][@checked]")
2.事件添加
<a href="#" name="li" >Link</a>
$(document).ready(function() { $("a").click(function() { $("div").hide(); //跌代不可见 <a> }); }); 3.页面 javascript 输入(和jsp的 out.print(...))$(html)
$("<div id='div1'><font color='red''>Hello</font></div>").appendTo("body"); 4.写css
$(document.body).css( "background", "black" ); 5.包含定位
<p>one</p> <div><p>two</p></div> <div>three</div>
$("div > p") //定位two <p>two</p>
6.范围定位
<body> <form> <input type="button" value="哈哈"/> </form> </body>
$("input:button", document.forms[0])[0].setAttribute("value","google"); 或 $("div", xml.responseXML) 等
7.表达试定位$("p[@name='p1']").hide();//hide不要 $(..)[0]
$("input[@name='butt1']:button", document.forms[0])[0].setAttribute("value","google"); 8.$(..).fun.. 添加方法
<form> <input name="butt1" type="button" value="google"/> </form> <script> jQuery.fn.extend({ check: function() { alert('check'); } }); $("input[@name='butt1']:button", document.forms[0]).check(); </script>
或
jQuery.extend({ min: function(a, b) { return a < b ? a : b; }, max: function(a, b) { return a > b ? a : b; } });
9.$.noConflict() <body> <form> <input name="butt1" type="button" value="google"/> </form> <a href="#" temp_href="#" name="li" >Link</a> <script> var $j = jQuery.noConflict(); // Use jQuery via $j() $j(document).ready(function(){ $("a").click(function() { $j(document.forms[0]).hide(); }); }); </script> </body> 10. $ 一般方法
//each(fn)$("img").each(function(i){ this.src = "test" + i + ".jpg"; }); <img/><img/> <img src="test0.jpg"/><img src="test1.jpg"/>
$("p").eq(1) //后1个 $("p").lt(1) //正取 1 开始
$("img").get();//全取 $("img").get(0); //顺序取 0开始 $("p").gt(0) //反取从0开始
$("*").index( $('#foo')[0] ) <div id="foobar"><b></b><span id="foo"></span></div> 返回结果 2
$("img").length; //总长度 $("img").size();
直接看代码.. dom4j 的一般使用都在里面了 /lib/dom4j-1.6.1.jar /lib/jaxen-1.1-beta-6.jar package useDom4j.test.supper;
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory;
import junit.framework.TestCase;
import org.dom4j.Document; import org.dom4j.DocumentFactory; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.QName; import org.dom4j.Visitor; import org.dom4j.VisitorSupport; import org.dom4j.XPath; import org.dom4j.io.DOMReader; import org.dom4j.io.HTMLWriter; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter;
public class useDom4jTest extends TestCase {
//use all private String path ; private ClassLoader clo; // file path -> bin private String classPath ; //use save static private Document doc; private String filese;
protected void setUp() throws Exception { super.setUp(); path = "useDom4j/test/config/test.xml"; clo = this.getClass().getClassLoader(); classPath = System.getProperty("java.class.path").split(";")[0] ; filese = System.getProperty("file.separator"); }
protected void tearDown() throws Exception { super.tearDown(); }
public void testRead()throws Exception{ SAXReader sax = new SAXReader(); //File read Document docF = sax.read( new File(clo.getResource(path).getFile()) ); assertNotNull("is File saxReader err",docF); //InPutStream read Document docI = sax.read( clo.getResourceAsStream(path) ); assertNotNull("is InPutStream saxReader err",docI); //URL read Document docU = sax.read( clo.getResource(path) ); assertNotNull("is Url saxReader err",docU); } /** converts a W3C DOM document into a dom4j document */ public void testConversion() throws Exception{ DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance(); DocumentBuilder dombuilder=domfac.newDocumentBuilder(); InputStream input = clo.getResourceAsStream(path) ; org.w3c.dom.Document doc3c = dombuilder.parse( input ); DOMReader xmlReader = new DOMReader(); assertEquals( " Conversion : W3C DOM-> dom4j DOM err", xmlReader.read(doc3c) instanceof Document,true ); } public void testCreate()throws Exception{ DocumentFactory factory = DocumentFactory.getInstance(); doc = factory.createDocument(); //root Create Element root = doc.addElement("testElement"); assertNotNull("is root Create err",root); Element author2 = root.addElement( "author" ) .addAttribute( "name", "Toby" ) .addAttribute( "location", "Germany" ) .addText( "Tobias Rademacher" );
Element author1 = root.addElement( "author" ) .addAttribute( "name", "James" ) .addAttribute( "location", "UK" ) .addText( "James Strachan" ); //Test Create //use XPath ->jaxen-xxx.jar assertEquals("create Element author2 err", doc.selectSingleNode("/testElement/author[@name='Toby']").getText() ,"Tobias Rademacher"); assertEquals("create Element author1 err", doc.selectSingleNode("/testElement/author[@location='UK']/@name").getText() ,"James"); }
public void testPrintingHTML()throws Exception{ String testSaveXml = "useDom4j/test/config/testHtml.html"; testSaveXml = classPath+filese+testSaveXml; File file = getFile(testSaveXml); //Save file.html HTMLWriter writer = new HTMLWriter(new FileOutputStream( file )); writer.write(new SAXReader().read( clo.getResource(path) )); writer.flush(); } public void testIterator(){ Element root = this.doc.getRootElement(); //Iterator Iterator elementIterator = root.elementIterator(); while(elementIterator.hasNext()){ Element element = (Element)elementIterator.next(); assertNotNull("not attr name", element.selectSingleNode("./@name") ); assertNotNull("not attr location", element.selectSingleNode("./@location") ); assertNotNull("not Text ", element.selectSingleNode(".").getText() ); } //for -> ./XX for ( int i = 0, size = root.nodeCount(); i < size; i++ ) { Node node = root.node(i); if ( node instanceof Element ) { Element element = (Element)node; assertNotNull("not attr name", element.selectSingleNode("./@name") ); assertNotNull("not attr location", element.selectSingleNode("./@location") ); assertNotNull("not Text ", element.selectSingleNode(".").getText() ); } } //List List elements = root.elements(); int size = elements.size() ; if ( size > 4 ) { elements.subList( 3, 4 ).clear(); assertEquals("List is not clear",size-elements.size()==1,true); }
} /** use test.xml test xpath -> /project/organization/ <organization> <name>MetaStuff Ltd.</name> <url>http://sourceforge.net/projects/dom4j</url> <logo>http://sourceforge.net/sflogo.php?group_id=16035</logo> </organization> xpath -> /project/dependencies/dependency[groupId='msv'] <dependency> <groupId>msv</groupId> <artifactId>xsdlib</artifactId> <version>20030807</version> <url>https://msv.dev.java.net/</url> </dependency> */ public void testXpath()throws Exception{ XPath xpathSelector = DocumentHelper.createXPath("/project/organization/*"); Document docT = new SAXReader().read( clo.getResourceAsStream(path) ); List results = xpathSelector.selectNodes(docT); for ( Iterator iter = results.iterator(); iter.hasNext(); ) { Element element = (Element) iter.next(); if(element.getName().equals("name")){ assertEquals("name err", element.getText().equals("MetaStuff Ltd."),true); } if(element.getName().equals("url")){ assertEquals("url err", element.getText().equals("http://sourceforge.net/projects/dom4j"),true); } if(element.getName().equals("logo")){ assertEquals("logo err", element.getText().equals("http://sourceforge.net/sflogo.php?group_id=16035"),true); } } // select String url = docT.valueOf( "/project/dependencies/dependency[groupId='msv']/url" ); assertEquals("Url err", url.equals("https://msv.dev.java.net/"),true); Number count = docT.numberValueOf( "/project/dependencies/dependency[groupId='msv']/version" ); assertEquals("Url err", count.intValue()==20030807,true); }
public void testVisitor(){ Visitor visitor = new VisitorSupport() { public void visit(Element element) { System.out.println( "Entity name: " + element.getName() + " text :" + element.getText() ); } };
doc.accept( visitor ); }
// element.clone ; element.createCopy ; public void testInsertElementAt() throws Exception{ Element root = this.doc.getRootElement(); Element oldElement = (Element)doc.selectSingleNode("/testElement/author[@name='Toby']"); Element newElement = (Element) oldElement.clone(); List list = root.content(); list.add( root.indexOf(oldElement)+1,newElement );
} public void testSave()throws Exception{ String testSaveXml = "useDom4j/test/config/testSave.xml"; testSaveXml = classPath+filese+testSaveXml; File file = getFile(testSaveXml); //Save file.xml XMLWriter writer = new XMLWriter(new FileOutputStream( file )); writer.write(doc); writer.flush(); }
private File getFile(String testSaveXml) throws IOException { File file = null ; URL url = clo.getResource(testSaveXml); if(url==null){ file = new File(testSaveXml); file.createNewFile(); }else{ file = new File( url.getFile() ); } return file; } }
引用:http://freezingxu.blog.com.cn/archives/2006/1892647.shtml /** * 对指定的节点增加属性和文本 * @param elmt * @param name * @param value * @param text * @return */ public Element addAttribute(Element elmt,String name,String value){ elmt.addAttribute(name,value); return elmt; } /** * 修改指定节点的属性和文本 * @param elmt * @param name * @param value * @param text * @return */ public Element setAttribute(Element elmt,String name,String value){ Attribute attribute = elmt.attribute(name); //attribute.setName(name); attribute.setValue(value); List list = new ArrayList(); list.add(attribute); elmt.setAttributes(list); return elmt; } /** * 删除指定节点的指定属性 * @param elmt * @param name * @return */ public Element removeAttribute(Element elmt,String name){ elmt.remove(elmt.attribute(name)); return elmt; } /** * 输出为文件 * @param doc * @throws IOException */ public void writeFile(Document doc) throws IOException{ FileWriter out = new FileWriter( "d:/newQuery.xml" ); doc.write(out); out.flush(); out.close(); }
看hbn 源代码 发现用了 CGlib 这就看看这个jar 。特留个文 ^_^(转)http://www.nirvanastudio.org/java/cglib-%E6%8C%87%E5%8D%97.html
CGlib 就2个例能说明一切 先是使用类 public class MyClass { public void method() { System.out.println("MyClass.method()"); }
public void method2() { System.out.println("MyClass.method2()"); } }
例1: import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.MethodInterceptor; public class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); //在这代理了 enhancer.setSuperclass(MyClass.class); enhancer.setCallback( new MethodInterceptorImpl() ); // 创造 代理 (动态扩展了MyClass类) MyClass my = (MyClass)enhancer.create(); my.method(); } private static class MethodInterceptorImpl implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(method); proxy.invokeSuper(obj, args); return null; } } } 例2: import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.NoOp; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.CallbackFilter; public class Main2 { public static void main(String[] args) { Callback[] callbacks = new Callback[] { new MethodInterceptorImpl(), NoOp.INSTANCE }; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MyClass.class); enhancer.setCallbacks( callbacks ); //添加 方法过滤器 返回1为不运行 2 为运行 enhancer.setCallbackFilter( new CallbackFilterImpl() ); MyClass my = (MyClass)enhancer.create(); my.method(); my.method2(); } private static class CallbackFilterImpl implements CallbackFilter { public int accept(Method method) { if ( method.getName().equals("method2") ) { return 1; } else { return 0; } } } private static class MethodInterceptorImpl implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(method); return proxy.invokeSuper(obj, args); } } } 简单不 哈哈 比jdk 中的动态代理好用 ,那还要接口 不太方便 。
参照: 容器外的JSP页面测试技术由于上面给出例 复杂 。一般人很难理解。我也是 ^_^ 但仔细看我还是自己写出一个比较简单的,望大家一起讨论。 被测试jsp
<%@ taglib prefix="html" uri="/WEB-INF/struts-html.tld" %> <%@ taglib prefix="c" uri="/WEB-INF/c-1_0-rt.tld" %> <html:html> <c:if test="${name != pass}"> ${name} <br> ${pass} <br> <!-- <html:text property="in" ></html:text> --> </c:if> </html:html>
ant直接把他放在 eclipes 工程的根目录下 build.xml 但有有3个参数要设置 tomcat.home Tomcat 的地址 webapp.path 工程中的根目录,下面有WEB-INF src 原代码 (到时候jsp会翻译成.java 到这个目录的 org.apache.jsp.jsp 下)
<project name="Webapp Precompilation" default="all" basedir=".">
<!-- tomcat dir --> <property name="tomcat.home" value="D:\Tomcat 5.0"/> <!-- this=..//WEB-INF (in eclipes) --> <property name="webapp.path" value=".\WebRoot"/> <!-- src (in eclipes) --> <property name="src" value="./src"/>
<target name="jspc"> <taskdef classname="org.apache.jasper.JspC" name="jasper2" > <classpath id="jspc.classpath"> <pathelement location="${java.home}/../lib/tools.jar"/> <fileset dir="${tomcat.home}/bin"> <include name="*.jar"/> </fileset> <fileset dir="${tomcat.home}/server/lib"> <include name="*.jar"/> </fileset> <fileset dir="${tomcat.home}/common/lib"> <include name="*.jar"/> </fileset> </classpath> </taskdef>
<jasper2 validateXml="false" uriroot="${webapp.path}" webXmlFragment="${webapp.path}/WEB-INF/generated_web.xml" outputDir="${src}" /> </target>
<target name="compile">
<mkdir dir="${webapp.path}/WEB-INF/classes"/> <mkdir dir="${webapp.path}/WEB-INF/lib"/>
<javac destdir="${webapp.path}/WEB-INF/classes" optimize="off" debug="on" failonerror="false" srcdir="${src}" excludes="**/*.smap"> <classpath> <pathelement location="${webapp.path}/WEB-INF/classes"/> <fileset dir="${webapp.path}/WEB-INF/lib"> <include name="*.jar"/> </fileset> <pathelement location="${tomcat.home}/common/classes"/> <fileset dir="${tomcat.home}/common/lib"> <include name="*.jar"/> </fileset> <pathelement location="${tomcat.home}/shared/classes"/> <fileset dir="${tomcat.home}/shared/lib"> <include name="*.jar"/> </fileset> <fileset dir="${tomcat.home}/bin"> <include name="*.jar"/> </fileset> </classpath> <include name="**" /> <exclude name="tags/**" /> </javac>
</target>
<target name="all" depends="jspc,compile"> </target>
<target name="cleanup"> <delete> <fileset dir="${webapp.path}/WEB-INF/src"/> <fileset dir="${webapp.path}/WEB-INF/classes/org/apache/jsp"/> </delete> </target>
</project> TEST
package jetty.test.supper;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.apache.jsp.jsp.MyJsp_jsp;
import com.meterware.httpunit.GetMethodWebRequest; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebResponse; import com.meterware.servletunit.InvocationContext; import com.meterware.servletunit.ServletRunner; import com.meterware.servletunit.ServletUnitClient;
import junit.framework.TestCase;
public class JSPCTest extends TestCase{ private InvocationContext ic = null ;
protected void setUp() throws Exception { ServletRunner sr = new ServletRunner(); // 向环境中注册 jsp sr.registerServlet("HelloWorld", MyJsp_jsp.class.getName()); ServletUnitClient sc = sr.newClient(); WebRequest request = new GetMethodWebRequest("http://localhost/HelloWorld"); ic = sc.newInvocation(request);
} public void testJspC() throws Exception{ HttpServletRequest re = ic .getRequest(); HttpServletResponse rq = ic.getResponse(); re.setAttribute("name","liukaiyi"); re.setAttribute("pass","123456"); MyJsp_jsp is = (MyJsp_jsp) ic.getServlet(); is._jspService(re,rq); WebResponse response = ic.getServletResponse(); // 输出 System.out.println( response.getText() ); } } 结果是
<html> liukaiyi <br> 123456 <br> </html>
后面用 HttpUnit 和 HtmlUnit 测试就不用我说了把 网上一大把。
学习测试留个印
测试 Servlet 使用:
package
jetty.test.supper;
import
java.io.File;
import
javax.servlet.http.HttpServletRequest;
import
jetty.LoginServlet;
import
com.meterware.httpunit.GetMethodWebRequest;
import
com.meterware.httpunit.WebConversation;
import
com.meterware.httpunit.WebRequest;
import
com.meterware.httpunit.WebResponse;
import
com.meterware.servletunit.InvocationContext;
import
com.meterware.servletunit.ServletRunner;
import
com.meterware.servletunit.ServletUnitClient;
import
junit.framework.TestCase;
public
class
HttpUnitTest
extends
TestCase {
public
void
ctestUrl()
throws
Exception{ System.out.println(
"
直接获取网页内容:
"
); WebConversation wc
=
new
WebConversation(); WebResponse wr
=
wc.getResponse(
"
http://www.google.com
"
); System.out.println( wr.getText() ); }
public
void
testRun1()
throws
Exception{ System.out.println(
"
无参数测试:
"
);
//
建立服务器
ServletRunner sr
=
new
ServletRunner(
new
File(
"
WebRoot\\WEB-INF\\test.xml
"
));
//
模拟客户端
ServletUnitClient sc
=
sr.newClient();
//
URL 定位
WebRequest request
=
new
GetMethodWebRequest(
"
http://localhost:7000/cactusDemo
"
); WebResponse response
=
sc.getResponse( request );
//
运行
System.out.println(response.getText()
+
"
\n
"
); }
public
void
testRun2()
throws
Exception{ System.out.println(
"
Session 和 request 测试:
"
); ServletRunner sr
=
new
ServletRunner(
new
File(
"
WebRoot\\WEB-INF\\test.xml
"
)); ServletUnitClient sc
=
sr.newClient(); WebRequest request
=
new
GetMethodWebRequest(
"
http://localhost/cactusDemo
"
);
//
Parameter 加参 use
request.setParameter(
"
use
"
,
"
web
"
);
//
取出 Servlet : LoginServlet 方法准备执行
InvocationContext ic
=
sc.newInvocation( request ); LoginServlet se
=
(LoginServlet)ic.getServlet(); HttpServletRequest re
=
ic.getRequest() ;
//
request session 加参 use
re.setAttribute(
"
use
"
,
"
re
"
); re.getSession(
true
).setAttribute(
"
use
"
,
"
re
"
);
se.doGet(re,ic.getResponse());
//
关键:运行测试方法
//
获取 out
WebResponse response
=
ic.getServletResponse(); System.out.println(response.getText()); } }
test.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<
web-app
xmlns
="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
version
="2.4"
xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>
<
servlet
>
<
servlet-name
>
cactusDemo
</
servlet-name
>
<
servlet-class
>
jetty.LoginServlet
</
servlet-class
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
cactusDemo
</
servlet-name
>
<
url-pattern
>
/cactusDemo
</
url-pattern
>
</
servlet-mapping
>
</
web-app
>
测试 JSP:
Cookbook
参考
不使用容器 进行 测试 jsp
测试Struts:
StrutsTestCase
参考
|