文档库 最新最全的文档下载
当前位置:文档库 › struts2自定义标签

struts2自定义标签

struts2自定义标签
struts2自定义标签

Struts2中实现自定义分页标签

Struts2中实现自定义标签很简单,主要分为3步:

1.创建taglib文件(.tld),编写标签声明。

2.编写自定义标签类。

3.在页面中使用标签。

下面以一个自定义的分页标签为例,进行说明。

其实,开发自定义标签并不需要Struts2的支持,一般情况下,只需要继承

javax.servlet.jsp.tagext.BodyTagSupport类,重写doStartTag,doEndTag等方法即可。这里在实现自定义标签时,继承的2个类分别是https://www.wendangku.net/doc/6515333320.html,ponentTagSupport和

https://www.wendangku.net/doc/6515333320.html,ponent,ComponentTagSupport实际上是对BodyTagSupport 的一次封装,看一下ComponentTagSupport类的继承关系就明了了:

Java代码

1. https://www.wendangku.net/doc/6515333320.html,ng.Object

2. extended by javax.servlet.jsp.tagext.TagSupport

3. extended by javax.servlet.jsp.tagext.BodyTagSupport

4. extended by org.apache.struts2.views.jsp.StrutsBodyTagSupport

5. extended by https://www.wendangku.net/doc/6515333320.html,ponentTagSupport

继承ComponentTagSupport类是为了获得标签中的属性值,并包装成Component对象。继承Component类是为了从Struts2中的ValueStack中获得相对应的值。

1.声明自定义标签。

首先,需要创建一个tld文件,这是一个标准的XML文件,这个文件中就包含有对自定义标签的声明,声明指出了标签的名字,实现标签的类,标签的属性等信息。当在页面中使用该标签时,web服务器就会从这个文件中找出相对应的标签类,并实例化后执行。这个文件其实与struts.xml文件的作用相类似。

tangs.tld

Xml代码

1.

2.

p://https://www.wendangku.net/doc/6515333320.html,/dtd/web-jsptaglibrary_1_2.dtd">

1.

2.

3. 2.2.3

4. 1.2

5. tangs

6. /tangs

7. "Tangs Tags"

8.

9.

10. pages

11. com.tangs.tag.PageTag //标签类

12. empty

13. //标签中的属性

14. cpage //属性名

15. true //是否必须

16. true //表示该自定义标签的某属性的值可以直接指定或者通过动态

计算指定

17.

18.

19. total

20. true

21. true

22.

23.

24. url

25. true

26. true

27.

28.

29.

2.编写标签类

PageTag.java

Java代码

1. package com.tangs.tag;

2.

3. import com.opensymphony.xwork2.util.ValueStack;

4. import javax.servlet.http.HttpServletRequest;

5. import javax.servlet.http.HttpServletResponse;

6. import https://www.wendangku.net/doc/6515333320.html,ponent;

7. import https://www.wendangku.net/doc/6515333320.html,ponentTagSupport;

8.

9. /**

10. * 分页标签

11. * @author tangs

12. */

13. public class PageTag extends ComponentTagSupport {

14. private String cpage; //当前页

15. private String total; //总页数

16. private String url; //请求地址

17.

18. public void setCpage(String cpage) {

19. this.cpage = cpage;

20. }

21.

22. public void setTotal(String total) {

23. this.total = total;

24. }

25.

26. public void setUrl(String url) {

27. this.url = url;

28. }

29.

30. @Override

31. public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) {

32. return new Pages(arg0); //返回Pages Component,分页的逻辑处理都在这个Component中

33. }

34.

35. //获得参数

36. protected void populateParams() {

37. super.populateParams();

38.

39. Pages pages = (Pages)component;

40. pages.setCpage(cpage);

41. pages.setTotal(total);

42. pages.setUrl(url);

43. }

44. }

Pages.java

Java代码

1. package com.tangs.tag;

2.

3. import com.opensymphony.xwork2.util.ValueStack;

4. import java.io.IOException;

5. import java.io.Writer;

6. import java.util.logging.Level;

7. import java.util.logging.Logger;

8. import https://www.wendangku.net/doc/6515333320.html,ponent;

