|
该用户从未签到
|
1、创建Web Project8 j c! K" o4 T" \! b b8 \
2、web工程与struts2整合
% l- _, n) @9 @ (1)添加struts2类库
6 b! g( p/ a { struts2-core-2.1.8.1.jar- X3 v/ x+ |* C4 G: } j
xwork-core-2.1.6.jar
4 g; j+ A# S* ^" b8 L commons-fileupload-1.2.1.jar
" D: |# G/ x: d commons-io-1.3.2.jar- y) }" A: O, \9 D3 u
ognl-2.7.3.jar
" _$ [& [3 W8 ~ freemarker-2.3.15.jar' [/ g$ U, A) g/ X% q" s, D: }% f
(2) 在web.xml文件中添加struts2集成
% x( g& Y m/ U) ~ j( W8 B <filter>" \1 u, i! f3 l# B2 e
<filter-name>struts</filter-name>
) ?( \6 [- ^% d* b! m8 `7 d <filter-class>
n% j& z& o8 I org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
; _& k0 h8 O, ~! ]5 D3 R </filter-class>
# n. M# r, I. \ O& P0 }+ Z5 n <init-param>( [8 x1 R7 x7 Y
<param-name>config</param-name>1 h% ?9 E) h- e
<!--
. x! g) f2 I) Q3 `( f0 \& G5 G 修改struts2默认配置文件,; P- n9 ]9 O, k9 f+ b" a0 ^
必须把struts-default.xml,
& A# k* z3 H2 S2 {! L struts-plugin.xml一起添加
9 W$ b3 \! f. T0 P& s R 必须:按顺序添加; ?7 r8 k7 O/ }! k) K8 p& c
-->8 R* G/ |% [+ `( E
<param-value>0 F4 c& W: {! x+ L6 w0 x
struts-default.xml,struts-plugin.xml,config/struts/struts.xml
' B( }7 X$ r+ q </param-value>5 H& @' ]! q' |4 P$ l4 Z9 v, b& @
</init-param>' b7 R2 Z2 K2 Q
</filter>
3 `/ G/ [# }+ j8 Z) k8 e0 E q <filter-mapping>
/ U# I) e' g* u+ u; U( _5 n <filter-name>struts</filter-name>
. l. O1 a6 f6 Y, C# M <url-pattern>/*</url-pattern>
) F. G/ {% i6 A1 I( P* |5 z </filter-mapping> ' m# B( p8 U! D1 `3 q+ _* ^
<!--struts2 *.action struts2 *.do-->
* d" a4 g7 ^. @3 g1 O% _ (3)创建struts2配置文件struts.xml配置 " C9 N5 \" [% I6 ]. a9 @7 y0 n$ ]
(4)完成页面跳转
/ R4 [* c* c5 u: T4 m- G# z3、测试struts2工程
$ ~8 P+ r$ R) p$ t; _6 v4、struts2与spring集成
# k( N, w: q5 h2 {5 A (1)添加spring类库与struts支持spring插件
! g$ g. ^' K0 K& { struts2-spring-plugin-2.1.8.1.jar
: ?7 I9 y/ M2 Y( c: L: f cglib-nodep-2.1_3.jar
+ d" M1 }4 O2 q commons-logging.jar' Z7 X3 l# i! N4 y
log4j-1.2.15.jar/ p( k, r X/ U) [8 ~
spring.jar+ {3 R3 K6 h& @* V" F
dom4j-1.6.1.jar
+ o: L$ O/ |8 B/ D (2)在web.xml中完成spring集成& ^# d( w4 c; w; b
<listener>
- M# r6 }& I: t& z1 I+ v" t, I <listener-class>; r. S7 V0 V ? e2 P
org.springframework.web.context.ContextLoaderListener, `: Q! J+ R0 W- W" P2 S- B& _
</listener-class>& _6 Z9 k6 H3 C1 @. F K
</listener>4 n# n+ a! }7 S8 y
<context-param>" F( `0 w, Q) K
<param-name>contextConfigLocation</param-name>8 b6 z A$ N4 d4 B, p$ W# T
<param-value>
: Z; u" a6 J8 `4 |) y classpath:config/spring/applicationContext.xml- p) n0 C0 q: J& L& `
<!--classpath:config/spring/applicationContext*.xml-->
! I- ^/ T7 G: ^- P9 i; n3 F </param-value>7 q' g+ I( u8 x0 M( w
</context-param>. N" `- m, F( Z% ?! G' _
(3)创建spring配置文件applicationContext.xml
n; m5 e1 c$ |" A" E (4)在struts2配置文件中添加spring 集成常量' b) K; ?" Y4 ^1 h1 a+ e
<!-- 设置集成spring框架 --># a2 Q! h4 T9 L
<constant name="struts.objectFactory" value="spring"/>
7 K F' p" O0 d9 f; R$ ?1 h" J# i (5)spring管理struts2中Action) G! ^5 X/ O+ t
(1)在spring 配置文件中加入bean管理, z0 c0 h0 K$ d: m& i
<bean id="userAction" class="com.tarena.web.action.UserAction" >2 S; \7 S9 D8 [7 z9 {) W
</bean> Y! e" f0 F! Z1 S
(2)修改struts-user.xml配置
% w7 c7 a; P" V0 q <action class="userAction" >
. Z! k: c% Q0 h </action>. X1 J$ d. M( P; t9 `/ K
5 测试struts+spring集成$ Y. O) }# {5 o) ~
6 spring+hibernate集成- Q. V0 Y8 K6 _3 w
(1)添加hibernate类库6 B. l2 |3 @$ x+ l
slf4j-nop-1.5.8.jar$ d- A2 e% p8 e
slf4j-api-1.5.8.jar1 k% `: t1 Q: T, {1 D
jta-1.1.jar$ v* c0 @4 y! s: d7 F
javassist-3.9.0.GA.jar
8 X/ p% T# ^+ j& D+ W# W5 Q* r hibernate3.jar1 M; q; o( }! }' ?
commons-collections-3.1.jar
) Y3 t- B% N' b$ U- m9 t: x antlr-2.7.6.jar
2 d/ b- f, ]# m7 n7 Y+ p (2)添加MySQL驱动类库 . m) r& t/ S4 G' s1 {2 N
mysql-connector-java-5.1.16-bin.jar% W! U& v$ |; ~" F% J9 I/ \ h9 H
(3)创建实体类 B7 _3 M, C! |! J
(4)编写User.hbm.xml映射文件! i$ I _6 \4 i4 ] ?: W
(5)反向生成表结构1 X$ x$ M3 j! N$ {$ f" q, w
(6)spring管理hibernate % R$ T5 o0 _6 H- C6 ]! ?) ~
在spring applicationContext.xml配置文件中添加spring对hibernate管理, q( v% P9 h5 c: T* z% d
(A) 添加DBCP连接池7 S1 L3 N% b- F9 ? i
a、添加类库
4 G5 _: r8 d. }9 v$ Z8 c, A commons-dbcp.jar0 O# N N, v, X; A8 @9 C
commons-pool.jar
% l. u( ]5 x" d+ S8 k( U b、applicationContext.xml在配置连接池
1 U4 }; p4 q, ^& w5 y% A$ E <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
1 _- U: Y L$ T9 V- {0 o) c <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
" \3 P- E+ x. C0 ] <property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb"/>
2 ]# K+ ~1 Y/ E- |* l3 o2 \- U0 i <property name="username" value="root"/>8 B! x3 c" S3 |
<property name="password" value="1234"/>
9 b; h: K3 J, d- P5 X- n <property name="initialSize" value="2"/>4 d) A* x* z) z6 i8 L# o
<property name="maxActive" value="8"/> Q8 {+ o& B% V. l$ G) W) J
<property name="maxIdle" value="5"/>
+ i' y7 F$ V" w+ [ <property name="minIdle" value="3"/>0 }$ r7 ~# L2 v, Z! j# H
<property name="maxWait" value="3000"/>
& r! Z! Q3 ^+ c <property name="removeAbandonedTimeout" value="60000"/>
- M1 {4 A& g- n: A( O* X: w8 y' I <property name="removeAbandoned" value="true"/>+ _1 L4 C* ~& S* s6 x) U& O- P
</bean>7 L# K) B# L/ q
连接池参数如下:, c. o. h1 r( W5 t
initialSize Y: o' v3 t" Q, i$ ~
连接池启动时创建的初始化连接数量
3 E; t4 u3 ^0 @9 W1 a' u7 J0 v6 [ (默认值initialSize :连接池启动时
, }- o# o, J- A 创建的初始化连接数量(默认值为0)
3 y1 Q5 U6 D( x5 S1 z g1 } maxActive ) S c+ `) r& C& Q. c
连接池中可同时连接的最大的连接数
0 g+ Y( B8 O- { (默认值为8 ,调整为20,高峰单机器在20并发左右,
4 Y7 h& h) f2 I9 @ P2 P( e' B; z 自己根据应用场景定) * w$ K0 J# h/ h* s+ b+ ~* T
maxIdle m8 }; R' R: J$ i* Z6 C
连接池中最大的空闲的连接数,
& s! K8 \+ b$ V% C9 @# v% i: R1 k6 N 超过的空闲连接将被释放," d: D) H% Z& N4 K8 f
如果设置为负数表示 不限制(默认为8个)5 U9 A/ F1 S: u# ?. G; S/ ~
minIdle/ ]( d- @- a: n: o: ~
连接池 中最小的空闲的连接数,低于这个数量会被
( X: V1 y2 k& ]" Y, Q+ G& Q7 U 创建新的连接(默认为0,调整为5, 该参数越接近+ L! `. e* i- V. E/ n @2 w
maxIdle,性能越好,因为连接的创建和销毁,3 i' G+ E9 q+ @. u$ P( ^* v
都是需要消耗资源的,但是不能太大,
& R; s$ v; k- j; f9 N0 d- p5 h 因为在机器很空闲的时候,也会创建低于% Y4 ?, i2 ^% r; q# b; d3 T( z) }
minidle个数的连接)
4 y7 H5 s( P3 M8 |7 o maxWait
; S( ?% C- u! W T/ L6 L/ { 最大等待时间,当没有可用 连接时,
/ J1 D. e+ ~6 R 连接池等待连接释放的最大时间,) @: M# w# F* d; @$ J: N
超过该时间限制会抛出异常,
' o. c! {- O! |) p 如果设 置-1表示无限等待(
& X! T& H$ A& x% W+ Y 默认为无限,调整为60000ms,0 a1 V& i- H4 r, s
避免因线程池不够用,而导致 请求被无限制挂起)
D5 M0 y' I* f8 \4 T+ K2 ? removeAbandonedTimeout :
( F' E9 D/ e. h' [5 Z8 g2 m 超过时间限制,回收没有用(废弃)的连接 / B4 K( v; t. H. \
(默认为 300秒,调整为180)
) H, Y+ r: k7 k U& d( H removeAbandoned :" O/ a; Y' q6 p0 K( z: `
超过 removeAbandonedTimeout时间后,0 X$ m! O6 f3 s( l& \
是否进行没用连接(废弃)的回收
8 i7 x$ z1 t g& ` (默认为 false,调整为true)
4 r$ V8 U2 P% e2 F- d- B" h- s (B)spring管理hibernate实体映射文件:
5 A4 n- [: W2 x9 d <bean id="sessionFactory"
* m8 @& P' V+ P- r) o class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">2 [& u" u! \ y3 R1 M1 _# g
<property name="dataSource" ref="dataSource" /> i3 ^: A' A' |1 n
<property name="hibernateProperties">0 Z7 E; V; K" Z8 D7 I' r6 v
<props>
, y* ]9 A2 z; L, Q# c( `" Q* D <prop key="hibernate.dialect">
" l% h- y- O9 p1 [ org.hibernate.dialect.MySQLDialect
# p! ?5 |; \7 E1 | </prop>
2 \) S/ |& X3 \6 N& M <prop key="hibernate.show_sql">true</prop>; N) C# C! \$ Y' b4 _8 m) L2 [
<prop key="hibernate.format_sql">true</prop>! [* G4 F. z/ ~1 u. W7 O( O# J; ^
</props>
6 l/ i& L0 m6 V; ^ ~) X# y </property>& q0 F# K& C9 Y8 Q
<property name="mappingLocations">2 e3 F% ?; b1 s
<list>
~, B0 Q& R2 F) { {4 |9 u7 P <value>
+ _3 A+ Q" B8 \( V! Z4 E5 O classpath:config/hibernate/hbm/User.hbm.xml
# v+ b4 s, f8 D+ W6 x8 M# d+ \ </value>3 [# l( l5 G3 W% D T3 \2 e( `) l! N
</list>
; g7 p! U2 ]6 r) x( A </property>( }: c( O. P; m+ ~
</bean>& j! F l9 i" S# C& l
(C)spring读写属性(properties)文件
3 V7 C5 f1 G i' R" K! J5 v/ G6 f a、创建属性文件 db.properties
: w# J: l, ?1 h b、在applicationContext.xml配置
8 M' \. i/ u. { <bean id="propertyPlaceholderConfigurer"
- m0 A8 X2 x! @1 q$ f5 e class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">; `4 ]) P4 }6 T, g% g) L {: o4 f1 a
<property name="locations">/ o" t. a# V+ A! z4 h& U/ Y+ a& g9 C
<list>
( f, S4 Z, Q: {' S5 g$ t <value>classpath:config/props/db.properties</value>
3 q: `' v0 U1 K </list>
, @- o% f% p' d8 g </property>+ L( K$ n6 S3 q F- K' N
</bean>
2 e* x' O5 {8 I+ h c:引用: ${username} Q1 G, |& u) r
5 W, _" I+ K* W) ~: Q5 Y (8)spring分文件管理
' |& t# a g3 r <!-- 引入其他spring 配置文件 -->
) y$ N- m( C8 c1 F9 B v7 `! k- C- ] applicationContext.xml引入下列文件5 K5 l. N2 C4 y' R8 b$ d' |
<import resource="applicationContext-web.xml"/>
0 A: v, J/ c7 p$ U6 s& L) r9 y <import resource="applicationContext-biz.xml"/>
# c' E' E! K8 t5 s <import resource="applicationContext-dao.xml"/>
( S2 [% K1 h2 R7、开发数据访问层
4 i9 r- S" O! e7 Y 使用spring提供hibernate 模板类 HibernateDaoSupport, M, W, e* w0 a& ^ v' [
UserDaoImpl extends HibernateDaoSupport5 o5 [4 V- b+ g& d6 y
在UserDaoImpl注入到spring 配置文件 applicationContext-dao.xml
+ s# @/ w* B5 J! t <bean id="userDaoImpl" class="com.tarena.dao.impl.UserDaoImpl">- p2 u. R5 O" K A
<!--HibernateDaoSupport中的sessionFactory-->( [" B. H* O4 R E& o% l, h
<property name="sessionFactory" ref="sessionFactory" />
: T1 w1 h7 D: q </bean>/ b% D( |2 M5 `! N( ]# K0 e/ C
8、添加spring声明事务管理(AOP)3 y: U: ]6 M) @. ?- {5 o
声明式事务管理:3 Z+ w, {% W2 T* {
添加spring 类库4 U) |2 f# X( |- Q* @
aspectjrt.jar9 p7 P# u( e+ `4 ?( Y
aspectjweaver.jar2 k) q& f I, ~% h! o0 E2 ^
了解事务的几种传播特性
+ w* r3 L2 D; {" `
- Z5 C. o8 q: O6 i1 ` (1)PROPAGATION_REQUIRED: 2 w" ?% a* i) G, l$ x, a8 q7 ?
如果存在一个事务,则支持当前事务,如果没有事务则开启。# t6 Q& W3 s0 ]1 p
(2)PROPAGATION_SUPPORTS:
8 w6 N3 n9 w) x# h' b 如果存在一个事务,支持当前事务。
! z- o& R" G+ x# h5 _: _ 如果没有事务,则非事务的执行。
4 D" n6 e P4 ~( _ (3)PROPAGATION_MANDATORY: 0 v" \3 f+ e2 H( f
如果已经存在一个事务,支持当前事务。8 y6 E% R3 @* o" \$ ]6 u9 ^7 d
如果没有一个活动的事务,则抛出异常。
7 ]; h" z7 M" i' G' x& o. q (4)PROPAGATION_REQUIRES_NEW: ( R+ k0 ?* H% [0 }$ }$ r, i
总是开启一个新的事务。如果一个事务已经存在,1 M. Q3 D1 d8 E p' F1 \
则将这个存在的事务挂起。: J. W3 Z+ l, @# O/ j* P* k
(7)PROPAGATION_NESTED:(spring特有)( m5 p |: w' x+ S+ u
如果一个活动的事务存在,则运行在一个嵌套的事务中. . X3 Y, d5 V* j f1 ~% c" b% Z
如果没有活动事务, 则按TransactionDefinition.: q* A. H: p3 s# ^! R9 E+ ^) o. o
PROPAGATION_REQUIRED 属性执行! q# r+ `, F. H: s. I
o1 B4 c1 x9 C' ?+ @( O7 ] P) w (5)PROPAGATION_NOT_SUPPORTED: a5 d) p8 f" S! {8 ?5 S/ Z( L
总是非事务地执行,并挂起任何存在的事务。) I" g* N( K2 r- v, u% h7 y
(6)PROPAGATION_NEVER: 9 }* C w# d# p8 @7 \
总是非事务地执行,如果存在一个活动事务,则抛出异常。 _6 Z0 ]2 J0 [% e N6 h& \
! X+ e2 A+ [$ g% ~ 6 @$ j+ V1 |9 C$ Y. d! u- f+ D
<!-- 配置声明事务管理 spring2.x-->
; B* E+ | R# n" ^- Y1 a% A. | <!-- 定义事务管理 -->9 {# @, n+ g& v- t9 D
<bean id="transactionManager"/ x3 b6 C& H2 [6 N
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
) Q7 T! }( @3 v0 b: J- ^# b r <property name="sessionFactory" ref="sessionFactory" />( }* L! x1 y; E1 f
</bean>, ^% l8 n2 j# w; f- F. x
<!-- 事务规则 -->
% L7 ?( t! z0 A! x* F9 m% W <tx:advice id="tmAdvice" transaction-manager="transactionManager">2 w" A0 r) n. ?
<tx:attributes>$ S7 g& @$ I9 D, |
<!--*通配符 save* 方法名必须是以save开始-->
& S2 q6 t8 b& M <tx:method name="save*" propagation="REQUIRED" />
! o6 f2 k! A- d3 O <tx:method name="update*" propagation="REQUIRED" />
( i) }" K- M* t( L3 V& i <tx:method name="delete*" propagation="REQUIRED" />
& R$ i! e8 j, _ <tx:method name="find*" read-only="true" />+ T L* U2 [, e7 O, }0 z
<!-- read-only 只读:-->- s! @' n* D( Y* Q, q, j$ f, \; ~
</tx:attributes>
! \' r/ C+ f9 Z3 q </tx:advice>
6 D/ \# F; N5 k4 p <aop:config>
; R9 C4 N) h1 p- n <!-- point cut -->
, T( j/ \$ n$ F <aop:pointcut id="pointCut"
5 i. Q. h# b) s; D expression="execution(* com.tarena.biz.*.*(..))" />9 }$ V% g% q6 Y7 J* u" u, L
<aop:advisor advice-ref="tmAdvice" pointcut-ref="pointCut"/> $ u* t7 Z5 {& e5 ?2 x
</aop:config>
" g: ?% i; \% H/ t* O( q9 ~
( b! s% z- T' L( S9、测试+ r7 v r- l& y5 E2 v; v1 V* J
添加测试类库 spring2.5.6
- f3 D5 T i3 X2 s junit-4.4.jar" s. K& N+ @& `! {& Q' ?* k
spring-test.jar N' E2 ]; d" Y6 H$ C ]& h5 r
//使用spring测试( B' x) }1 e5 Z6 G
@RunWith(SpringJUnit4ClassRunner.class)3 ?' m6 B/ q" ^
//加载spring配置文件, ~7 Q6 v; @7 S9 |% j; ]
@ContextConfiguration(locations = {
4 m, p% i& ~+ t9 u# A; b0 h4 R "classpath:config/spring/applicationContext.xml",% D& t; s5 J+ m
"classpath:config/spring/applicationContext-dao.xml",
$ k! T" v8 J* `7 y5 g4 P "classpath:config/spring/applicationContext-biz.xml",5 n9 p' G! n% p2 J' l
"classpath:config/spring/applicationContext-web.xml" })
1 l& x" T2 _) ? //自动注入. b6 Q3 w) ~$ i) U1 O8 o S
@Autowired7 m3 m$ R9 M$ s# L3 V
private IUserDao iuserDao;5 `9 ?2 j) M1 A- ]: R) j2 q
( K6 {+ k0 j+ O1 p8 {% ]) J6 s* S! K& N
@Test8 H+ ~* X- w/ W$ q" z+ R$ e, V
public void saveUserTest(){' C5 F2 A1 _& h6 F6 s) U' j
//测试方法
- G! A0 y* r3 T) G }4 |$ w' ]* U6 e* @) x' j
10、完成业务层代码编写) i. |; B) N' Q0 f9 O7 V9 x
11、完成表示层代码编写
8 |+ H, P5 e/ G12、测试工程
& M% q6 `( v: P; P3 T: a- H0 m& ?" l/ |* u7 `( e
13、spring处理hibernate延时加载8 U: i; i1 W" u4 l1 e9 F) P
1、配置延时过滤器
. u4 R8 U) B+ M) I8 d OpenSessionInViewFilter.class( d" [4 ^/ z* A' k7 [, E$ i
2、在web.xml配置OpenSessionInViewFilter
5 l7 A7 a; j5 W, C 5 V6 [; u! F7 e' y- I
<filter>$ Q0 w4 _1 W9 O* L$ y" M
<filter-name>openSessionInViewFilter</filter-name>
6 u/ Z1 D; y1 R+ Y: \ <filter-class>
- [* K! \, w# A# c% w8 P# A org.springframework.orm.hibernate3.support.OpenSessionInViewFilter' l: O' v `" F) e8 C
</filter-class>
7 U+ \; K0 s; x, ^, B <init-param>
2 P2 d, @( i3 B( n( X <param-name>sessionFactoryBeanName</param-name>
. N+ ]* B* p8 \6 q <param-value>sessionFactory</param-value>
' N/ i( i8 z# j# b* \ </init-param>
$ d1 p- W8 f, b8 x7 C: l# G </filter>6 X% W/ n: q j% u# n F
<filter-mapping>" b- `9 r& `. n W8 @5 u
<filter-name>openSessionInViewFilter</filter-name>' o% F! s5 }" V. `$ Y$ u/ U K2 t, L
<url-pattern>/*</url-pattern>+ n: b% n) D- l( b
</filter-mapping>
9 Z) d# \5 U! H2 s6 y5 n( e
+ I' S* Z) S( n* {& v |
|