关于struts2中prepare接口实现数据准备

关于struts2中prepare接口实现数据准备

之前做过不少的项目,所有的action只实现了一个execute()方法,也用到过Preparable接口,并没注意到它的具体用法。随着项目的需 求的增加,按照以前的方法,每一个功能都需要一个action,这样势必会造成action类的大规模膨胀。所以决定采取action!method的形 式,这样在一个action中可以包含很多方法,减少了action类的数量,也便于维护。

把crud方法放在一个action类中,就必定会涉及到一些数据准备的事情,所以用Preparable接口就再合适不过了,实现这个接口的prepare()方法,这个方法会在action类的所有方法执行前执行,另外我们也可以按照它的规则来写一些其它形式的prepare方法,例如aciton中有一个方法叫input(),那么我们可以实现一个prepareInput方法,这样在input()执行前,会执行prepareInput()方法。

好了,言归正传,我们有这样的一个action:

Java代码 

1. package ht.gisoa.action; 

2. 

3. import ht.gisoa.model.Sysconfig; 

4. import ht.gisoa.service.SysconfigManager; 

5. 

6. import java.util.List; 

7. import java.util.Map; 

8. 

9. import javax.servlet.http.HttpServletRequest; 

10. 

11. import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 

12. 

13. import com.opensymphony.webwork.ServletActionContext; 

14. import com.opensymphony.webwork.interceptor.ServletRequestAware; 

15. import com.opensymphony.webwork.interceptor.SessionAware; 

16. import com.opensymphony.xwork.ActionSupport; 

17. import com.opensymphony.xwork.ModelDriven; 

18. import com.opensymphony.xwork.Preparable; 

19. import com.thoughtworks.xstream.XStream; 

20. 

21. public class SystemConfigAction extends ActionSupport implements Preparable,SessionAware,ServletRequestAware,ModelDriven{ 

22. /** 

23. * 

24. */ 

25. 

26. private Map session ; 

27. private HttpServletRequest request; 

28. 

29. private NamedParameterJdbcTemplate namedParameterJdbcTemplate = null; 

30. 

31. private Double hignSpeed = 0.0; 

32. private Double midSpeed = 0.0; 

33. private Double lowSpeed = 0.0; 

34. 

35. private static final long serialVersionUID = 1L; 

36. private SysconfigManager sysconfigManager = null; 

37. 

38. 

39. private Long id ; 

40. private Sysconfig entity; 

41. 

42. public void setId(Long id) { 

43. this.id = id; 

44. } 

45. 

46. public String editSpeed() throws Exception{ 

47. Map<String,Sysconfig> configs = sysconfigManager.getSpeedConfig() ; 

48. ServletActionContext.getRequest().setAttribute("configs", configs); 

49. return this.SUCCESS; 

50. } 

51. 

52. public String input() throws Exception{ 

53. return "input"; 

54. } 

55. 

56. public String list(){ 

57. List<Sysconfig> speedCollection = sysconfigManager.getSpeedList(); 

58. ServletActionContext.getRequest().setAttribute("speedCollection", speedCollection); 

59. return "list"; 

60. } 

61. 

62. public String save() throws Exception{ 

63. sysconfigManager.mergy(entity); 

64. return "reload"; 

65. } 

66. 

67. public String delete() throws Exception{ 

68. sysconfigManager.delete(id); 

69. return "reload"; 

70. } 

71. 

72. public SysconfigManager getSysconfigManager() { 

73. return sysconfigManager; 

74. } 

75. public void setSysconfigManager(SysconfigManager sysconfigManager) { 

76. this.sysconfigManager = sysconfigManager; 

77. } 

78. 

79. public Double getHignSpeed() { 

80. return hignSpeed; 

81. } 

82. 

83. public void setHignSpeed(Double hignSpeed) { 

84. this.hignSpeed = hignSpeed; 

85. } 

86. 

87. public Double getMidSpeed() { 

88. return midSpeed; 

89. } 

90. 

91. public void setMidSpeed(Double midSpeed) { 

92. this.midSpeed = midSpeed; 

93. } 

94. 

95. public Double getLowSpeed() { 

96. return lowSpeed; 

97. } 

98. 

99. public void setLowSpeed(Double lowSpeed) { 

100. this.lowSpeed = lowSpeed; 

101. } 

102. 

103. public void setSession(Map session) { 

104. this.session = session; 

105. } 

106. 

107. public void setServletRequest(HttpServletRequest request) { 

108. this.request = request; 

109. } 

110. 

111. public void prepare() throws Exception { 

112. 

113. } 

114. 

115. public void prepareModel() throws Exception { 

116. if (id==null){ 

117. System.out.println("id=null"); 

118. entity = new Sysconfig(); 

119. entity.setKeyType(1L); 

120. }else{ 

121. System.out.println("id=="+id); 

122. entity = sysconfigManager.get(id); 

123. } 

124. } 

125. 

126. public void prepareInput() throws Exception{ 

127. prepareModel(); 

128. } 

129. public void prepareSave() throws Exception { 

130. prepareModel(); 

131. } 

132. 

133. public Object getModel() { 

134. return entity; 

135. } 

136. } 