9.

10. /**

11. * 分页逻辑Bean

12. * @author tangs

13. */

14. public class Pages extends Component {

15. private String cpage;

16. private String total;

17. private String url;

18.

19. public String getCpage() {

20. return cpage;

21. }

22.

23. public void setCpage(String cpage) {

24. this.cpage = cpage;

25. }

26.

27. public String getTotal() {

28. return total;

29. }

30.

31. public void setTotal(String total) {

32. this.total = total;

33. }

34.

35. public String getUrl() {

36. return url;

37. }

38.

39. public void setUrl(String url) {

40. this.url = url;

41. }

42.

43.

44. public Pages(ValueStack arg0) {

45. super(arg0);

46. }

47.

48. @Override

49. public boolean start(Writer writer) {

50. boolean result = super.start(writer);

51. try {

52. StringBuilder str = new StringBuilder();

53. boolean isValid = true;

54.

55. //从ValueStack中取出数值

56. if (isValid) {

57. if (total.startsWith("%{") && total.endsWith("}")) {

58. total = total.substring(2, total.length() -1);

59. total = (String)this.getStack().findValue(total);

60. isValid = total == null ? false : true;

61. } else {

62. isValid = false;

63. }

64. }

65. if (isValid) {

66. if (cpage.startsWith("%{") && cpage.endsWith("}")) {

67. cpage = cpage.substring(2, cpage.length() - 1);

68. cpage = (String)this.getStack().findValue(cpage);

69. isValid = cpage == null ? false : true;

70. } else {

71. isValid = false;

72. }

73. }

74. if (isValid) {

75. if (url.startsWith("%{") && url.endsWith("}")) {

76. url = url.substring(2, url.length() - 1);

77. url = (String)this.getStack().findValue(url);

78. isValid = url == null ? false : true;

79. } else {

80. isValid = false;

81. }

82. }

83.

84. if (isValid) {

85. Integer cpageInt = Integer.valueOf(cpage);

86. //当前页与总页数相等

87. if (cpage.equals(total)) {

88. //如果total = 1,则无需分页,显示“[第1页] [共1页]”

89. if ("1".equals(total)) {

90. str.append("[第 " + cpage + " 页]");

91. str.append(" [共 " + total + " 页]");

92. } else {

93. //到达最后一页,显示“[首页] [上一页] [末页]”

94. str.append("[首页] [上一页] [末页]");

104. }

105. } else {

106. //当前页与总页数不相同

107. if ("1".equals(cpage)) {

108. //第一页,显示“[首页] [下一页] [末页]”

109. str.append("[首页] [下一页] [末页]");

119. } else {

120. //不是第一页,显示“[首页] [上一页] [下一页] [末页]”

121. str.append("[首页] [上一页] [下一页] [末页]");

134. }

135. }

136. }

137.

138. writer.write(str.toString());

139.

140. } catch (IOException ex) {

141. Logger.getLogger(Pages.class.getName()).log(Level.SEVERE, null, ex);

142. }

143. return result;

144. }

145. }

3.服务端

服务端主要是获得请求然后转向显示的页面

DisplayAction.java

Java代码

1. /*

2. * To change this template, choose Tools | Templates

3. * and open the template in the editor.

4. */

5.

6. package com.tangs.action;

7.

8. import com.opensymphony.xwork2.ActionSupport;

9.

10. /**

11. *

12. * @author tangs

13. */

14. public class DisplayAction extends ActionSupport {

15. private String cpage;

16. private String total;

17. private String url;

18.

19. public String list() {

20.

21. //Get data from server

22. //...

23. //这里没有做任何逻辑,直接跳转到了页面

24. return SUCCESS;

25. }

26. public String getCpage() {

27. return cpage;

28. }

29.

30. public void setCpage(String cpage) {

31. this.cpage = cpage;

32. }

33.

34. public String getTotal() {

35. return total;

36. }

37.

38. public void setTotal(String total) {

39. this.total = total;

40. }

41.

42. public String getUrl() {

43. return url;

44. }

45.

46. public void setUrl(String url) {

47. this.url = url;

48. }

49.

50.

51. }

struts.xml

