标签:
6-4 获得web元素的第四种方法:继承ServletRequestAware接口 9
7 OGNL:Object-Graph Navigation Language(对象图导航语言) 9
9-1 如果value值不存在,就将default值显示页面 15
10-6-2 写download()方法进行页面外输出 18
11-3-1 声明属性(与页面对应)并创建set和get方法 19
13-1自定义拦截器需要实现接口Interceptor 并且实现三个接口 22
V(View)视图:用户界面--->HTML/JSP
C(Control)控制:流程控制完成UI和java的交互--->servlet/Struts2
M(Model)模型:java模型和数据库模型-->JDBC/Hibernate
Struts2代替了Servlet完成了UI和JAVA代码的数据交互
window-->preferences-->搜索catalog-->xml catalog-->add
key type=uri
location=选取struts核心包解压后的struts-2.0.dtd文件路径
key=http://struts.apache.org/dtds/struts-2.0.dtd
1 创建Struts2的Action类
2 配置Action类
3 在页面的请求跳转到Action(配置文件)
4 在Action类中接收数据
5 将Action类中的数据传递到页面
6 在页面上接收Action传递的数据(LSTL+EL)
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
*头文件位置
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>
<!-- 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>
index.jsp
<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的方法
Action类作用:我们创建Action是为了接收用户请求,响应用户
1 Action类的命名:**Action
2 在Action类中定义无参数带有String类型返回值的方法响应用户请求
3 所有的Action类必须在struts.xml中进行配置
一个实现了xwork包中的Action接口的类,我们成为Action可以用来接受请求
*直接创建一个类 可以作为Action使用
*创建一个类实现Action接口(com.opensymphony.xwork2.Action)可以重写execute()方法
*创建一个类继承ActionSupport(因为ActionSupport实现了Action接口)
在Action类中
*定义属性: private String str;
*生成set和get方法
*在方法中设置值: str="哇哈哈2";
在struts.xml配置文件中: <result name="a">/list01.jsp?str={str}</result>
在页面上取值: ${str }
在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 }
在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的值)
定义需要的对象
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范围的值");
实现三个接口 :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范围的值");
定义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");
继承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");
* OGNL:对象图导航语言
* 常用的从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="userName"/>
<s:property value="stu"/>
<s:property value="stu.stuNum"/>
<s:property value="stu.cla.claName"/>
<s:property value="stu.method()"/>
<s:property value="stu.add(1,8)"/>
<constantname="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<s:property value="@com.softeem.dto.Student@method1()"/>
<s:property value="stu.method1()"/>
<s:property value="@java.lang.Math@sqrt(9)"/>
<s:property value="@@sqrt(9)"/>
<s:property value="#request.userPwd"/>
<s:property value="#request.stu1"/>
<s:property value="#request.stu1.stuName"/>
<s:property value="#request.stu1.method()"/>
<s:property value="method02()"/>
<s:property value="list"/>
<s:property value="list[1]"/>
<s:property value="list[1].stuNum"/>
<s:property value="list.get(0).stuNum"/>
<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>
<s:property value="set"/>
<s:property value="set.{stuNum}"/>
<s:iterator var="s" value="set">
<s:property value="#request.s.stuName"/>
</s:iterator>
<s:property value="map"/>
<s:property value="map.get(‘s1‘)"/>
<s:property value="map[‘s1‘]"/>
<s:property value="map[\‘s1\‘]"/>
<s:property value="map.s1"/>
<s:property value="map[‘s1‘].stuName"/>
<s:property value="map.keySet()"/>
<s:property value="map.keys"/>
<s:iterator var="key" value="map.keySet()">
<s:property value="key"/>
</s:iterator>
<s:property value="map.values"/>
<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>
<s:property value="list.{?#this.stuAge>20}"/>
<s:property value="list.{^#this.stuAge>20}"/>
<s:property value="list.{$#this.stuAge>20}"/>
<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>
*通用标签
*控制标签
*UI标签(展现)
*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",表示直接显示字符串
*在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"/>
*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
*包含静态文件:
<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>
if elseif else
iterator
status属性:
count遍历过的元素总数
index遍历过的索引
even当前是否偶数
odd当前是否奇数
first是否第一个元素
last是否最后一个元素
subset(截取集合的一部分)
theme(主题)
struts.xml中控制theme,默认为xhtml,可以设置为simple/css_xhtml/ajax
<constant name="struts.ui.theme" value="css_xhtml"/>
$用于i18n和struts的配置文件中
#用于取ActionContext的值
%将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用
<s:property value="str" default="哈哈"/>
<s:property value="str" escape="false"/>
page/request/session/application
<s:set name="s" value="stu" scope="request"></s:set>
<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>
<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>
<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>
poi-3.9-20121203.jar
<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>
<a href="ExcelAction!download">导出表格</a>
private InputStream excelStream;//定义一个输入流,生成set和get
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);
<action name="UserAction" class="com.softeem.action.UserAction">
<result>/success.jsp</result>
<result name="error">/index.jsp</result>
</action>
<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>
<s:property value="errors.error[0]"/>
<s:fielderror name="error"></s:fielderror>
private String name;
private String pass;
if("admin".equals(name)){
if("123".equals(pass)){
return "success";
}else{
this.addFieldError("error","密码错误");
}
}else{
this.addFieldError("error","用户不存在");
}
//返回error进行接收
return "error";
英文: app_en_US.properties
日文: app_ja_JP.properties
中文: app_zh_CN.properties
I18NAction(仅仅是为了进行换语言二设置的action类)
UserAction(提交数据的处理action)
配置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>
<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>
连接进行设置显示语言
<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">
destroy():销毁的时候执行
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>
<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>
手工验证:指的是在对应的action里面通过validate方法对这个action里面的属性进行校验
validate方法是重写,它是在ValidateAble接口中定义的所以我们这个action要实现ValidateAble接口才能完成校验但是ActionSupport已经实现了ValidateAble接口,所以我们创建的action只要继承了ActionSupport,就可以重写validate
对action中所有的方法进行校验:
@Override
public void validate() { }
对action中指定的方法进行校验(Xxx为需要校验的方法名)
public void validateXxx() {
}
1.类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性
2.如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext;conversionError拦截器将异常信息封装到fieldError里,不管类型转换是否出现异常,都会进入到第3步
3.系统通过反射,先调用action中的validateXxx()方法,Xxx为action中的方法名
4.再调用action中的validate方法
5.如果系统中的fieldErrors存在错误信息,系统自动将请求转发至名为input的result中,如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法
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", "请输入邮箱");
}
}
自动验证:使用xwork里面提供的验证,通过配置文件对action的属性进行验证使用基于xml配置的方式实现输入校验时,Action也需要继承ActionSupport,并且提供校验文件,校验文件和action类应该在同一个包中,文件命名格式为:ActionClassName-validation.xml,其中ActionClassName为action的类名,-validation是固定写法
例子:
例: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>未校验失败后的提示信息
如果只需要对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
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时校验通过,否则不通过 |
|
邮件地址校验器,要求如果field的值非空,则必须是合法的邮件地址 |
url |
网址校验器,要求如果field的值非空,则必须是合法的url地址 |
date |
日期校验器,要求field的日期值必须在指定范围内,min指定最小值,max指定最大值 |
conversion |
转换校验器,指定在类型转换失败时,提示的错误信息 |
visitor |
用于校验action中的复合属性,它指定一个校验文件用于校验复合属性中的属性 |
expression |
OGNL表达式校验器,expression参数指定ognl表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过,该校验器不可用在字段校验器风格的配置中 |
<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>
* 当我们转换类继承的是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,只要提交了对应类型的属性的时候就会调用类型转换类
(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
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/yzjyhp/article/details/47045853