Struts2的配置以及详解
2015-07-24 19:50
531 查看
1,truts2的作用: 3
1-1 MVC框架: 3
1-2 导入struts.xml配置文件的快捷提示: 3
2,struts2的配置 4
2-1 配置简介 4
2-2配置Struts2的三个步骤 4
1 导入Struts2的jar包 4
2 添加核心配置文件Struts2.xml 4
3 配置过滤器web.xml 5
3,完整的执行步骤: 5
4,创建Action类 6
4-1 Action类的要求: 6
4-2 创建Action类的方法 6
5 从Action向页面传值 6
5-1通过URL 6
5-2通过request传值 6
5-3用list 7
6 获取web元素的方法 7
6-1 获得web元素的第一种方法:直接定义Map 7
6-2 获得web元素的第二种方法:实现三接口 8
6-3 获得web元素的第三种方法:定义三Http对象 8
6-4 获得web元素的第四种方法:继承ServletRequestAware接口 9
7 OGNL:Object-Graph Navigation Language(对象图导航语言) 9
7-1 获取普通对象和值:需要set和get方法 10
7-2 获取对象中对象的属性值 10
7-3 获取对象中的普通方法 10
7-4获取对象中的静态方法 10
(1)在配置中配置: 10
(2)在页面取值 10
(3)调用数学方法 10
7-5 获取值栈中request的值,前面要加’#’ 10
7-6 调用Action中的方法 11
7-7 获取list集合 11
(1)获取指定下标的list元素 11
(2)获取指定属性的集合 11
7-8 获取set集合 11
7-9 获取map集合 11
(1)获取根据key取值 的四种方法 12
(2)获取根据key取具体的属性值 12
(3)回去所有key的方法 12
(4)获取map中的值 12
(5)遍历具体的属性值 12
7-10 根据条件查询打印 12
(1)获取集合list将年龄大于20的学生打印出来 12
(2)第一个满足条件的’^’ 12
(3)最后一个满足条件的 ‘$’ 13
(4)迭代满足条件的 13
8 Struts2标签 13
8-1,struts标签分为: 13
8-2,通用标签: 13
(1)property 13
(2)set 13
(3)bean 14
(4)include(解决中文问题很麻烦) 14
(5)param 14
(6)debug 14
8-3,控制标签: 14
8-4,UI标签: 15
8-5,$#%的区别 15
9 struts2标签的实例 15
9-1 如果value值不存在,就将default值显示页面 15
9-2 escape是否以文本形式输出 15
9-3 从值栈中获取数据存放到web元素中 15
9-4 在页面中设置对象 15
9-6 迭代器 16
9-7 用标签划页面 16
10 struts框架中用Exp 17
10-1 导入exp操作的jar包 17
10-2 导入struts2的jar包 17
10-3 配置struts.xml核心配置文件 17
10-4 配置web.xml 17
10-5 在页面上写连接跳转 17
10-6 写Action类 17
10-6-1 定义属性冰生成set和get方法 17
10-6-2 写download()方法进行页面外输出 18
11 配置error信息 19
11-1在struts.xml进行配置 19
11-2在页面中进行配置信息 19
11-2-1提交信息: 19
11-2-2接受错误信息的提示的两种方法 19
11-3 在Action中进行配置 19
11-3-1 声明属性(与页面对应)并创建set和get方法 19
11-3-2 在默认的方法中进行数据处理 19
12配置I18N步骤 20
12-1 导入struts2的jar包 20
12-2 创建转换的环境配置文件 20
12-3 创建Action类 20
12-4 配置struts.xml核心配置文件 20
12-5 配置web.xml文件 21
12-6 配置页面的连接信息 21
13 自定义拦截器 22
13-1自定义拦截器需要实现接口Interceptor 并且实现三个接口 22
13-2在struts.xml中进行配置 22
14 用拦截器防止重复提交 23
15 数据校验 23
15-1手工数据校验 23
15-1-1输入校验流程: 24
15-1-2实例:对Add()方法进行校验 24
15-2 自动数据校验(xml) 25
15-2-1对整个actionClass进行验证 25
15-2-2 对action中的某个方法校验 25
15-3系统提供的校验器如下: 26
15-4实际的例子 27
16自定义类型转换器的配置 29
16-1 配置 29
16-2例如: 29
C(Control)控制:流程控制完成UI和java的交互--->servlet/Struts2
M(Model)模型:java模型和数据库模型-->JDBC/Hibernate
Struts2代替了Servlet完成了UI和JAVA代码的数据交互
key type=uri
location=选取struts核心包解压后的struts-2.0.dtd文件路径
key=http://struts.apache.org/dtds/struts-2.0.dtd
2 配置Action类
3 在页面的请求跳转到Action(配置文件)
4 在Action类中接收数据
5 将Action类中的数据传递到页面
6 在页面上接收Action传递的数据(LSTL+EL)
commons-io-2.0.1.jar -->io流
commons-lang-2.5.jar
commons-logging-1.1.1.jar
freemarker-2.3.16.jar
javassist-3.11.0.GA.jar
ognl-3.0.1.jar
struts2-core-2.2.3.1.jar -->核心配置包
xwork-core-2.2.3.1.jar
2 添加核心配置文件Struts2.xml
*头文件位置
struts2-core-2.2.3.1.jar(倒数第二个)-->struts-2.0.dtd(倒数第六个)-->30-32行
*内容
<struts>
<package name="a" extends="struts-default">
<!-- 如果说执行的是Action中默认的方法,那么就不用配置method
如果是action中的具体的方法那么就配置 method="具体的方法名"-->
<action name="AddAction" class="com.softeem.action.AddAction" method="add">
<result>/success.jsp</result>
</action>
</package>
</struts>
3 配置过滤器web.xml
<!-- struts2的核心过滤器配置 -->
<filter>
<filter-name>struts2</filter-name>
<!--struts2的 核心过滤器Filter的路径 -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<!-- 拦截所有 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
<body>
<form action="AddAction" method="post">
用户名:<input type="text" name="name"/>
密码:<input type="password" name="pass"/>
<input type="submit" value="提交"/>
</form>
</body>
--注意:当我们点击提交的时候会提交form表单到--->action="AddAction"-->
这个时候web.xml中的核心控制器会拦截所有的客户请求-->转发给struts.xml
-->在struts.xml文件中会根据传递过来的action="AddAction" 进行对比
-->然后再进入到相应的Action配置中-->根据Action的class路径跳转到Action
-->如果struts.xml文件中的Action配置没有method那么在相应的Action中执行默认的方法
如果配置了method那么在相应的Action中执行配置的method的方法
2 在Action类中定义无参数带有String类型返回值的方法响应用户请求
3 所有的Action类必须在struts.xml中进行配置
一个实现了xwork包中的Action接口的类,我们成为Action可以用来接受请求
*创建一个类实现Action接口(com.opensymphony.xwork2.Action)可以重写execute()方法
*创建一个类继承ActionSupport(因为ActionSupport实现了Action接口)
*定义属性: private String str;
*生成set和get方法
*在方法中设置值: str="哇哈哈2";
在struts.xml配置文件中: <result name="a">/list01.jsp?str={str}</result>
在页面上取值: ${str }
*定义属性: private List<Student> list;;
*生成set和get方法
*在方法中设置值:
方法一:
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("msg","王向新" );
方法二:
Map request = (Map)ServletActionContext.getContext().get("request");
request.put("msg", "王向新大坏蛋");
在页面上取值: ${requestScope.msg }
*定义属性: private List<Student> list;;
*生成set和get方法
*在方法中设置值:
list = new ArrayList<Student>();
list.add(new Student("郭群1","男",15));
list.add(new Student("郭群2","男",16));
在页面上取值:
*导入标签: <%@taglib prefix="s" uri="/struts-tags" %>
*获取: <s:debug></s:debug>(通过一定的方法可以获取list的值)
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
在execute()方法中:
获取实例对象
request = (Map)ActionContext.getContext().get("request");
session = ActionContext.getContext().getSession();
application = ActionContext.getContext().getApplication();
设置属性值
request.put("r", "request范围的值");
session.put("s", "session范围的值");
application.put("a", "application范围的值");
重写三个方法:setRequest,setSession,setApplication
定义需要的对象
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
在接口实现方法中:
获取实例对象
setRequest: this.request = request;
setSession: this.session = session;
setApplication: this.application = application;
在execute()方法中:
设置属性值
request.put("r", "request范围的值");
session.put("s", "session范围的值");
application.put("a", "application范围的值");
然后得到对应的实例对象
定义需要的对象
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
在execute()方法中:
获取实例
request = ServletActionContext.getRequest();
session = request.getSession();
application = session.getServletContext();
设置属性
request.setAttribute("r", "request");
session.setAttribute("s", "session");
application.setAttribute("a", "application");
定义需要的对象
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
在setServletRequest方法中获取对应的实例对象
this.request = request;
this.session = request.getSession();
this.application = session.getServletContext();
在execute()方法中:
设置属性值
request.setAttribute("r", "request44");
session.setAttribute("s", "session44");
application.setAttribute("a", "application44");
* 常用的从Action传值到JSP的方式有两中:
* 全局属性传值和web元素传值
* 全局属性(变量)传值放在值栈中
* web元素传值放在上下文中
导入struts2知道的标签
<%@taglib prefix="s" uri="/struts-tags" %>
导入c标签
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<s:property value="stu"/>
<s:property value="stu.stuNum"/>
<s:property value="stu.add(1,8)"/>
<s:property value="stu.method1()"/>
<s:property value="@@sqrt(9)"/>
<s:property value="#request.stu1"/>
<s:property value="#request.stu1.stuName"/>
<s:property value="#request.stu1.method()"/>
<s:property value="list[1].stuNum"/>
<s:property value="list.get(0).stuNum"/>
<s:property value="list.{stuAge}"/>
(1)获取指定属性的集合的第几个元素
<s:property value="list.{stuNum}[0]"/>
(2)遍历list集合
<s:iterator value="list" var="stu">
<s:property value="#request.stu.stuNum"/>
<s:property value="#request.stu.stuName"/>
<s:property value="#request.stu.stuAge"/>
<s:property value="#request.stu.stuSex"/><br/>
</s:iterator>
<s:property value="set.{stuNum}"/>
<s:iterator var="s" value="set">
<s:property value="#request.s.stuName"/>
</s:iterator>
<s:property value="map['s1']"/>
<s:property value="map[\'s1\']"/>
<s:property value="map.s1"/>
(2)获取根据key取具体的属性值
<s:property value="map['s1'].stuName"/>
<s:property value="map.keys"/>
<s:iterator var="key" value="map.keySet()">
<s:property value="key"/>
</s:iterator>
<s:property value="#request.value.stuNum"/>
<s:property value="#request.value.stuName"/>
<s:property value="#request.value.stuAge"/>
<s:property value="#request.value.stuSex"/><br/>
</s:iterator>
<s:property value="#request.s.stuNum+'--'+#request.s.stuName+'--'+#request.s.stuAge+'--'+#request.s.stuSex"/><br/>
</s:iterator>
*控制标签
*UI标签(展现)
表示根据在值栈中根据username取到一个对象显示
*property取值为字符串<s:property value="'哈哈'"/>
表示直接显示一个"哈哈"字符串,直接显示的字符串要加上单引号
*property的默认值:<s:property value="admin" default="管理员"/>
如果根据admin在值栈中取值没有取到,则显示默认值
*property设定HTML:<s:property value="'<hr/>'" escape="true"/>
如果没有加上escape="true",表示直接显示字符串
默认存放在request和ActionContext中,value值为对象
*从request中取值:<s:property value="#request.user"/>
*从ActionContext中取值:<s:property value="#user"/>
默认取值空间为ActionContext
*范围的设置:<s:set name="key" value="password" scope="page"/>
<s:bean name="com.softeem.pojos.User" var="user1">
<s:param name="username" value="'张三'"></s:param>
</s:bean>
var表示新创建的对象的名字,如果没有var属性就不能在Context stack中找到
s:param给新创建的对象属性赋值,注意value
<s:include value="/test.jsp"></s:include>
*用%包含文件:
<s:set var="incPage" value="'/test.jsp''}"/>
<s:include value="incPage"></s:include>
<s:include value="#incPage"></s:include>
<s:include value="%{#incPage}"></s:include>
iterator
status属性:
count遍历过的元素总数
index遍历过的索引
even当前是否偶数
odd当前是否奇数
first是否第一个元素
last是否最后一个元素
subset(截取集合的一部分)
struts.xml中控制theme,默认为xhtml,可以设置为simple/css_xhtml/ajax
<constant name="struts.ui.theme" value="css_xhtml"/>
#用于取ActionContext的值
%将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用
<s:set name="s" value="stu" scope="request"></s:set>
<s:param name="stuNum" value="'11'"/>
<s:param name="stuName" value="'aa'"/>
<s:param name="stuSex" value="'男'"/>
<s:param name="stuAge" value="22"/>
</s:bean>
取值:
<s:property value="#ssss.stuName"/>
9-5 if判断
<s:if test="stu.stuSex.equals(\"男\")">这家伙是男的</s:if>
<s:elseif test="stu.stuSex.equals(\"女\")">这家伙是女的的</s:elseif>
<s:else>这家伙不男不女</s:else>
<s:property value="#statu.count"/>当前总的数目
<s:property value="#statu.index"/>当前的下标
<s:property value="#statu.even"/>当前是否是偶数
<!-- 判断当前元素是不是偶数行 -->
<s:if test="%{#statu.even}">
<font color="red"><s:property value="#p1.name"/></font>
</s:if>
<s:else>
<s:if test="%{#statu.first}">
<font size="10px"><s:property value="#p1.name"/></font>
</s:if>
<s:else>
<font color="green"><s:property value="#p1.name"/></font>
</s:else>
</s:else>
</s:iterator>
<s:textarea name="name" label="用户名"></s:textarea>
<s:password name="pass" label="密码"></s:password>
<s:radio list="{'男','女'}" name="sex" required="true" label="性别"></s:radio>
<s:select list="map2" label="部门"></s:select>
<s:checkboxlist list="{'java','php','c++','ruby'}" name="test" label="学习计划"></s:checkboxlist>
<s:textarea label="个人简介"></s:textarea>
<s:submit value="提交" labelposition="right"></s:submit>
</s:form>
<package name="default" extends="struts-default">
<action name="ExcelAction" class="com.softeem.action.ExcelAction">
<!-- 固定的写法 -->
<result type="stream">
<param name="contentType">application/vnd.ms-excel</param>
<paramname="contentDisposition">attachment;filename=${fileName}</param>
<param name="inputName">excelStream</param>
</result>
</action>
</package>
</struts>
private String fileName; //从页面接受传入的文件名称
HSSFWorkbook workbook = null;
//自定义表名
fileName=URLEncoder.encode("用户信息表.xls","utf-8");
//创建工作薄
workbook = new HSSFWorkbook();
//创建一个表单
HSSFSheet sheet = workbook.createSheet("基本信息");
//创建首行
HSSFRow row_head = sheet.createRow(0);
//设置本行每个格子的属性值
row_head.createCell(0).setCellValue("序号");
row_head.createCell(1).setCellValue("用户名");
row_head.createCell(2).setCellValue("手机号");
row_head.createCell(3).setCellValue("邮箱地址");
row_head.createCell(4).setCellValue("性别");
//创建数据行
HSSFRow row1 = sheet.createRow(1);
row1.createCell(2).setCellValue("110");
row1.createCell(3).setCellValue("110@qq.com");
row1.createCell(4).setCellValue("男");
HSSFRow row2 = sheet.createRow(2);
row2.createCell(0).setCellValue(2);
row2.createCell(1).setCellValue("王五");
row2.createCell(2).setCellValue("120");
row2.createCell(3).setCellValue("120@qq.com");
row2.createCell(4).setCellValue("男");
//创建字节数组输出流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//把字节输入流绑定到工作簿里
workbook.write(bos);
//讲输出流转换成字节数组
byte[] byt = bos.toByteArray();
//用定义的输入流输出有工作簿生成 的字节数组
excelStream = new ByteArrayInputStream(byt);
<result>/success.jsp</result>
<result name="error">/index.jsp</result>
</action>
<table>
<tr><td>usrname:</td><td><input type="text" name="name"/></td></tr>
<tr><td>usrpass:</td><td><input type="password" name="pass"/></td></tr>
<tr><td colspan="2"><input type="submit" value="提交"/></td></tr>
</table>
</form>
<s:fielderror name="error"></s:fielderror>
private String pass;
if("123".equals(pass)){
return "success";
}else{
this.addFieldError("error","密码错误");
}
}else{
this.addFieldError("error","用户不存在");
}
//返回error进行接收
return "error";
日文: app_ja_JP.properties
中文: app_zh_CN.properties
UserAction(提交数据的处理action)
<constant name="struts.custom.i18n.resources" value="app"></constant>
对配置的环境变量进行解析,并在结果集合中调用
<package name="p" extends="struts-default">
<action name="I18NAction" class="com.softeem.action.I18NAction">
<result>/index.jsp</result>
</action>
</package>
在网页进行跳转的路径是UserAction时进行调用
<package name="p2" extends="p">
<action name="UserAction" class="com.softeem.action.UserAction">
<result>/index.jsp</result>
</action>
</package>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<a href="I18NAction?request_locale=zh_CN">中文</a>
<a href="I18NAction?request_locale=en_US">英文</a>
<a href="I18NAction?request_locale=ja_JP">日文</a>
获取环境变量中的值
<s:property value="getText(\'userlogin\')"/>获取 userlogin 的对应的语言的值
<s:property value="getText(\"user\")"/>获取 user 的对应的语言的值
提交数据的时候进行跳转
<form action="UserAction" method="post">
init():初始化时候执行
intercept(ActionInvocation arg0):拦截时执行的方法
1过滤器在首次请求的时候会执行,拦截器在任意的时候都可以执行
2过滤器所有的请求(servlet/jsp)都会过滤,拦截器可以精确到任何一个action
引入指定的拦截器 配置其他拦截器之前需要引入struts2提供的默认拦截器defaultStack否则当前的拦截器会将默认的覆盖
配置整个package的拦截器
<package name="struts2" extends="struts-default">
<interceptors>
<interceptor name="MyInterceoter" class="com.softeem.interceptor.MyInterceoter"></interceptor>
</interceptors>
<action name="testAction" class="com.softeem.action.TestAction">
<result>/main.jsp</result>
<!-- 声明配置默认 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 声明配置自定义 -->
<interceptor-ref name="MyInterceoter"></interceptor-ref>
</action>
</package>
配置拦截器栈
<!-- 自动启动 -->
<constant name="struts.devMode" value="true"></constant>
<package name="struts2" extends="struts-default">
<!-- 自定义一个拦截器 ,在哪个action需要拦截,就在该action进行配置-->
<interceptors>
<interceptor name="ProInterceptor" class="com.softeem.intercepter.ProInterceptor"></interceptor>
<!-- 拦截器栈 -->
<interceptor-stack name="MyStack">
<interceptor-ref name="ProInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="mainAction" class="com.softeem.action.TestAction">
<!-- 引用拦截器栈 -->
<interceptor-ref name="MyStack"></interceptor-ref>
<result>/main.jsp</result>
</action>
</package>
<!-- 自动启动 -->
<constant name="struts.devMode" value="true"></constant>
<package name="struts2" extends="struts-default">
<action name="testAction" class="com.softeem.action.TestAction">
<!-- 配置拦截器 默认拦截器-->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 拦截重复提交-->
<interceptor-ref name="token"></interceptor-ref>
<result>/main.jsp</result>
<!--重复提交跳转到指定的页面-->
<result name="invalid.token">/resubmit.jsp</result>
</action>
</package>
</struts>
validate方法是重写,它是在ValidateAble接口中定义的所以我们这个action要实现ValidateAble接口才能完成校验但是ActionSupport已经实现了ValidateAble接口,所以我们创建的action只要继承了ActionSupport,就可以重写validate
对action中所有的方法进行校验:
@Override
public void validate() { }
对action中指定的方法进行校验(Xxx为需要校验的方法名)
public void validateXxx() {
}
2.如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext;conversionError拦截器将异常信息封装到fieldError里,不管类型转换是否出现异常,都会进入到第3步
3.系统通过反射,先调用action中的validateXxx()方法,Xxx为action中的方法名
4.再调用action中的validate方法
5.如果系统中的fieldErrors存在错误信息,系统自动将请求转发至名为input的result中,如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法
if(user.getUname() == null || "".equals(user.getUname())){
this.addFieldError("uname", "请输入用户名");
}
if(user.getUphone() != null || !"".equals(user.getUphone())){
if(!Pattern.matches("^1[358]\\d{9}$", user.getUphone())){
this.addFieldError("uphone", "输入的手机格式不正确");
}
}else{
this.addFieldError("uphone", "请输入手机号");
}
if(user.getUemail() != null || !"".equals(user.getUemail())){
if(!Pattern.matches("^\\S+@\\S+.(com|COM)$", user.getUemail())){
this.addFieldError("uemail", "输入的邮箱不正确");
}
}else{
this.addFieldError("uemail", "请输入邮箱");
}
}
例子:
用于验证的配置文件命名:UserAction-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空</message>
</field-validator>
</field>
</validators>
<field>指定action中需要校验的属性
<field-validator>指定校验器type为校验器的类型;
<param>中name值指定先调用String类的trim()方法去掉前后空格再来校验
<message>未校验失败后的提示信息
<action name="user_*"class="com.softeem.action.UserAction" method={1}>
<result>/success.jsp</result>
<result name="input">/fail.jsp</result>
</action>
UserAction.java中的方法
public String add(){}
public String update(){}
若要对add()方法实施验证,校验文件的取名为:
UserAction-user_add-validation.xml
若要对update()方法实施验证,校验文件的取名为:
UserAction-user_update-validation.xml
<!-- 命名方式:UserAction-UserAction_add-validation.xml
action的名称-struts对action的配置name的值-validation.xml -->
<!-- 需要被验证的字段 -->
<field name="user.uname">
<!-- 指定校验器 -->
<!-- 校验是否为空 -->
<field-validator type="requiredstring">
<message>请输入用户名</message>
</field-validator>
<!-- 一个属性字段可以指定对个校验器 -->
<!-- 校验长度 -->
<field-validator type="stringlength">
<param name="minLength">1</param>
<param name="maxLength">6</param>
<message>用户名的长度必须在4-16之间</message>
</field-validator>
</field>
<!-- 验证邮箱 -->
<field name="user.uemail">
<field-validator type="requiredstring">
<message>请输入邮箱地址</message>
</field-validator>
<!-- 邮箱的格式 -->
<field-validator type="email">
<message>输入邮箱格式不正确</message>
</field-validator>
</field>
<!-- 对网址进行校验(要http://) -->
<field name="user.url">
<field-validator type="requiredstring">
<message>请输入个人主页</message>
</field-validator>
<field-validator type="url">
<message>输入个人主页不正确</message>
</field-validator>
</field>
<field name="user.uphone">
<field-validator type="requiredstring">
<message>请输入手机号</message>
</field-validator>
<!-- 正则表达式 -->
<field-validator type="regex">
<param name="expression"><![CDATA[^1[358]\d{9}$]]></param>
<message>输入手机号不正确</message>
</field-validator>
</field>
<!-- 校验日期 -->
<field name="user.birth">
<!-- 必填校验器,无类型规定 -->
<field-validator type="required">
<message>请输入日期</message>
</field-validator>
<field-validator type="date">
<param name="max">2013-11-24</param>
<message>日期不能大于${max}</message>
</field-validator>
</field>
<!-- 校验密码 -->
<field name="user.upass">
<field-validator type="requiredstring">
<message>请输入密码</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">1</param>
<param name="maxLength">6</param>
<message>密码的长度必须在1-6之间</message>
</field-validator>
</field>
<!-- 校验重复密码 -->
<field name="reupass">
<field-validator type="requiredstring">
<message>请输入再次输入密码</message>
</field-validator>
<field-validator type="fieldexpression">
<param name="expression"><![CDATA[reupass==user.upass]]></param>
<message>两次密码不一致</message>
</field-validator>
</field>
</validators>
* 需要重写一个方法:convertValue(Object value, Class toType)
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
* 配置指定级别的属性文件(Action级别,包级别,项目级别)
类型转换类的三种配置形式(局部转换器,全局转换器):
*actin级别:
配置文件的名字:action-conversion.properties
内部配置:ation对应的属性名=转换类的路径
配置文件的存放位置:和action位置相同
说明:当用户访问这个action中这个属性的时候才调用类型转换类
*pojo级别:
配置文件的名字:pojo-conversion.properties
配置文件的存放位置:和pojo的位置相同
内部配置:pojo对应的属性名=类型转换类的路径
说明:当用户访问任何action,只要提交了这个pojo中的这个属性的时候就会调用类型转换类
*src级别:
配置文件的名字:xwork-conversion.properties
配置文件的存放位置:直接存放在src下
内部配置:属性类型(+包名)=类型转换类的路径
说明:用户访问任何action,只要提交了对应类型的属性的时候就会调用类型转换类
public class DateTimeConvert extends DefaultTypeConverter{
@Override
public Object convertValue(Object value, Class toType) {
//页面端传来的每一个控件的数据都是字符串数组
String[] s = (String[])value;
if(toType==java.util.Date.class){
String str = s[0];
//定义自己的日期输出格式,页面输出格式yyyyMMdd,但是系统自带的日期转换就被覆盖了
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parseObject(str);
} catch (ParseException e) {
e.printStackTrace();
}
}else if(toType==String.class){
return s[0];
}
return super.convertValue(value, toType);
}
}
(2)环境配置
命 名: UserAction-conversion.properties
参数信息: hiredate=com.softeem.convert.DateTimeConvert
1-1 MVC框架: 3
1-2 导入struts.xml配置文件的快捷提示: 3
2,struts2的配置 4
2-1 配置简介 4
2-2配置Struts2的三个步骤 4
1 导入Struts2的jar包 4
2 添加核心配置文件Struts2.xml 4
3 配置过滤器web.xml 5
3,完整的执行步骤: 5
4,创建Action类 6
4-1 Action类的要求: 6
4-2 创建Action类的方法 6
5 从Action向页面传值 6
5-1通过URL 6
5-2通过request传值 6
5-3用list 7
6 获取web元素的方法 7
6-1 获得web元素的第一种方法:直接定义Map 7
6-2 获得web元素的第二种方法:实现三接口 8
6-3 获得web元素的第三种方法:定义三Http对象 8
6-4 获得web元素的第四种方法:继承ServletRequestAware接口 9
7 OGNL:Object-Graph Navigation Language(对象图导航语言) 9
7-1 获取普通对象和值:需要set和get方法 10
7-2 获取对象中对象的属性值 10
7-3 获取对象中的普通方法 10
7-4获取对象中的静态方法 10
(1)在配置中配置: 10
(2)在页面取值 10
(3)调用数学方法 10
7-5 获取值栈中request的值,前面要加’#’ 10
7-6 调用Action中的方法 11
7-7 获取list集合 11
(1)获取指定下标的list元素 11
(2)获取指定属性的集合 11
7-8 获取set集合 11
7-9 获取map集合 11
(1)获取根据key取值 的四种方法 12
(2)获取根据key取具体的属性值 12
(3)回去所有key的方法 12
(4)获取map中的值 12
(5)遍历具体的属性值 12
7-10 根据条件查询打印 12
(1)获取集合list将年龄大于20的学生打印出来 12
(2)第一个满足条件的’^’ 12
(3)最后一个满足条件的 ‘$’ 13
(4)迭代满足条件的 13
8 Struts2标签 13
8-1,struts标签分为: 13
8-2,通用标签: 13
(1)property 13
(2)set 13
(3)bean 14
(4)include(解决中文问题很麻烦) 14
(5)param 14
(6)debug 14
8-3,控制标签: 14
8-4,UI标签: 15
8-5,$#%的区别 15
9 struts2标签的实例 15
9-1 如果value值不存在,就将default值显示页面 15
9-2 escape是否以文本形式输出 15
9-3 从值栈中获取数据存放到web元素中 15
9-4 在页面中设置对象 15
9-6 迭代器 16
9-7 用标签划页面 16
10 struts框架中用Exp 17
10-1 导入exp操作的jar包 17
10-2 导入struts2的jar包 17
10-3 配置struts.xml核心配置文件 17
10-4 配置web.xml 17
10-5 在页面上写连接跳转 17
10-6 写Action类 17
10-6-1 定义属性冰生成set和get方法 17
10-6-2 写download()方法进行页面外输出 18
11 配置error信息 19
11-1在struts.xml进行配置 19
11-2在页面中进行配置信息 19
11-2-1提交信息: 19
11-2-2接受错误信息的提示的两种方法 19
11-3 在Action中进行配置 19
11-3-1 声明属性(与页面对应)并创建set和get方法 19
11-3-2 在默认的方法中进行数据处理 19
12配置I18N步骤 20
12-1 导入struts2的jar包 20
12-2 创建转换的环境配置文件 20
12-3 创建Action类 20
12-4 配置struts.xml核心配置文件 20
12-5 配置web.xml文件 21
12-6 配置页面的连接信息 21
13 自定义拦截器 22
13-1自定义拦截器需要实现接口Interceptor 并且实现三个接口 22
13-2在struts.xml中进行配置 22
14 用拦截器防止重复提交 23
15 数据校验 23
15-1手工数据校验 23
15-1-1输入校验流程: 24
15-1-2实例:对Add()方法进行校验 24
15-2 自动数据校验(xml) 25
15-2-1对整个actionClass进行验证 25
15-2-2 对action中的某个方法校验 25
15-3系统提供的校验器如下: 26
15-4实际的例子 27
16自定义类型转换器的配置 29
16-1 配置 29
16-2例如: 29
1,truts2的作用:
1-1 MVC框架:
V(View)视图:用户界面--->HTML/JSPC(Control)控制:流程控制完成UI和java的交互--->servlet/Struts2
M(Model)模型:java模型和数据库模型-->JDBC/Hibernate
Struts2代替了Servlet完成了UI和JAVA代码的数据交互
1-2 导入struts.xml配置文件的快捷提示:
window-->preferences-->搜索catalog-->xml catalog-->addkey type=uri
location=选取struts核心包解压后的struts-2.0.dtd文件路径
key=http://struts.apache.org/dtds/struts-2.0.dtd
2,struts2的配置
2-1 配置简介
1 创建Struts2的Action类2 配置Action类
3 在页面的请求跳转到Action(配置文件)
4 在Action类中接收数据
5 将Action类中的数据传递到页面
6 在页面上接收Action传递的数据(LSTL+EL)
2-2配置Struts2的三个步骤
1 导入Struts2的jar包
commons-fileupload-1.2.2.jar -->上传下载commons-io-2.0.1.jar -->io流
commons-lang-2.5.jar
commons-logging-1.1.1.jar
freemarker-2.3.16.jar
javassist-3.11.0.GA.jar
ognl-3.0.1.jar
struts2-core-2.2.3.1.jar -->核心配置包
xwork-core-2.2.3.1.jar
2 添加核心配置文件Struts2.xml
*头文件位置
struts2-core-2.2.3.1.jar(倒数第二个)-->struts-2.0.dtd(倒数第六个)-->30-32行
*内容
<struts>
<package name="a" extends="struts-default">
<!-- 如果说执行的是Action中默认的方法,那么就不用配置method
如果是action中的具体的方法那么就配置 method="具体的方法名"-->
<action name="AddAction" class="com.softeem.action.AddAction" method="add">
<result>/success.jsp</result>
</action>
</package>
</struts>
3 配置过滤器web.xml
<!-- struts2的核心过滤器配置 -->
<filter>
<filter-name>struts2</filter-name>
<!--struts2的 核心过滤器Filter的路径 -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<!-- 拦截所有 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
3,完整的执行步骤:
index.jsp<body>
<form action="AddAction" method="post">
用户名:<input type="text" name="name"/>
密码:<input type="password" name="pass"/>
<input type="submit" value="提交"/>
</form>
</body>
--注意:当我们点击提交的时候会提交form表单到--->action="AddAction"-->
这个时候web.xml中的核心控制器会拦截所有的客户请求-->转发给struts.xml
-->在struts.xml文件中会根据传递过来的action="AddAction" 进行对比
-->然后再进入到相应的Action配置中-->根据Action的class路径跳转到Action
-->如果struts.xml文件中的Action配置没有method那么在相应的Action中执行默认的方法
如果配置了method那么在相应的Action中执行配置的method的方法
4,创建Action类
Action类作用:我们创建Action是为了接收用户请求,响应用户4-1 Action类的要求:
1 Action类的命名:**Action2 在Action类中定义无参数带有String类型返回值的方法响应用户请求
3 所有的Action类必须在struts.xml中进行配置
一个实现了xwork包中的Action接口的类,我们成为Action可以用来接受请求
4-2 创建Action类的方法
*直接创建一个类 可以作为Action使用*创建一个类实现Action接口(com.opensymphony.xwork2.Action)可以重写execute()方法
*创建一个类继承ActionSupport(因为ActionSupport实现了Action接口)
5 从Action向页面传值
5-1通过URL
在Action类中*定义属性: private String str;
*生成set和get方法
*在方法中设置值: str="哇哈哈2";
在struts.xml配置文件中: <result name="a">/list01.jsp?str={str}</result>
在页面上取值: ${str }
5-2通过request传值
在Action类中*定义属性: private List<Student> list;;
*生成set和get方法
*在方法中设置值:
方法一:
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("msg","王向新" );
方法二:
Map request = (Map)ServletActionContext.getContext().get("request");
request.put("msg", "王向新大坏蛋");
在页面上取值: ${requestScope.msg }
5-3用list
在Action类中*定义属性: private List<Student> list;;
*生成set和get方法
*在方法中设置值:
list = new ArrayList<Student>();
list.add(new Student("郭群1","男",15));
list.add(new Student("郭群2","男",16));
在页面上取值:
*导入标签: <%@taglib prefix="s" uri="/struts-tags" %>
*获取: <s:debug></s:debug>(通过一定的方法可以获取list的值)
6 获取web元素的方法
6-1 获得web元素的第一种方法:直接定义Map
定义需要的对象private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
在execute()方法中:
获取实例对象
request = (Map)ActionContext.getContext().get("request");
session = ActionContext.getContext().getSession();
application = ActionContext.getContext().getApplication();
设置属性值
request.put("r", "request范围的值");
session.put("s", "session范围的值");
application.put("a", "application范围的值");
6-2 获得web元素的第二种方法:实现三接口
实现三个接口 :RequestAware,SessionAware,ApplicationAware重写三个方法:setRequest,setSession,setApplication
定义需要的对象
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
在接口实现方法中:
获取实例对象
setRequest: this.request = request;
setSession: this.session = session;
setApplication: this.application = application;
在execute()方法中:
设置属性值
request.put("r", "request范围的值");
session.put("s", "session范围的值");
application.put("a", "application范围的值");
6-3 获得web元素的第三种方法:定义三Http对象
定义web中的HttpServletRequest,HttpSession,ServletContext类的对象然后得到对应的实例对象
定义需要的对象
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
在execute()方法中:
获取实例
request = ServletActionContext.getRequest();
session = request.getSession();
application = session.getServletContext();
设置属性
request.setAttribute("r", "request");
session.setAttribute("s", "session");
application.setAttribute("a", "application");
6-4 获得web元素的第四种方法:继承ServletRequestAware接口
继承ActionSupport类,实现ServletRequestAware接口定义需要的对象
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
在setServletRequest方法中获取对应的实例对象
this.request = request;
this.session = request.getSession();
this.application = session.getServletContext();
在execute()方法中:
设置属性值
request.setAttribute("r", "request44");
session.setAttribute("s", "session44");
application.setAttribute("a", "application44");
7 OGNL:Object-Graph Navigation Language(对象图导航语言)
* OGNL:对象图导航语言* 常用的从Action传值到JSP的方式有两中:
* 全局属性传值和web元素传值
* 全局属性(变量)传值放在值栈中
* web元素传值放在上下文中
导入struts2知道的标签
<%@taglib prefix="s" uri="/struts-tags" %>
导入c标签
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
7-1 获取普通对象和值:需要set和get方法
<s:property value="userName"/><s:property value="stu"/>
<s:property value="stu.stuNum"/>
7-2 获取对象中对象的属性值
<s:property value="stu.cla.claName"/>7-3 获取对象中的普通方法
<s:property value="stu.method()"/><s:property value="stu.add(1,8)"/>
7-4获取对象中的静态方法
(1)在配置中配置:
<constantname="struts.ognl.allowStaticMethodAccess" value="true"></constant>(2)在页面取值
<s:property value="@com.softeem.dto.Student@method1()"/><s:property value="stu.method1()"/>
(3)调用数学方法
<s:property value="@java.lang.Math@sqrt(9)"/><s:property value="@@sqrt(9)"/>
7-5 获取值栈中request的值,前面要加’#’
<s:property value="#request.userPwd"/><s:property value="#request.stu1"/>
<s:property value="#request.stu1.stuName"/>
<s:property value="#request.stu1.method()"/>
7-6 调用Action中的方法
<s:property value="method02()"/>7-7 获取list集合
<s:property value="list"/>(1)获取指定下标的list元素
<s:property value="list[1]"/><s:property value="list[1].stuNum"/>
<s:property value="list.get(0).stuNum"/>
(2)获取指定属性的集合
<s:property value="list.{stuNum}"/><s:property value="list.{stuAge}"/>
(1)获取指定属性的集合的第几个元素
<s:property value="list.{stuNum}[0]"/>
(2)遍历list集合
<s:iterator value="list" var="stu">
<s:property value="#request.stu.stuNum"/>
<s:property value="#request.stu.stuName"/>
<s:property value="#request.stu.stuAge"/>
<s:property value="#request.stu.stuSex"/><br/>
</s:iterator>
7-8 获取set集合
<s:property value="set"/><s:property value="set.{stuNum}"/>
<s:iterator var="s" value="set">
<s:property value="#request.s.stuName"/>
</s:iterator>
7-9 获取map集合
<s:property value="map"/>(1)获取根据key取值 的四种方法
<s:property value="map.get('s1')"/><s:property value="map['s1']"/>
<s:property value="map[\'s1\']"/>
<s:property value="map.s1"/>
(2)获取根据key取具体的属性值
<s:property value="map['s1'].stuName"/>
(3)回去所有key的方法
<s:property value="map.keySet()"/><s:property value="map.keys"/>
<s:iterator var="key" value="map.keySet()">
<s:property value="key"/>
</s:iterator>
(4)获取map中的值
<s:property value="map.values"/>(5)遍历具体的属性值
<s:iterator value="map.values" var="value"><s:property value="#request.value.stuNum"/>
<s:property value="#request.value.stuName"/>
<s:property value="#request.value.stuAge"/>
<s:property value="#request.value.stuSex"/><br/>
</s:iterator>
7-10 根据条件查询打印
(1)获取集合list将年龄大于20的学生打印出来
<s:property value="list.{?#this.stuAge>20}"/>(2)第一个满足条件的’^’
<s:property value="list.{^#this.stuAge>20}"/>(3)最后一个满足条件的 ‘$’
<s:property value="list.{$#this.stuAge>20}"/>(4)迭代满足条件的
<s:iterator value="list.{?#this.stuAge>20}" var="s"><s:property value="#request.s.stuNum+'--'+#request.s.stuName+'--'+#request.s.stuAge+'--'+#request.s.stuSex"/><br/>
</s:iterator>
8 Struts2标签
8-1,struts标签分为:
*通用标签*控制标签
*UI标签(展现)
8-2,通用标签:
(1)property
*property标签中的value属性默认是一个object<s:property value="username"/>表示根据在值栈中根据username取到一个对象显示
*property取值为字符串<s:property value="'哈哈'"/>
表示直接显示一个"哈哈"字符串,直接显示的字符串要加上单引号
*property的默认值:<s:property value="admin" default="管理员"/>
如果根据admin在值栈中取值没有取到,则显示默认值
*property设定HTML:<s:property value="'<hr/>'" escape="true"/>
如果没有加上escape="true",表示直接显示字符串
(2)set
*在request或者ActionContext中存入信息:<s:set var="user" value="Obj"/>默认存放在request和ActionContext中,value值为对象
*从request中取值:<s:property value="#request.user"/>
*从ActionContext中取值:<s:property value="#user"/>
默认取值空间为ActionContext
*范围的设置:<s:set name="key" value="password" scope="page"/>
(3)bean
*bean 定义bean,使用param来设定新的属性值<s:bean name="com.softeem.pojos.User" var="user1">
<s:param name="username" value="'张三'"></s:param>
</s:bean>
var表示新创建的对象的名字,如果没有var属性就不能在Context stack中找到
s:param给新创建的对象属性赋值,注意value
(4)include(解决中文问题很麻烦)
*包含静态文件:<s:include value="/test.jsp"></s:include>
*用%包含文件:
<s:set var="incPage" value="'/test.jsp''}"/>
<s:include value="incPage"></s:include>
<s:include value="#incPage"></s:include>
<s:include value="%{#incPage}"></s:include>
(5)param
(6)debug
8-3,控制标签:
if elseif elseiterator
status属性:
count遍历过的元素总数
index遍历过的索引
even当前是否偶数
odd当前是否奇数
first是否第一个元素
last是否最后一个元素
subset(截取集合的一部分)
8-4,UI标签:
theme(主题)struts.xml中控制theme,默认为xhtml,可以设置为simple/css_xhtml/ajax
<constant name="struts.ui.theme" value="css_xhtml"/>
8-5,$#%的区别
$用于i18n和struts的配置文件中#用于取ActionContext的值
%将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用
9 struts2标签的实例
9-1 如果value值不存在,就将default值显示页面
<s:property value="str" default="哈哈"/>9-2 escape是否以文本形式输出
<s:property value="str" escape="false"/>9-3 从值栈中获取数据存放到web元素中
page/request/session/application<s:set name="s" value="stu" scope="request"></s:set>
9-4 在页面中设置对象
<s:bean name="com.softeem.dto.Student" var="ssss"><s:param name="stuNum" value="'11'"/>
<s:param name="stuName" value="'aa'"/>
<s:param name="stuSex" value="'男'"/>
<s:param name="stuAge" value="22"/>
</s:bean>
取值:
<s:property value="#ssss.stuName"/>
9-5 if判断
<s:if test="stu.stuSex.equals(\"男\")">这家伙是男的</s:if>
<s:elseif test="stu.stuSex.equals(\"女\")">这家伙是女的的</s:elseif>
<s:else>这家伙不男不女</s:else>
9-6 迭代器
<s:iterator var="p1" value="list" status="statu"><s:property value="#statu.count"/>当前总的数目
<s:property value="#statu.index"/>当前的下标
<s:property value="#statu.even"/>当前是否是偶数
<!-- 判断当前元素是不是偶数行 -->
<s:if test="%{#statu.even}">
<font color="red"><s:property value="#p1.name"/></font>
</s:if>
<s:else>
<s:if test="%{#statu.first}">
<font size="10px"><s:property value="#p1.name"/></font>
</s:if>
<s:else>
<font color="green"><s:property value="#p1.name"/></font>
</s:else>
</s:else>
</s:iterator>
9-7 用标签划页面
<s:form action=""><s:textarea name="name" label="用户名"></s:textarea>
<s:password name="pass" label="密码"></s:password>
<s:radio list="{'男','女'}" name="sex" required="true" label="性别"></s:radio>
<s:select list="map2" label="部门"></s:select>
<s:checkboxlist list="{'java','php','c++','ruby'}" name="test" label="学习计划"></s:checkboxlist>
<s:textarea label="个人简介"></s:textarea>
<s:submit value="提交" labelposition="right"></s:submit>
</s:form>
10 struts框架中用Exp
10-1 导入exp操作的jar包
poi-3.9-20121203.jar10-2 导入struts2的jar包
10-3 配置struts.xml核心配置文件
<struts><package name="default" extends="struts-default">
<action name="ExcelAction" class="com.softeem.action.ExcelAction">
<!-- 固定的写法 -->
<result type="stream">
<param name="contentType">application/vnd.ms-excel</param>
<paramname="contentDisposition">attachment;filename=${fileName}</param>
<param name="inputName">excelStream</param>
</result>
</action>
</package>
</struts>
10-4 配置web.xml
10-5 在页面上写连接跳转
<a href="ExcelAction!download">导出表格</a>10-6 写Action类
10-6-1 定义属性冰生成set和get方法
private InputStream excelStream;//定义一个输入流,生成set和getprivate String fileName; //从页面接受传入的文件名称
10-6-2 写download()方法进行页面外输出
//声明一个工作簿HSSFWorkbook workbook = null;
//自定义表名
fileName=URLEncoder.encode("用户信息表.xls","utf-8");
//创建工作薄
workbook = new HSSFWorkbook();
//创建一个表单
HSSFSheet sheet = workbook.createSheet("基本信息");
//创建首行
HSSFRow row_head = sheet.createRow(0);
//设置本行每个格子的属性值
row_head.createCell(0).setCellValue("序号");
row_head.createCell(1).setCellValue("用户名");
row_head.createCell(2).setCellValue("手机号");
row_head.createCell(3).setCellValue("邮箱地址");
row_head.createCell(4).setCellValue("性别");
//创建数据行
HSSFRow row1 = sheet.createRow(1);
row1.createCell(2).setCellValue("110");
row1.createCell(3).setCellValue("110@qq.com");
row1.createCell(4).setCellValue("男");
HSSFRow row2 = sheet.createRow(2);
row2.createCell(0).setCellValue(2);
row2.createCell(1).setCellValue("王五");
row2.createCell(2).setCellValue("120");
row2.createCell(3).setCellValue("120@qq.com");
row2.createCell(4).setCellValue("男");
//创建字节数组输出流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//把字节输入流绑定到工作簿里
workbook.write(bos);
//讲输出流转换成字节数组
byte[] byt = bos.toByteArray();
//用定义的输入流输出有工作簿生成 的字节数组
excelStream = new ByteArrayInputStream(byt);
11 配置error信息
11-1在struts.xml进行配置
<action name="UserAction" class="com.softeem.action.UserAction"><result>/success.jsp</result>
<result name="error">/index.jsp</result>
</action>
11-2在页面中进行配置信息
11-2-1提交信息:
<form action="UserAction" method="post"><table>
<tr><td>usrname:</td><td><input type="text" name="name"/></td></tr>
<tr><td>usrpass:</td><td><input type="password" name="pass"/></td></tr>
<tr><td colspan="2"><input type="submit" value="提交"/></td></tr>
</table>
</form>
11-2-2接受错误信息的提示的两种方法
<s:property value="errors.error[0]"/><s:fielderror name="error"></s:fielderror>
11-3 在Action中进行配置
11-3-1 声明属性(与页面对应)并创建set和get方法
private String name;private String pass;
11-3-2 在默认的方法中进行数据处理
if("admin".equals(name)){if("123".equals(pass)){
return "success";
}else{
this.addFieldError("error","密码错误");
}
}else{
this.addFieldError("error","用户不存在");
}
//返回error进行接收
return "error";
12配置I18N步骤
12-1 导入struts2的jar包
12-2 创建转换的环境配置文件
英文: app_en_US.properties日文: app_ja_JP.properties
中文: app_zh_CN.properties
12-3 创建Action类
I18NAction(仅仅是为了进行换语言二设置的action类)UserAction(提交数据的处理action)
12-4 配置struts.xml核心配置文件
配置i18n:<constant name="struts.custom.i18n.resources" value="app"></constant>
对配置的环境变量进行解析,并在结果集合中调用
<package name="p" extends="struts-default">
<action name="I18NAction" class="com.softeem.action.I18NAction">
<result>/index.jsp</result>
</action>
</package>
在网页进行跳转的路径是UserAction时进行调用
<package name="p2" extends="p">
<action name="UserAction" class="com.softeem.action.UserAction">
<result>/index.jsp</result>
</action>
</package>
12-5 配置web.xml文件
<filter><filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
12-6 配置页面的连接信息
连接进行设置显示语言<a href="I18NAction?request_locale=zh_CN">中文</a>
<a href="I18NAction?request_locale=en_US">英文</a>
<a href="I18NAction?request_locale=ja_JP">日文</a>
获取环境变量中的值
<s:property value="getText(\'userlogin\')"/>获取 userlogin 的对应的语言的值
<s:property value="getText(\"user\")"/>获取 user 的对应的语言的值
提交数据的时候进行跳转
<form action="UserAction" method="post">
13 自定义拦截器
13-1自定义拦截器需要实现接口Interceptor 并且实现三个接口
destroy():销毁的时候执行init():初始化时候执行
intercept(ActionInvocation arg0):拦截时执行的方法
13-2在struts.xml中进行配置
拦截器和过滤器的区别?1过滤器在首次请求的时候会执行,拦截器在任意的时候都可以执行
2过滤器所有的请求(servlet/jsp)都会过滤,拦截器可以精确到任何一个action
引入指定的拦截器 配置其他拦截器之前需要引入struts2提供的默认拦截器defaultStack否则当前的拦截器会将默认的覆盖
配置整个package的拦截器
<package name="struts2" extends="struts-default">
<interceptors>
<interceptor name="MyInterceoter" class="com.softeem.interceptor.MyInterceoter"></interceptor>
</interceptors>
<action name="testAction" class="com.softeem.action.TestAction">
<result>/main.jsp</result>
<!-- 声明配置默认 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 声明配置自定义 -->
<interceptor-ref name="MyInterceoter"></interceptor-ref>
</action>
</package>
配置拦截器栈
<!-- 自动启动 -->
<constant name="struts.devMode" value="true"></constant>
<package name="struts2" extends="struts-default">
<!-- 自定义一个拦截器 ,在哪个action需要拦截,就在该action进行配置-->
<interceptors>
<interceptor name="ProInterceptor" class="com.softeem.intercepter.ProInterceptor"></interceptor>
<!-- 拦截器栈 -->
<interceptor-stack name="MyStack">
<interceptor-ref name="ProInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="mainAction" class="com.softeem.action.TestAction">
<!-- 引用拦截器栈 -->
<interceptor-ref name="MyStack"></interceptor-ref>
<result>/main.jsp</result>
</action>
</package>
14 用拦截器防止重复提交
<struts><!-- 自动启动 -->
<constant name="struts.devMode" value="true"></constant>
<package name="struts2" extends="struts-default">
<action name="testAction" class="com.softeem.action.TestAction">
<!-- 配置拦截器 默认拦截器-->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 拦截重复提交-->
<interceptor-ref name="token"></interceptor-ref>
<result>/main.jsp</result>
<!--重复提交跳转到指定的页面-->
<result name="invalid.token">/resubmit.jsp</result>
</action>
</package>
</struts>
15 数据校验
15-1手工数据校验
手工验证:指的是在对应的action里面通过validate方法对这个action里面的属性进行校验validate方法是重写,它是在ValidateAble接口中定义的所以我们这个action要实现ValidateAble接口才能完成校验但是ActionSupport已经实现了ValidateAble接口,所以我们创建的action只要继承了ActionSupport,就可以重写validate
对action中所有的方法进行校验:
@Override
public void validate() { }
对action中指定的方法进行校验(Xxx为需要校验的方法名)
public void validateXxx() {
}
15-1-1输入校验流程:
1.类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性2.如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext;conversionError拦截器将异常信息封装到fieldError里,不管类型转换是否出现异常,都会进入到第3步
3.系统通过反射,先调用action中的validateXxx()方法,Xxx为action中的方法名
4.再调用action中的validate方法
5.如果系统中的fieldErrors存在错误信息,系统自动将请求转发至名为input的result中,如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法
15-1-2实例:对Add()方法进行校验
public void validateAdd() {if(user.getUname() == null || "".equals(user.getUname())){
this.addFieldError("uname", "请输入用户名");
}
if(user.getUphone() != null || !"".equals(user.getUphone())){
if(!Pattern.matches("^1[358]\\d{9}$", user.getUphone())){
this.addFieldError("uphone", "输入的手机格式不正确");
}
}else{
this.addFieldError("uphone", "请输入手机号");
}
if(user.getUemail() != null || !"".equals(user.getUemail())){
if(!Pattern.matches("^\\S+@\\S+.(com|COM)$", user.getUemail())){
this.addFieldError("uemail", "输入的邮箱不正确");
}
}else{
this.addFieldError("uemail", "请输入邮箱");
}
}
15-2 自动数据校验(xml)
自动验证:使用xwork里面提供的验证,通过配置文件对action的属性进行验证使用基于xml配置的方式实现输入校验时,Action也需要继承ActionSupport,并且提供校验文件,校验文件和action类应该在同一个包中,文件命名格式为:ActionClassName-validation.xml,其中ActionClassName为action的类名,-validation是固定写法例子:
15-2-1对整个actionClass进行验证
例:com.softeem.action.UserAction用于验证的配置文件命名:UserAction-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空</message>
</field-validator>
</field>
</validators>
<field>指定action中需要校验的属性
<field-validator>指定校验器type为校验器的类型;
<param>中name值指定先调用String类的trim()方法去掉前后空格再来校验
<message>未校验失败后的提示信息
15-2-2 对action中的某个方法校验
如果只需要对action中的某个方法执行输入校验,那么校验文件命名应该为ActionClassName-ActionName-validation.xml,其中ActionName为struts.xml中action的名称,例如:<action name="user_*"class="com.softeem.action.UserAction" method={1}>
<result>/success.jsp</result>
<result name="input">/fail.jsp</result>
</action>
UserAction.java中的方法
public String add(){}
public String update(){}
若要对add()方法实施验证,校验文件的取名为:
UserAction-user_add-validation.xml
若要对update()方法实施验证,校验文件的取名为:
UserAction-user_update-validation.xml
15-3系统提供的校验器如下:
required | 必填校验器,要求field的值不能为null |
requiredstring | 必填字符串校验器,要求field的值不能为null,并且长度大于0,默认情况下会对字符串去前后空格 |
stringlength | 字符串长度校验器,要求field的值必须在指定的范围内(minLength,maxLength),否则校验失败,trim参数指定校验field之前是否去除字符串前后的空格 |
minLength | 参数指定最小长度 |
maxLength | 参数指定最大长度 |
regex | 正则表达式校验器,检查被校验的field是否匹配一个正则表达式 |
expression | 参数指定正则表达式 |
caseSensitive | 参数指定进行正则表达式匹配时,是否区分大小写,默认值为true |
int | 整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值 |
double | 双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,min指定最小值,max指定最大值 |
fieldexpression | 字段OGNL表达式校验器,要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过 |
email | 邮件地址校验器,要求如果field的值非空,则必须是合法的邮件地址 |
url | 网址校验器,要求如果field的值非空,则必须是合法的url地址 |
date | 日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值 |
conversion | 转换校验器,指定在类型转换失败时,提示的错误信息 |
visitor | 用于校验action中的复合属性,它指定一个校验文件用于校验复合属性中的属性 |
expression | OGNL表达式校验器,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过,该校验器不可用在字段校验器风格的配置中 |
15-4实际的例子
<validators><!-- 命名方式:UserAction-UserAction_add-validation.xml
action的名称-struts对action的配置name的值-validation.xml -->
<!-- 需要被验证的字段 -->
<field name="user.uname">
<!-- 指定校验器 -->
<!-- 校验是否为空 -->
<field-validator type="requiredstring">
<message>请输入用户名</message>
</field-validator>
<!-- 一个属性字段可以指定对个校验器 -->
<!-- 校验长度 -->
<field-validator type="stringlength">
<param name="minLength">1</param>
<param name="maxLength">6</param>
<message>用户名的长度必须在4-16之间</message>
</field-validator>
</field>
<!-- 验证邮箱 -->
<field name="user.uemail">
<field-validator type="requiredstring">
<message>请输入邮箱地址</message>
</field-validator>
<!-- 邮箱的格式 -->
<field-validator type="email">
<message>输入邮箱格式不正确</message>
</field-validator>
</field>
<!-- 对网址进行校验(要http://) -->
<field name="user.url">
<field-validator type="requiredstring">
<message>请输入个人主页</message>
</field-validator>
<field-validator type="url">
<message>输入个人主页不正确</message>
</field-validator>
</field>
<field name="user.uphone">
<field-validator type="requiredstring">
<message>请输入手机号</message>
</field-validator>
<!-- 正则表达式 -->
<field-validator type="regex">
<param name="expression"><![CDATA[^1[358]\d{9}$]]></param>
<message>输入手机号不正确</message>
</field-validator>
</field>
<!-- 校验日期 -->
<field name="user.birth">
<!-- 必填校验器,无类型规定 -->
<field-validator type="required">
<message>请输入日期</message>
</field-validator>
<field-validator type="date">
<param name="max">2013-11-24</param>
<message>日期不能大于${max}</message>
</field-validator>
</field>
<!-- 校验密码 -->
<field name="user.upass">
<field-validator type="requiredstring">
<message>请输入密码</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">1</param>
<param name="maxLength">6</param>
<message>密码的长度必须在1-6之间</message>
</field-validator>
</field>
<!-- 校验重复密码 -->
<field name="reupass">
<field-validator type="requiredstring">
<message>请输入再次输入密码</message>
</field-validator>
<field-validator type="fieldexpression">
<param name="expression"><![CDATA[reupass==user.upass]]></param>
<message>两次密码不一致</message>
</field-validator>
</field>
</validators>
16自定义类型转换器的配置
16-1 配置
* 当我们转换类继承的是DefaultTypeConverter,或者实现implements TypeConverter接口* 需要重写一个方法:convertValue(Object value, Class toType)
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
* 配置指定级别的属性文件(Action级别,包级别,项目级别)
类型转换类的三种配置形式(局部转换器,全局转换器):
*actin级别:
配置文件的名字:action-conversion.properties
内部配置:ation对应的属性名=转换类的路径
配置文件的存放位置:和action位置相同
说明:当用户访问这个action中这个属性的时候才调用类型转换类
*pojo级别:
配置文件的名字:pojo-conversion.properties
配置文件的存放位置:和pojo的位置相同
内部配置:pojo对应的属性名=类型转换类的路径
说明:当用户访问任何action,只要提交了这个pojo中的这个属性的时候就会调用类型转换类
*src级别:
配置文件的名字:xwork-conversion.properties
配置文件的存放位置:直接存放在src下
内部配置:属性类型(+包名)=类型转换类的路径
说明:用户访问任何action,只要提交了对应类型的属性的时候就会调用类型转换类
16-2例如:
(1)Java类的配置信息public class DateTimeConvert extends DefaultTypeConverter{
@Override
public Object convertValue(Object value, Class toType) {
//页面端传来的每一个控件的数据都是字符串数组
String[] s = (String[])value;
if(toType==java.util.Date.class){
String str = s[0];
//定义自己的日期输出格式,页面输出格式yyyyMMdd,但是系统自带的日期转换就被覆盖了
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parseObject(str);
} catch (ParseException e) {
e.printStackTrace();
}
}else if(toType==String.class){
return s[0];
}
return super.convertValue(value, toType);
}
}
(2)环境配置
命 名: UserAction-conversion.properties
参数信息: hiredate=com.softeem.convert.DateTimeConvert
相关文章推荐
- Spring的配置以及详解
- 用Java进行AES256-ECB-PKCS7Padding加密
- Java转型(向上或向下转型)
- java多线程
- Java Lock Condition
- bj Java初学2015-07-24
- JAVA时间类
- 无Maven不项目---使用Eclipse快速搭建Maven项目
- Spring(八)编码剖析@Resource注解的实现原理
- Myeclipse如何自动创建hibernate
- 认识JAVA
- 最奇葩的java错误,让我深深不能忘记。
- 算法(第四版)学习笔记之java实现归并排序
- Java内存区域与模拟内存区域异常
- 使用myeclipse与SQLyog怎么建立简单的登陆页面
- java音乐播放之IO流处理
- 使用Sax解析器对XML文件进行解析并转化为JavaBean
- 使用记事本开发第一个java程序
- 利用递归算法获取文件夹下所有文件(包括子文件)
- Java基础-- IO