Xml代码

1.

2.

https://www.wendangku.net/doc/6515333320.html,/dtds/struts-2.0.dtd" >

3.

4.

5.

6. /list.jsp

7.

8.

9.

4.在页面中使用标签

list.jsp

Html代码

1. <%@page contentType="text/html"pageEncoding="UTF-8"%>

2. <%@ taglib prefix="tangs"uri="/WEB-INF/tangs.tld"%>

3. <%@ taglib prefix="s"uri="/WEB-INF/struts-tags.tld"%>

4.

5.

6.

7.

8. List

9.

10.

11. 共页第

12.

13.

14.

好了,启动服务器,从浏览器中输入http://localhost:7001/TagTest/list.page?cpage=1&total=5&url=list.page

就会得到下面的结果:

Struts2中实现自定义分页标签--功能扩充

Struts2中实现自定义分页标签--功能扩充

上一篇结合Struts2实现了分页的自定义标签。标签比较简单,3个参数,单一的显示样式。下面对该标签的功能进行进一步的扩充,主要包括:

1.可以为标签指定样式。通过styleClass属性,可以为标签指定一个样式表。

2.增加了分页样式的选择。通过theme属性指定分页样式。

theme="text"的样式:

theme="number"的样式:

修改方案:

1.在tld文件中增加这两个属性的声明:

Xml代码

1.

2. styleClass

1.

2. false

3. true

4.

5.

6. theme

7. false

8. true

9.

2.在自定义标签类中分别增加styleClass和theme属性,并提供setter方法:PageTag.java

Java代码

1. /*

2. * To change this template, choose Tools | Templates

3. * and open the template in the editor.

4. */

5.

6. package com.tangs.tag;

7.

8. import com.opensymphony.xwork2.util.ValueStack;

9. import javax.servlet.http.HttpServletRequest;

10. import javax.servlet.http.HttpServletResponse;

11. import https://www.wendangku.net/doc/6515333320.html,ponent;

12. import https://www.wendangku.net/doc/6515333320.html,ponentTagSupport;

13.

14. /**

15. * 分页标签

16. * @author tangs

17. */

18. public class PageTag extends ComponentTagSupport {

19. private String cpage;

20. private String total;

21. private String url;

22. private String styleClass; //新增的样式属性

23. private String theme; //新增的分页样式属性

24.

25. public void setTheme(String theme) {

26. this.theme = theme;

27. }

28.

29. public void setStyleClass(String styleClass) {

30. this.styleClass = styleClass;

31. }

32.

33. public void setCpage(String cpage) {

34. this.cpage = cpage;

35. }

36.

37. public void setTotal(String total) {

38. this.total = total;

39. }

40.

41. public void setUrl(String url) {

42. this.url = url;

43. }

44.

45. @Override

46. public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) {

47. return new Pages(arg0, arg1);

48. }

49.

50. protected void populateParams() {

51. super.populateParams();

52.

53. Pages pages = (Pages)component;

54. pages.setCpage(cpage);

55. pages.setTotal(total);

56. pages.setUrl(url);

57. pages.setStyleClass(styleClass);

58. pages.setTheme(theme);

59.

60. }

61. }

Pages.java

Java代码

1. /*

2. * To change this template, choose Tools | Templates

3. * and open the template in the editor.

4. */

5.

6. package com.tangs.tag;

7.

8. import com.opensymphony.xwork2.util.ValueStack;

9. import java.io.IOException;

10. import java.io.Writer;

11. import java.util.logging.Level;

12. import java.util.logging.Logger;

13. import javax.servlet.http.HttpServletRequest;

14. import https://www.wendangku.net/doc/6515333320.html,ponent;

15.

16. /**

17. * 分页逻辑Bean

18. * @author tangs

19. */