这里要注意,要在spring中配置该action的作用域为prototype,否则,不同的方法之间会出现数据混乱的情况:

Xml代码 

1. <bean id="systemconfig" 

2. class="ht.gisoa.action.SystemConfigAction" scope="prototype"> 

3. <property name="sysconfigManager"> 

4. <ref bean="SysconfigManager" /> 

5. </property> 

6. </bean> 

sysconfig_input.jsp代码如下:

Jsp代码 

1. <%@ page language="java" pageEncoding="UTF-8" isELIgnored="false"%> 

2. <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> 

3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 

4. <html> 

5. <head> 

6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 

7. 

8. </head> 

9. <body> 

10. <div id="msg"> 

11. ${msg} 

12. </div> 

13. <c:choose><c:when test="${ param.id == null}">创建</c:when><c:otherwise>修改</c:otherwise></c:choose>设置 

14. <div id="main"> 

15. <form action="systemconfig!save.action"> 

16. <input type="text" name="model.keyName" value="${model.keyName}"/><br> 

17. <input type="text" name="model.keyValue" value="${model.keyValue}"/><br> 

18. <input type="hidden" name="model.id" value="${model.id}"/><br> 

19. <input type="hidden" name="model.keyType" value="1"/><br> 

20. <input type="submit" value="修改"/> 

21. </form> 

22. </div> 

23. <c:remove var="msg" scope="session"/> 

24. </body> 

25. </html> 

我们编辑完信息,提交后,会执行action中的save方法,按道理,表单提交后,会将action中的model填充好数据,但是save方法 之前又会执行prepareSave方法,从数据库里获取一次数据,这样不就把之前填充好的数据冲掉了吗?仔细想想也确实是这样的.

那么该如何解决这种矛盾呢,立即使出google大法,查了一下关于interceptor的资料,有这样的一个interceptor:paramsPrepareParamsStack,paramsPrepareParamsStack主要解决了ModelDriven和Preparable的配合问题,从字面上理解来说,这个stack的拦截器调用的顺序为:首先params,然后prepare,接下来modelDriven,最后再params。Struts 2.0的设计上要求modelDriven在params之前调用,而业务中prepare要负责准备model,准备model又需要参数,这就需要在prepare之前运行params拦截器设置相关参数,这个也就是创建paramsPrepareParamsStack的原因。流程如下: 
1. params拦截器首先给action中的相关参数赋值,如id 
2. prepare拦截器执行prepare方法,prepare方法中会根据参数,如id,去调用业务逻辑,设置model对象 
3. modelDriven拦截器将model对象压入value stack,这里的model对象就是在prepare中创建的 
4. params拦截器再将参数赋值给model对象 
5. action的业务逻辑执行

我的xwork.xml中相关配置如下:

Xml代码 

1. <action name="systemconfig" class="systemconfig"> 

2. <result name="list" type="dispatcher"> 

3. <param name="location">syscfg_speed_list.jsp</param> 

4. </result> 

5. <result name="reload" type="redirect"> 

6. <param name="location">systemconfig!list.action</param> 

7. </result> 

8. <result name="input" type="dispatcher"> 

9. <param name="location">syscfg_speed_input.jsp</param> 

10. </result> 

11. <interceptor-ref name="paramsPrepareParamsStack" /> 

12. <interceptor-ref name="modelParamsStack"></interceptor-ref> 

13. </action> 

通过paramsPrepareParamsStack可以让流程更明确,代码更简洁,也更利于大家的交流。


你可能感兴趣的:(关于struts2中prepare接口实现数据准备)