该用户从未签到
|
1、创建Web Project2 x$ f$ L) S# R) t, x6 K+ V
2、web工程与struts2整合+ q9 p8 b/ h" ^ a! C
(1)添加struts2类库) c6 V/ v5 `/ `
struts2-core-2.1.8.1.jar
" T% n6 I. m) h( n* }- G0 X+ V xwork-core-2.1.6.jar
V- r& k0 f, c3 O. P commons-fileupload-1.2.1.jar
4 M! i3 G# L- j; B commons-io-1.3.2.jar1 y1 d3 V2 l6 O5 V- A
ognl-2.7.3.jar) j) T/ w# e* u$ T/ i) d) p( v
freemarker-2.3.15.jar
* u: W# H2 Q* F! ^0 P& Y (2) 在web.xml文件中添加struts2集成' [; R1 }2 O9 _9 H+ q* _3 M
<filter>9 M3 ^( z/ k0 [( }
<filter-name>struts</filter-name>
$ i! f* K8 A- T9 Q$ v! L1 d) A <filter-class>* U, }* w+ I8 L
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter; L; o9 P) a! U" D5 v: S9 X6 {
</filter-class> ]! F8 Z- O4 t/ R9 S) m4 h
<init-param>3 A: V, d3 ]8 N' I
<param-name>config</param-name>( X( Y1 M4 E& p. P; x0 E `) I8 i
<!--$ k+ E& g2 C9 u
修改struts2默认配置文件,
, k. y; S0 r& K# j 必须把struts-default.xml,
; a7 z1 k( u0 B, P! E6 P struts-plugin.xml一起添加
5 j5 |% C6 Z" c5 t1 N0 l6 u 必须:按顺序添加7 R J `+ p8 x2 U. S( K8 E
-->
4 |/ }( G% \( a& ? <param-value>
! z3 l9 R1 J" ^9 O+ F, P% d struts-default.xml,struts-plugin.xml,config/struts/struts.xml
) W! @! v! A8 m: v( q5 S </param-value>, [0 R, Z) a/ [+ n3 T
</init-param>
5 L; o, Z, _6 W8 `; T6 P- \. z </filter>
( ?! j+ S1 p( j& f: ]! o2 m <filter-mapping>$ t" u- }6 O3 A# j- i0 [* e6 _" y2 s
<filter-name>struts</filter-name> I$ m8 q+ v, r" U7 \% g
<url-pattern>/*</url-pattern>- Q8 d2 O) |9 n% i9 Z3 T o
</filter-mapping> $ j. z) |. T3 I! T' N
<!--struts2 *.action struts2 *.do-->& ^" i8 s* }2 j% V# J! ]5 \
(3)创建struts2配置文件struts.xml配置 ' P5 V# g+ h9 t+ O) Q
(4)完成页面跳转 {4 s% y3 T M8 H+ r$ s, e7 _
3、测试struts2工程' K0 v9 a8 P, r
4、struts2与spring集成0 X- G4 F( u; t! h! ^( n3 M3 b3 r
(1)添加spring类库与struts支持spring插件
" T. B8 w" |- z: h5 o: @7 `( M3 m struts2-spring-plugin-2.1.8.1.jar
# K f& e3 W* h$ }7 d; ?. s4 W cglib-nodep-2.1_3.jar9 X7 O* N* p/ ]$ D+ Q Y! o
commons-logging.jar
/ P1 W6 U( W* R4 ` log4j-1.2.15.jar5 A) _- H6 ?4 \/ g
spring.jar0 p5 O1 ~/ }9 M! B2 N
dom4j-1.6.1.jar* j, S( J" @. F; K& m
(2)在web.xml中完成spring集成
3 s8 b8 T8 y, x) F) d8 c0 s <listener>3 W7 e6 d1 A0 X9 u" p6 _' e
<listener-class>% y0 C. p+ H- M$ ?% ?+ F
org.springframework.web.context.ContextLoaderListener
# N5 e% t2 I* u2 S: N </listener-class>; ^3 f# E$ {# W9 W* {/ k# N5 U
</listener>
; i' G% v+ A }" z9 V <context-param>
+ p2 x( z# m$ D& O& o <param-name>contextConfigLocation</param-name>% }0 K( _6 i8 h D$ [
<param-value>
- {/ c" o% x$ k/ z' _4 G" C& g/ O classpath:config/spring/applicationContext.xml0 ?- [8 W a6 k, C' O+ g: [
<!--classpath:config/spring/applicationContext*.xml-->/ V8 j& P" q& ?% }% j
</param-value>( N1 T* z" Q+ g, ^& j6 j9 x# h
</context-param> O; ~! \+ X) n' \# }& s
(3)创建spring配置文件applicationContext.xml0 r% }9 k6 J. E8 z' v# a
(4)在struts2配置文件中添加spring 集成常量" a" V C, w0 q# o
<!-- 设置集成spring框架 -->! _% }! H8 ~4 y- {
<constant name="struts.objectFactory" value="spring"/>
( d7 P z0 f$ Z (5)spring管理struts2中Action
5 b/ w# R, N/ ~. d6 ~0 e( X2 ~# t (1)在spring 配置文件中加入bean管理- _3 W! y5 |9 D9 A+ S, F
<bean id="userAction" class="com.tarena.web.action.UserAction" >/ l7 G1 I! d; ?% N
</bean>
" H& E' a$ x+ l6 l; G7 i! S (2)修改struts-user.xml配置" D. v2 k( T6 F: ]+ I
<action class="userAction" >
" B" E$ c! o% E7 o </action>
1 f M1 s0 h5 @& O) }6 o9 u/ r5 测试struts+spring集成
% m r% a% M+ T0 ?. e6 spring+hibernate集成5 w* u; E( _/ C: q
(1)添加hibernate类库% z. w$ u3 X$ S% L! T9 x6 J' g# A
slf4j-nop-1.5.8.jar* _2 x* O- z3 }+ l7 c6 \, D" z
slf4j-api-1.5.8.jar4 `: F0 ^! V7 R8 `; Z) S
jta-1.1.jar
9 C( C! O+ C' @# q7 j# A+ K javassist-3.9.0.GA.jar
' t0 _ `- I, p; G hibernate3.jar; `. v! N$ D& J7 q8 l5 ?3 K
commons-collections-3.1.jar, W; a& j* U, Z( s; Z; t
antlr-2.7.6.jar& L5 q' I" |% R! h. h9 Q( [
(2)添加MySQL驱动类库
) i7 q8 U. g& s4 ~3 l4 o6 i/ T mysql-connector-java-5.1.16-bin.jar
3 ?& b. c, L1 c9 K& J0 ]1 w (3)创建实体类
' q2 |1 |' T C3 d' U7 e. K (4)编写User.hbm.xml映射文件
4 {- O" g6 d: }2 R7 S# U (5)反向生成表结构4 n) s" t P% m6 |2 B7 ], Z
(6)spring管理hibernate
* Z/ T2 k, U1 B1 N: t 在spring applicationContext.xml配置文件中添加spring对hibernate管理( a0 O8 z% l5 U* S6 ]3 z1 L
(A) 添加DBCP连接池" T" a- [7 Q8 Z. \( b
a、添加类库
0 n0 J6 S5 B# a' C8 i$ ^$ T8 v commons-dbcp.jar
$ y$ e6 T6 w2 I- R1 m commons-pool.jar
% L& o0 L1 D' k( ^ b、applicationContext.xml在配置连接池
! `& x% F( @2 R% j0 [ <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
% p: C( E5 c8 u/ i6 P. t8 `" D <property name="driverClassName" value="com.mysql.jdbc.Driver"/>" C& k- T& G/ S% ~: U" U+ H
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb"/>' } w9 M" r" B8 } W
<property name="username" value="root"/>
% N) j- J, Y+ j& r" h <property name="password" value="1234"/>% N, h8 `2 D* `3 ?: W! ]8 l
<property name="initialSize" value="2"/>4 Y5 n* M7 h9 G# @
<property name="maxActive" value="8"/>5 S" Q- J5 C$ {' m: W. |# Z
<property name="maxIdle" value="5"/>
7 ]$ g% p7 x9 N3 H2 O9 @* e( ^ <property name="minIdle" value="3"/>
0 e1 ~2 C. b* i7 q <property name="maxWait" value="3000"/>) d# u: L/ d2 U9 X& I
<property name="removeAbandonedTimeout" value="60000"/>
! ^# f. z- G9 o% i- G. g <property name="removeAbandoned" value="true"/>2 S, V( Q- R- j) [
</bean>
" S8 R* Q" g8 c$ N 连接池参数如下:
2 |# n: P S" P initialSize
" c: V! k! [3 p& c6 s3 L" x 连接池启动时创建的初始化连接数量# H/ k' t% V3 e0 v, h
(默认值initialSize :连接池启动时
* v( Y5 b3 v' \8 F5 m6 D+ I, Q3 j 创建的初始化连接数量(默认值为0)
/ q+ R+ `9 z$ [ q U maxActive & }; \( k1 B- J- e! `
连接池中可同时连接的最大的连接数 S6 b0 P( s& o3 z
(默认值为8 ,调整为20,高峰单机器在20并发左右,
. I0 e% s; ^, o9 l1 a4 V 自己根据应用场景定) , i1 _- @9 |. K3 @+ r7 l, m+ O0 @
maxIdle7 Z2 } h1 H0 @) Z T7 g* N2 X* d/ v
连接池中最大的空闲的连接数,
) F5 @+ |$ l: J. h) b) d G' V1 d0 z 超过的空闲连接将被释放,
3 u) e. k- g8 X5 }4 V5 s+ F 如果设置为负数表示 不限制(默认为8个)
: A" P( N7 J) Y/ @" ~5 ^* X minIdle
# e, o5 b5 e2 ?/ b* u# t/ W% T 连接池 中最小的空闲的连接数,低于这个数量会被
, g+ l. }* s, F3 x$ Q3 t$ w 创建新的连接(默认为0,调整为5, 该参数越接近: R" ^# _' d# x* m" j8 T3 u
maxIdle,性能越好,因为连接的创建和销毁,
# T) e5 X; \0 ?; b 都是需要消耗资源的,但是不能太大,; b( D n. h* D
因为在机器很空闲的时候,也会创建低于
% r+ E9 l5 p. K0 x8 o4 e2 T" j) F Y minidle个数的连接) & [# v$ [5 D; {9 }
maxWait
1 T2 l$ H% b$ R* N 最大等待时间,当没有可用 连接时,: a% T; n1 j# ~& c; H. g
连接池等待连接释放的最大时间,2 c4 X2 k. h7 V
超过该时间限制会抛出异常,8 @+ m5 D& P* l4 q% V3 y2 U. w
如果设 置-1表示无限等待(
9 }7 n! M- `: x. S* M 默认为无限,调整为60000ms,: n8 L F4 D$ n0 E% P# k3 }( `
避免因线程池不够用,而导致 请求被无限制挂起) ' T/ c% o: N4 }6 p7 l( l
removeAbandonedTimeout :
" W+ V' k! `2 d$ B8 S; M 超过时间限制,回收没有用(废弃)的连接
4 m* W& m# c3 Z7 [% C# e (默认为 300秒,调整为180) * C9 p/ Y" o& J% B, V
removeAbandoned :
! P' e# L5 A+ h0 O( Y 超过 removeAbandonedTimeout时间后," Q" @' B* E- R' G
是否进行没用连接(废弃)的回收$ z e/ t. V! e& g& Y
(默认为 false,调整为true)
, b* ~; n* k: p( b2 K) I/ ?$ { (B)spring管理hibernate实体映射文件:
( T. h: z: Q2 [# ? <bean id="sessionFactory"* t5 o4 C' T3 G
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">' M+ z& ^5 T r( B
<property name="dataSource" ref="dataSource" />
/ w" X: g, D. P$ n7 V) l <property name="hibernateProperties">
# E1 S# a, A. \" C6 k: C; m' s <props>, o* S: M9 E: `! h4 r& `" r9 g
<prop key="hibernate.dialect">% r" Q; V# c8 x. ~' w: Y
org.hibernate.dialect.MySQLDialect. t1 O1 E5 b+ Q! p( j
</prop>
: w& `0 q- e' E" u3 k <prop key="hibernate.show_sql">true</prop>
3 r9 |6 ?" Z4 c <prop key="hibernate.format_sql">true</prop>
3 H& @3 x: J7 T5 T- m </props>
6 N* E! H4 T( X8 L </property># z% b8 V( J( q9 H# Q! b0 d4 R$ {
<property name="mappingLocations">
* F/ r) ?# r2 C4 u4 e" S# w <list>& `" K' I0 P1 J. G
<value>
: E4 Q. {2 r! h# [0 j, @7 w classpath:config/hibernate/hbm/User.hbm.xml
, G" o+ F0 f" }, I </value>- V {" O, D7 Q. K" m. t
</list>6 B! I' P# R' h0 f* b
</property>5 @3 o* d$ S6 K( `) n3 l. B" K
</bean>
% \# L" x/ F% v! [% B) O" m* J (C)spring读写属性(properties)文件: ?( s' h! N1 [
a、创建属性文件 db.properties- p4 L& p( w9 ^; E# Q9 R& M
b、在applicationContext.xml配置
& O, L/ l* a, @/ j. r& m, R <bean id="propertyPlaceholderConfigurer"
- D$ |9 q7 W) A( k! c1 X0 c( E class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
" e7 y7 p* D* I: e; s* t. u <property name="locations">2 X1 j2 u* H+ O& }" ^3 _2 X
<list>
) S: d% u# `' e" [% t9 s" r4 i <value>classpath:config/props/db.properties</value>
6 r1 b5 Y. V0 I, d P7 n, e/ ` </list>
3 V1 V5 e0 K' R </property>
8 E4 {& Q# U) r1 s9 B- I </bean>5 A# M& x! \; W9 C( B* I
c:引用: ${username}
' \5 U1 q" W( f# `0 F& B5 C / ~) u$ _$ \1 ?$ J, I" z5 B C! ?8 v# i
(8)spring分文件管理
c: f4 ?1 W! r <!-- 引入其他spring 配置文件 -->
+ R7 I6 t- G# Y ?! m% h7 N applicationContext.xml引入下列文件
. ^, I4 U) G2 B' j <import resource="applicationContext-web.xml"/>9 A9 A+ ^. Z2 B9 v
<import resource="applicationContext-biz.xml"/>
$ e2 t; ]9 z/ U% W <import resource="applicationContext-dao.xml"/>
! t+ w& A8 G# _) L. b7、开发数据访问层8 X' C& o/ Y c( h. F+ }0 v
使用spring提供hibernate 模板类 HibernateDaoSupport
2 x; o8 t" r% v+ p4 J UserDaoImpl extends HibernateDaoSupport4 V. T) n' S7 l; w
在UserDaoImpl注入到spring 配置文件 applicationContext-dao.xml, H! ]/ n. A7 [* a, Q7 Y4 q3 o
<bean id="userDaoImpl" class="com.tarena.dao.impl.UserDaoImpl">
. |8 g6 t. R- v r <!--HibernateDaoSupport中的sessionFactory--> m4 p8 d! C2 ?! t( _: s
<property name="sessionFactory" ref="sessionFactory" />
9 S. l: b8 n; X5 ~8 ~9 C' S2 X </bean>, B7 H( L7 m; z
8、添加spring声明事务管理(AOP)" H' {, n! b1 R; x9 w
声明式事务管理:" K# R7 P9 z0 p8 V
添加spring 类库- a5 i# Z" _, o+ E- L8 n2 C& y* b
aspectjrt.jar2 l9 S( W- |8 c) C6 S
aspectjweaver.jar
2 b8 E" ~: V h% n& K2 u2 D 了解事务的几种传播特性
5 U1 q* A2 Z& r" Y- i) _# ?) w, M$ R, r+ V8 p
(1)PROPAGATION_REQUIRED: 5 R Q4 K1 \1 [2 R0 G
如果存在一个事务,则支持当前事务,如果没有事务则开启。
" Y" V2 | Q. k. X9 P2 p (2)PROPAGATION_SUPPORTS:
1 V6 Q% b' p: r* s 如果存在一个事务,支持当前事务。; q6 ` D5 |% l9 z
如果没有事务,则非事务的执行。
5 y9 A8 E4 Y0 S9 P. `! Q5 V. t (3)PROPAGATION_MANDATORY: ' N: {, R" i$ k' N
如果已经存在一个事务,支持当前事务。
7 T/ f1 ^! \4 H* h5 D+ q 如果没有一个活动的事务,则抛出异常。 |( D) ~2 r0 q2 k! @2 t+ Z2 v. o) x n
(4)PROPAGATION_REQUIRES_NEW: 4 y# {7 L. U8 T3 v) `, T6 M
总是开启一个新的事务。如果一个事务已经存在,) V, t% ^0 J# J8 S# l7 S
则将这个存在的事务挂起。
& s2 R% F! c$ k" \1 w (7)PROPAGATION_NESTED:(spring特有) z& r- c7 O! g0 V- F
如果一个活动的事务存在,则运行在一个嵌套的事务中. - L1 p9 {9 `% d( R/ B% p& f- c
如果没有活动事务, 则按TransactionDefinition.# @& }7 X; i/ L. f0 Z1 q
PROPAGATION_REQUIRED 属性执行) W: ~ z @$ ~7 H
( W6 B; R) A. Q" s, L, `# ]
(5)PROPAGATION_NOT_SUPPORTED: 9 Y* [: T7 c' T1 U# r9 v
总是非事务地执行,并挂起任何存在的事务。
- t% a- D! g" h1 m" Q (6)PROPAGATION_NEVER:
4 I$ X% z8 B# f' a6 h% y2 l 总是非事务地执行,如果存在一个活动事务,则抛出异常。0 \, G; X$ n8 Q! j4 u
7 M z3 t& m4 s: g+ T3 @
# {# Z- q& U6 `' n% b3 n" x0 |1 I <!-- 配置声明事务管理 spring2.x-->
6 H$ [, m1 W* y F <!-- 定义事务管理 -->
7 S' h, N1 i& [0 f9 V# ]3 _ <bean id="transactionManager"
/ A2 y9 [$ \5 D" {1 J) H" o class="org.springframework.orm.hibernate3.HibernateTransactionManager">3 y* \! q9 V- j( O
<property name="sessionFactory" ref="sessionFactory" />
# N& @+ u4 ^+ v5 T. t+ u$ Q) \ </bean>
2 w* i' T3 P1 Z f/ ?/ A' ` <!-- 事务规则 -->- z" i! l, k+ T! |/ h" Y
<tx:advice id="tmAdvice" transaction-manager="transactionManager">
9 s, c% n' N; U+ s& H+ { <tx:attributes>7 N. m2 P3 t0 ?
<!--*通配符 save* 方法名必须是以save开始-->0 q; ^6 U* ?; L4 j2 v2 L2 M! o
<tx:method name="save*" propagation="REQUIRED" />
# y, Y7 X2 J' ]; j <tx:method name="update*" propagation="REQUIRED" />/ Y6 x+ [ l1 f+ ?& s: ^$ W
<tx:method name="delete*" propagation="REQUIRED" />, e, m9 t D1 l `! ^
<tx:method name="find*" read-only="true" />! g- {" C- D. g+ b
<!-- read-only 只读:-->
3 {* T) p- o" x/ @3 D* i- J+ ^ l8 d </tx:attributes>' ` _4 p' G. F8 T" g
</tx:advice>
D7 E. B5 \$ w4 c- p; m1 [ <aop:config>
- ^7 _. ~4 ?9 U3 i# W3 M9 o8 k <!-- point cut -->
" {* M# W& _5 K' `4 z* h <aop:pointcut id="pointCut"
' d" T) S, \& k) h; _& { expression="execution(* com.tarena.biz.*.*(..))" />
7 C/ K+ N5 M! A' f: P1 y. m <aop:advisor advice-ref="tmAdvice" pointcut-ref="pointCut"/>
0 L1 B! @2 n+ h* y </aop:config>5 n1 w( [. K6 G% F) q: j5 Z, j
- a2 _6 n( ~- [7 O8 w
9、测试
4 o8 p1 W( U. B( s 添加测试类库 spring2.5.6" s r& P7 q4 x/ {
junit-4.4.jar
, v/ k2 ?* J& O+ _' f spring-test.jar# |1 u: j. R8 J! v2 l
//使用spring测试& _: m* `! X4 _6 b9 x( |
@RunWith(SpringJUnit4ClassRunner.class)0 N: }2 o- o. b- P# t
//加载spring配置文件4 r4 T1 W" Q: L9 g5 D
@ContextConfiguration(locations = {1 y* g+ u+ W) S
"classpath:config/spring/applicationContext.xml",
3 ^# T5 j& w$ u( v) k0 W "classpath:config/spring/applicationContext-dao.xml",
0 T- f. ?3 y5 t# e* m9 T "classpath:config/spring/applicationContext-biz.xml",+ V' T/ C% T2 J# Y
"classpath:config/spring/applicationContext-web.xml" })2 I {% O( U- q/ J# q: R
//自动注入
: p" N) S7 s5 V. b5 m @Autowired
, f" V* X2 n( V* N% m private IUserDao iuserDao;" j0 |7 p% J0 ~- @" x1 _
3 J6 m Q; c1 q7 [% \) W2 U
@Test( \2 [' [4 U- \, G) U" u
public void saveUserTest(){7 D) s% z* k& i! b
//测试方法
/ ~& s' D; }4 W* W }
1 _/ Z4 n( x) c$ [; t10、完成业务层代码编写, ?2 S' O: k1 ]$ U
11、完成表示层代码编写
4 N$ A: a" Y# ?) i& z* t3 ]6 \12、测试工程0 w* w! b$ K" P- W; W" T& k
# Z- ^: a+ g- e' V1 r: t# n2 l
13、spring处理hibernate延时加载+ [0 e g% K0 O* F+ T9 }
1、配置延时过滤器
3 C4 L) ?0 S# f7 u9 K OpenSessionInViewFilter.class# M1 C, C1 T7 V ^* a2 f% ?
2、在web.xml配置OpenSessionInViewFilter; @# Z0 f5 I4 I- T) Q
/ V) T' Y) b+ V2 v+ b& } <filter>2 ~2 w- Z; X( h% W0 R! g
<filter-name>openSessionInViewFilter</filter-name>9 Y1 n9 V3 Y+ n
<filter-class>
' F0 N4 z1 y: {& V org.springframework.orm.hibernate3.support.OpenSessionInViewFilter) z4 s2 i M; C( q# g
</filter-class>
1 z( [" a' S# l: I2 f1 Z <init-param>
/ r8 c7 O: ?# a. j- f8 R <param-name>sessionFactoryBeanName</param-name>
4 V0 Y& A( v0 |# M' U7 J8 | <param-value>sessionFactory</param-value>
4 t! p1 K( L0 Y' ] </init-param>1 b; o$ n2 ?- M7 M$ ?
</filter>: g# B8 K. a3 w
<filter-mapping>
( R/ d$ W2 }2 v+ w( j: V# A; t. c <filter-name>openSessionInViewFilter</filter-name>
% a* z8 G! e3 n1 A" b; ?; P- i <url-pattern>/*</url-pattern>
. ]2 t3 y+ c/ P$ \: r9 s: b </filter-mapping>+ t; R: r0 N3 i$ ]" m) r
* s* Z# w" ^& C5 G
|
|