20. public class Pages extends Component {

21. private HttpServletRequest request;

22. private String cpage;

23. private String total;

24. private String url;

25. private String styleClass;

26. private String theme;

27.

28. public String getTheme() {

29. return theme;

30. }

31.

32. public void setTheme(String theme) {

33. this.theme = theme;

34. }

35.

36.

37. public String getStyleClass() {

38. return styleClass;

39. }

40.

41. public void setStyleClass(String styleClass) {

42. this.styleClass = styleClass;

43. }

44.

45.

46. public String getCpage() {

47. return cpage;

48. }

49.

50. public void setCpage(String cpage) {

51. this.cpage = cpage;

52. }

53.

54. public String getTotal() {

55. return total;

56. }

57.

58. public void setTotal(String total) {

59. this.total = total;

60. }

61.

62. public String getUrl() {

63. return url;

64. }

65.

66. public void setUrl(String url) {

67. this.url = url;

68. }

69.

70.

71. public Pages(ValueStack arg0, HttpServletRequest request) {

72. super(arg0);

73. this.request = request;

74. }

75.

76. @Override

77. public boolean start(Writer writer) {

78. boolean result = super.start(writer);

79. try {

80. StringBuilder str = new StringBuilder();

81. boolean isValid = true;

82.

83. //从ValueStack中取出数值

84. if (isValid) {

85. if (total.startsWith("%{") && total.endsWith("}")) {

86. total = total.substring(2, total.length() -1);

87. total = (String)this.getStack().findValue(total);

88. isValid = total == null ? false : true;

89. } else {

90. isValid = false;

91. }

92. }

93. if (isValid) {

94. if (cpage.startsWith("%{") && cpage.endsWith("}")) {

95. cpage = cpage.substring(2, cpage.length() - 1);

96. cpage = (String)this.getStack().findValue(cpage);

97. isValid = cpage == null ? false : true;

98. } else {

99. isValid = false;

100. }

101. }

102. if (isValid) {

103. if (url.startsWith("%{") && url.endsWith("}")) {

104. url = url.substring(2, url.length() - 1);

105. url = (String)this.getStack().findValue(url);

106. isValid = url == null ? false : true;

107. } else {

108. isValid = false;

109. }

110. }

111.

112. if (isValid) {

113. Integer cpageInt = Integer.valueOf(cpage);

114. str.append("

115. if (styleClass != null) {

116. str.append(" class='"+styleClass+"'>");

117. } else {

118. str.append(">");

119. }

120.

121. //文本样式

122. if (theme == null || "text".equals(theme)) { //theme="text"样式

123. //当前页与总页数相等

124. if (cpage.equals(total)) {

125. //如果total = 1,则无需分页,显示“[第1页] [共1页]”

126. if ("1".equals(total)) {

127. str.append("[第 " + cpage + " 页]");

128. str.append(" [共 " + total + " 页]");

129. } else {

130. //到达最后一页,显示“[首页] [上一页] [末页]”

131. str.append("[首页] [上一页] [末页]");

141. }

142. } else {

143. //当前页与总页数不相同

144. if ("1".equals(cpage)) {

145. //第一页,显示“[首页] [下一页] [末页]”

146. str.append("[首页] [下一页] [末页]");

156. } else {

157. //不是第一页,显示“[首页] [上一页] [下一页] [末页]”

158. str.append("[首页] [上一页] [下一页] [末页]");

171. }

172. }

173. } else if ("number".equals(theme)) { //theme="number"的数字样式 [1 2 3 4 5 6 7 8 9 10 > >>] 174. Integer totalInt = Integer.valueOf(total);

175.

176. //如果只有一页,则无需分页

177. str.append("[ ");

178. if (totalInt == 1) {

179. str.append("1 ");

180. } else {

181. //计算一共分几组

182. int group = (totalInt - 1) / 10 + 1;

183. //当前第几组

184. int cgroup = (cpageInt - 1) / 10 + 1;

185.

186. if (cgroup > 1) {

187. //当前不是第一组,要显示“<<<”

188. //<<:返回前一组第一页

189. //<:返回前一页

190. str.append("? " );

194. str.append("? " );

198. }

199. //10个为一组显示

200. for (int i = (cgroup - 1) * 10 + 1; i <= totalInt && i <= cgroup * 10; i++) {

201. if (cpageInt == i) { //当前页要加粗显示

202. str.append("");

203. }

204. str.append("" + i + " ");

208. if (cpageInt == i) {

209. str.append("");

210. }

211. }

212. //如果多于1组并且不是最后一组,显示“>>>”

213. if (group > 1&& cgroup != group) {

214. //>>:返回下一组最后一页

215. //>:返回下一页

216. str.append("? " );

220. str.append("? " );

224. }

225. }

226. str.append("]");

227. }

228. str.append("");

229. }

230.

231. writer.write(str.toString());

232.

233. } catch (IOException ex) {

234. Logger.getLogger(Pages.class.getName()).log(Level.SEVERE, null, ex);

235. }

236. return result;

237. }

238. }

3.在页面中使用标签

Html代码

1. 指定了styleClass和theme属性,得到的分页样式:

SCME_STRUTS2试卷

--------------------------------------装--------------------------------------订------------------------------线---------------------------------------- **学院课程考试试卷 课程名称:《使用Struts2开发基于MVC设计模式的企业级应用》(A)卷 年级:班级: 姓名:_______________ 学号:_________________ 考试(考查) 闭卷 选择题(每题2分,共计100分) 1.在控制器类中一般需要添加相应属性的( A )和(C )。(选两项) A.setter方法 B.as方法 C.getter方法 D.is方法 2.业务控制器需要在( B )配置文件中进行配置 A.web.xml B.struts.xml C.struts2.xml D.webwork.xml 3.不属于Struts 2表单标签库的是( D )。 A. B. C. D.标签的property属性指定字段的名字,对应ActionForm bean中的一个属性,代码如下: 的对应的userForm bean属性 private String login_Name; public String getLogin_Name() { return login_Name; } public void setLogin_Name(String login_Name) { this.login_Name = login_Name; } 3,:生成HTML标签,使用方法与相同。 启用 停用 4,:生成HTML 5.在JSP页面中可以通过Struts 2提供的___D________标签来输出国际化信息。D A. B. C. D. 6.资源文件的后缀名为____D_______。D

Struts2试题

Struts2试题 1.struts2的执行流程? 客户端提交一个HttpServletRequest请求(action或JSP页面) 请求被提交到一系列Filter过滤器,如ActionCleanUp和FiterDispatcher等 FilterDispatcher是Struts2控制器的核心,它通常是过滤器链中的最后一个过滤器询问ActionMapper是否需要调用某个action来处理 如果ActonMapper据诶的那个需要调用某个A传统,FilterDispatcher则把请求教到ActionProxy,由其进行处理 ActionProxy通过Configuration Manager询问框架配置文件,找到需要调用的Action类ActionProxy创建一个ActionInvocation实例,而ActionInvocation通过代理模式调用action Action执行完毕后,返回一个result字符串,此时再按相反的顺序通过Interceptor拦截器最后ActionInvocation负责根据struts配置文件中配置的result元素,找到与返回值对应的result 2.struts2的web里需要配置什么? 1. 2. 3.struts2 4. 5.org.apache.struts2.dispatcher.FilterDispatcher 6. 7. 8. 9.

10.struts2 11./* 12. 3.struts.xml文件哪个常量可以实现不用重新启动服务就可以得到反馈? 4.struts中的package的作用是什么?namespace可以为空吗?如果namespace为空会意味着什么呢? 标识 可以、 Timmer 如果没写,说明该包为默认空间只要敲index没有精确对应的package都交给namespackage 如果还没有就崩溃 5.Action的实现通集成常用那种方法? 一种是直接实现自己的Action 另一种是实现Action的接口 继承ActionSupport 6.路径设置用什么路径,绝对还是相对? 都可以 7.通配符有几种?要遵循什么原则? {1} 方法名 8.Action的属性?

Struts2中防止表单的重复提交

Struts2中防止表单的重复提交 在学习编程的过程中,我觉得不止要获得课本的知识, 更多的是通过学习技术知识提高解决问题的能力,这样我们才能走在最前方,更多Java学习,请搜索疯狂Java; struts2的token令牌 1、javaweb控制表单重复提交 (1)在jsp页面上使用隐藏域 这样做,每次正常跳转到该页面隐藏域都会产生不同的value的值,此时属于正常操作 如果提交表单的时候,出现隐藏域的值相同,说明表单重复提交(2)在Action类中 先获取session中存放的token的值,String sessionToken = session.getAttibuter ("sessionToken"); 首先会获取页面表单隐藏域(token.html)的值,String token = request.getParameter("token.html"); 同时放置到session中,session.setAttibuter("sessionToken",token); 判断表单是否重复提交 if(sessionToken.equal(token)){//表单重复提交 } else{//表单没有重复提交 } 2、struts实现表单重复提交 (1)在某个页面验证表单重复提交,此时要添加标签,该标签可以产生如下代码: (2)由于token拦截器没有放置到默认栈中,所以当使用token表单重复提交的时候,需要在struts.xml中加载token拦截器

struts2复习模拟题

填空: 1.Struts 2以__过滤器__为核心,采用__拦截器__的机制来处理用户的请求。 2.构建Struts 2应用的最基础的几个类库是_struts2-core__、_commons-logging_、_xwork-core_、__freamarker___以及_ognl_。 3.Struts 2中的控制器类是一个普通的_POJO_。 4.如果要在JSP页面中使用Struts 2提供的标签库,首先必须在页面中使用taglib编译指令导入标签库,其中taglib编译指令为_____<%@ taglib prefix=”s” uri=”strut-tags”%>______。5.在Struts 2表单标签库中,表单标签为__________。 6.ActionSupport类实现了__action_________接口和___validateable________等接口。7.通过控制器类中的____validate()_______方法来输出校验错误信息。 8. 在Hibernate XML影射文件中描述主键生成机制,其属性描述了主键的生成策略,至少写出三种策略名 increment 、 native 、 uuid 。 9. 在Hibernate中级联操作的属性值至少写出三个____none_______ 、_____save-update______、____all_______。 10 Hibernate的会话接口是 ______Session接口_____,它由接口 __SessionFactory接口__创建;Hibernate处理事务的接口是____Transaction接口_______;封装HQL的接口是_____Criteria接口______ 。 11.Struts2框架由_____ Struts ______和______ WebWork _____框架发展而来。 12.Struts2中的控制器类是一个普通的____Class_______。 13.注入资源的注释是____@Resource ___

如何自定义Struts2表单验证后的错误信息显示格式

如何自定义Struts2表单验证后的错误信息显示格式/样式 (s:fielderror,换行,黑点) 前面一段时间学过一些Struts2的知识,感觉Struts2和1.x还是有很大的差别的,我还不好说1.x肯定会过时还是2.0会很快流行,这毕竟是需要作为导向的。 在Struts2中验证真的比较容易,可以在Action中直接写validate,也可以使用validate框架进行验证,这个我觉得比Struts1.x方便了很多,但是有个问题一直困扰了我,直到现在有个小程序要用到这个方面的知识,那就是验证后如何很好地人性化地在jsp 页面中显示了。 大家都知道,Struts2显示验证结果有一些方式,一般通过两种方式,介绍如下: 1.在页面的上面或者某个位置全部显示错误 代码: 这样会显示所有的错误信息,模拟效果如下: 2.在每个字段下面或上面显示,通过 XXX(标签的name属性,象https://www.wendangku.net/doc/6515333320.html,ername) 例:用 戶 名: https://www.wendangku.net/doc/6515333320.html,ername 显示效果如下:

上面的差不多是Struts默认显示的两种方式,但是我们常见的显示方式并不是这样的,所有我们需要自定义这种格式,我们的习惯是把错误信息显示在某个出错字段的后面,一行显示,而它给了一个小黑点并且换了行,我们现在就来解决这个问题。 这个问题困扰了我很久,真的很久以前想过,但是没有彻底地解决,一直留到现在,今天在google上搜了很久,终于给解决了,现在分享一下解决的途径。 先提供网上的思路给大家(关键解决的思路) 1.struts2表单验证_错误信息的显示问题中提到 引用 10 楼 starwar2030 的回复: 可以在CSS中定义 .formFieldError { font-family: verdana, arial, helvetica, sans-serif; font-size: 12px; color: #FF3300; vertical-align: bottom; } .formFieldError ul{ margin: 0px; padding: 3px; vertical-align: middle; } 而后使用类似用

相关文档