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.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
计算指定
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
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.
3.
4.
5.
6.
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.
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.
1.
2.
3.
4.
5.
6.
7.
8.
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.
--------------------------------------装--------------------------------------订------------------------------线---------------------------------------- **学院课程考试试卷 课程名称:《使用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.
Struts2学习之二--Struts2标签介绍 热12已有 14625 次阅读 2009-07-12 18:53 [顶]3G移动--Android开发工程师全能班 (转) Struts2学习之二--Struts2标签介绍 在上一篇文章《为Struts 2.0做好准备》中,我过于详细地介绍了Struts 2.0开发环境和运行环境的配置,所以,本文很少涉及的以上两方面的细节。如果,您看完《为Struts 2.0做好准备》后,还有什么不明白,或者没法运行文中例子,请联系我。我的E-MAIL:Max.M.Yuan@https://www.wendangku.net/doc/6515333320.html,。 在介绍常用标志前,我想先从总体上,对Struts 1.x与Struts 2.0的标志库(Tag Library)作比较。 分类将标志库按功能 分成HTML、Tiles、 Logic和Bean等 几部分 严格上来说,没有分类,所有标志都在URI 为“/struts-tags”命名空间下,不过, 我们可以从功能上将其分为两大类:非UI 标志和UI标志 表达式语言(expression languages)不支持嵌入语言 (EL) OGNL、JSTL、Groovy和Velcity 以上表格,纯属个人总结,如有所不足或错误,请不吝指正 好了,我要开始介绍“常用”(这里所谓的“常用”,是指在已往工作中使用Struts里经常用到的)的标志了。 1.非UI标志 o if、elseif和else 描述: 执行基本的条件流转。
参数: 名称必 需 默 认 类型描述备注 test 是Boolean 决定标志里内容是否 显示的表达式 else标志 没有这个 参数 id 否Object/String 用来标识元素的id。在UI和表单中为HTML的id属性 例子: <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags" %>
Strus2标签库 Struts2提供了一套标签库用于简化JSP层的编程,开发者只需要标签中做少量的设置,就可以实现各种常用的效果。Struts2的标签与Action联系比较紧密,使用标签后,Struts会自动完成JSP层的显示数据、在Action层采集数据等工作。 Struts2的标签都统一包含在struts-tags.tld文件中(位于struts2-core-2.2.1.jar中),使用统一前缀。 Struts标签库大致分为: UI标签:包括表单标签,非表单标签 非UI标签:流程控制标签,数据访问标签 首先要在JSP中使用taglib编译指令导入标签库,然后才可以使用标签。 <%@taglib prefix="s" uri="/struts-tags"%> 以上代码用于导入Struts2标签库,其中URI就是对应web.xml文件中指定的标签库的URI,而prefix属性值是该标签库的前缀。 第1节OGNL语言 OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。 OGNL语法类似于EL,主要使用.作为操作符,例如要访问person.getCountry().getName()可以这样写:https://www.wendangku.net/doc/6515333320.html,。 1.1 OGNL的常用符号 主要是#号,其作用有三种: 1. 访问OGNL上下文与ActionContext资源,相当于ActionContext.getContext(), 常用#属性如下表: parameters:
这个标签负责输出提示信息到客户端,例子如下: Action代码如下: public String execute() { addActionMessage("第一条普通消息!"); addActionMessage("第二条普通消息!"); return SUCCESS; } JSP:
1.下面关于Struts2描述正确的是()。 A. Struts2是线程安全的 B. Strut2为每个请求都只生成一个Action实例 C .Strut2是在Struts1基础上发展起来的 D. Struts2只支持jsp视图组件 2.Struts2配置包时,必须继承struts-default包,在下 面的哪个文件中可以找到struts-default包的配置()。 A.default.properties B. struts-message.properties C. struts.dtd D.struts-default.xml 3.Struts2默认的处理结果类型是()。 A. dispatcher B. redirect C. chain D. 以上说法都不正确 4.在Struts2框架中,实现Action接口的作用是()。 A.实现其中的execute()方法 B.实现数据校验 C.实现国际化 D.规范Action类 5.在Struts2中动态方法调用的格式为()。 A. ActionName_methodName.do B. ActionName!methodName.do C. ActionName_methodName.action D. ActionName!methodName.action 6.在Struts2中自定义的类型转换器必须实现的接口是 ()。 A.Convert B.TypeConverter C. StrutsTypeConverter D. StrutsConvert 7.在Struts2中,Action类中的属性从表单获取用户输入 的值,以下哪个组件将表单的值解析出来赋给Action ()。 A. ActionServlet B. Action C. 拦截器栈 D. HttpServletRequest 8.在Struts2中,关于 常用Struts标签的使用说明 Struts Html标签库 1, Struts2_day03 前一天内容 1 在action获取表单提交数据 (1)使用ActionContext类获取 (2)使用ServletActionContext类获取 (3)接口注入 2 结果配置 (1)全局结果页面和局部结果页面 (2)result标签type属性 - type属性值: -- 默认值是dispatcher做转发 -- redirect做重定向 -- chain转发到action -- redirectAction重定向到action 3 struts2提供获取表单数据方式 (1)属性封装 (2)模型驱动封装 (3)表达式封装 4 struts2获取数据封装到集合中 5 使用模型驱动和属性封装注意问题: (1)不能同时使用对同一个表单进行数据操作 6 表达式封装和模型驱动比较 (1)相同点:可以把数据封装到实体类对象里面 (2)不同的:表达式封装可以封装到多个实体类对象里面今天内容 1 ognl概述 2 ognl入门案例 3 什么是值栈 (1)servlet和action区别 (2)值栈存储位置 - 每个action对象里面有一个值栈对象 - 值栈对象里面有action引用 4 如何获取值栈对象 5 值栈内部结构 (1)root:list集合 (2)context:map集合 6 向值栈放数据 (1)s:debug标签 (2)向值栈放字符串 (3)向值栈放对象 (4)向值栈放list集合 - set方法 - push方法 - 定义变量,get方法 7 从值栈获取数据 (1)从值栈获取字符串 (2)从值栈获取对象 (3)从值栈获取list集合 - s:iterator标签使用 8 EL表达式获取值栈数据 (1)增强request里面getAttribute方法 9 ognl表达式#、%使用 OGNL概述 1 之前web阶段,学习过EL表达式,EL表达式在jsp中获取域对象里面的值 2 OGNL是一种表达式,这个表达式功能更加强大, (1)在struts2里面操作值栈数据 (2)一般把ognl在struts2操作:和struts2标签一起使用操作值栈 3 OGNL不是struts2的一部分,单独的项目,经常和struts2一起使用 (1)使用ognl时候首先导入jar包,struts2提供jar包 Struts2 框架第三天 今天重点内容安排: 第一天:struts2 开发流程、访问Action,Action方法调用,结果集类型 第二天:获取请求参数,请求数据校验机制,拦截器 1、V alueStack 值栈的存储原理和相关操作 2、Ognl 表达式语言语法 3、struts2 页面控制标签 4、struts2 form表单相关标签 重点难点:值栈和Ognl 1.值栈和Ognl表达式 1.1.什么是Ognl Ognl 对象导航图语言Object Graphic Navigation Language,类似EL,比EL ${}语法要强大很多,Struts2框架使用OGNL作为默认的表达式语言必须要引入struts标签库 EL Expression Language 表达式语言,用来获取JSP页面四个域范围数据 pageContext、request、session、application ) Ognl 主要用法: 1、访问OGNL上下文值栈对象获取数据(最重要) 2、操作集合对象(结合struts2 标签库使用)---- 生成checkbox 、生成select 1.2.什么是值栈ValueStack接口! 值栈ValueStack 实际上是一个接口,struts2 Ognl使用都是基于值栈完成的 Struts2 内部提供OgnlValueStack的接口实现类,实现了值栈接口! 前端控制器每一次请求都会创建一个值栈对象源码: 一次请求对应一个值栈对象值栈生命周期= request 生命周期的!! 值栈是struts2 一个数据结构,贯穿整个Action实例生命周期(request生命周期),一次请求对应一个Action实例,一个Action实例对应一个值栈实例 值栈保存了Action 和其它常用web对象的引用,通过值栈,间接操作这些对象!1.3.值栈的存储结构 1:采用标签 Struts2基础知识 Struts2概述 1.Struts2框架应用javaee三层结构中的web层框架。 2.Struts2框架在struts1和webwork基础之上发展的全新框架。 3.Struts2所解决的问题: 在以往实现一个功能时,都需要写很多的servlet,从而造成后期维护上的不方便。 图解: 4.现在比较稳定的Struts2版本 struts-2.3.24-all.zip 5.web层常见框架 1.struts 2.springMVC Struts2框架入门 1.导入jar包 1.在lib里面有jar包,但不能全部导入,因为里面含有一些spring 包,是不能使用的,导入会导致程序不能运行。 2.到app目录里面复制案例的jar包是最好的方法。 2.创建action 3.配置action类的访问路径 1.创建struts2核心配置文件,该核心配置文件位置和名称是固定的, 位置必须在src下面,名称为struts.xml 。 2.引入dtd约束,可以在案例文件中找到,复制在struts.xml文件中即 可。 3.action的配置 *注意访问路径: http://域名/端口号/项目名/action名.action 注意:.action可以省略,但建议不要省略,为了兼容一些老版本的浏览器。 4.配置Struts2的过滤器,可以在案例中的web.xml文件中找到,复制粘贴 即可。 Struts2执行过程 图解: Struts2配置 1.是一种常量标签 2.修改Struts2的默认常量值 1.常用方式 在struts.xml中进行配置。 2.其它两种方式 1.在src下面创建struts.properties文件并修改。 2.在web.xml文件中进行修改。 3.Struts2最常用的常量 struts.il8n.encoding=UTF-8,解决表单在通过post方式提交中文时,中文乱码的问题。 常用的Struts 2.0的标志(Tag )介绍 在上一篇文章《为Struts 2.0做好准备》中,我过于详细地介绍了Struts 2.0开发环境和运行环境的配置,所以,本文很少涉及的以上两方面的细节。如果,您看完《为Struts 2.0做好准备》后,还有什么不明白,或者没法运行文中例子,请联系我。我的E-MAIL :Max.M.Yuan@https://www.wendangku.net/doc/6515333320.html, 。 在介绍常用标志前,我想先从总体上,对Struts 1.x 与Struts 2.0的标志库(Tag Library )作比较。 分类 将标志库按功能分成HTML 、Tiles 、Logic 和Bean 等几部分 严格上来说,没有分类,所有标志都在URI 为“/struts -tags” 命名空间下,不过,我们可以从功能上将其分为两大类:非UI 标志和UI 标志 表达式语言(expression languages ) 不支持嵌入语言(EL ) OGNL 、JSTL 、 Groovy 和Velcity 以上表格,纯属个人总结,如有所不足或错误,请不吝指正 好了,我要开始介绍“常用”(这里所谓的“常用”,是指在已往工作中使用Struts 里经常用到的)的标志了。 要在JSP 中使用Struts 2.0标志,先要指明标志的引入。通过在JSP 的代码的顶部加入以下代码可以做到这点。 <%@taglib prefix ="s" uri ="/struts-tags" %> 1. 非UI 标志 o if 、elseif 和else 描述: 执行基本的条件流转。 参数: 名称 必需 默 认 类型 描述 备注 test 是 Boolean 决定标志里内容是否显示的表达式 else 标志没有这个参数 Struts2面试题 1、struts2工作流程 Struts 2框架本身大致可以分为3个部分: 核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。核心控制器FilterDispatcher是Struts 2框架的基础, 包含了框架内部的控制流程和处理机制。 业务控制器Action和业务逻辑组件是需要用户来自己实现的。 用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件, 供核心控制器FilterDispatcher来使用。 Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同, 所以说Struts 2是WebWork的升级版本。基本简要流程如下: 1 、客户端初始化一个指向Servlet容器的请求; 2、这个请求经过一系列的过滤器(Filter) (这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器, 这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 3 、接着FilterDispatcher被调用, FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action 4、如果ActionMapper决定需要调用某个Action, FilterDispatcher把请求的处理交给ActionProxy 5、ActionProxy通过Configuration Manager询问框架的配置文件, 找到需要调用的Action类 6、ActionProxy创建一个ActionInvocation的实例。 7、ActionInvocation实例使用命名模式来调用, 在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。 8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP 或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper 9、响应的返回是通过我们在web.xml中配置的过滤器 10、如果ActionContextCleanUp是当前使用的,则FilterDispatecher将不会清理sreadlocal ActionContext;如果ActionContextCleanUp不使用,则将会去清理sreadlocals。 2、说下Struts的设计模式 MVC模式: web应用程序启动时就会加载并初始化ActionServler。用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用Action的execute()方法。Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生 成动态的网页,返回给客户。 STRUTS2模拟测试(开卷——定时90分钟) 一、填空题 1.Struts2框架由___Struts1________和____WebWork_______框架发展而来。(Struts&WebWork ) 2.Struts2以___WebWork______为核心,采用____拦截器_______的机制来处理用户的请求。(WebWork,拦截器)3.构建Struts2应用的最基础的几个类库是struts-core-2.1.6.jar___________、__xwork-2.1.2.jar_________、__ognl-2.6.11.jar_________ 、_freemarket-2.3.13、_commons-logging-1.0.4.jar_________以及 ___commons-fileupload-1.2.1.jar________。 4.Struts2中的控制器类是一个普通的_____class______。Class 5.如果要在JSP页面中使用Struts2提供的标签库,首先必须在页面中使用taglib编译指令导入标签库,其中taglib编译指令为_<%@ taglib prefix=”s” uri=”/struts-tags”%>__________。<%taglib uri="/struts-tags" prefix="s"%> 6.在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. 10. 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)在某个页面验证表单重复提交,此时要添加 填空: 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表单标签库中,表单标签为_____ 如何自定义Struts2表单验证后的错误信息显示格式/样式 (s:fielderror,换行,黑点) 前面一段时间学过一些Struts2的知识,感觉Struts2和1.x还是有很大的差别的,我还不好说1.x肯定会过时还是2.0会很快流行,这毕竟是需要作为导向的。 在Struts2中验证真的比较容易,可以在Action中直接写validate,也可以使用validate框架进行验证,这个我觉得比Struts1.x方便了很多,但是有个问题一直困扰了我,直到现在有个小程序要用到这个方面的知识,那就是验证后如何很好地人性化地在jsp 页面中显示了。 大家都知道,Struts2显示验证结果有一些方式,一般通过两种方式,介绍如下: 1.在页面的上面或者某个位置全部显示错误 代码: 上面的差不多是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; } 而后使用类似用 struts标签说明
Struts2_day03笔记
struts2_day03笔记
Struts2知识点总结
struts2常用标签
struts2面试题(自己总结)
STRUTS2模拟(答案)
Struts2试题
Struts2中防止表单的重复提交
struts2复习模拟题
如何自定义Struts2表单验证后的错误信息显示格式