Struts2总结
4109 点击·0 回帖
![]() | ![]() | |
![]() | Struts2 1. 搭建Struts2的开发环境: 1) 导入相应的jar包;6个 2) 编写struts的配置文件;struts.xml 3) struts2在web中的启动配置;web.xml 2. 第一个struts2应用 3. actin属性的注入message是action中的变量 <paramname="message">注入参数的值</param> 4. 编写自定义类型转换器:建立自定义局部类型转换器,处理日期类型,通过继承DefaultTypeConverter,(推荐使用StrutsTypeConverter,它继承了DefaultTypeConverter)实现自己的DateTypeConverter,并且在action所在的包下创建HelloWorldAction3-conversion.properties文件;在文件中编写对应关系:birthday=com.lcq.type.converter.DateTypeConverter 将转换的属性和转换器进行绑定。如果是全局,类型转换器就要将properties文件放置在src的根目录下,同时修改文件的名称为:xwork-conversion.properties,修改里边的内容为:要转换的变量的类型=转换器的名称, 转换器的编写: [java] /** * 建立自定义类型转换器,处理日期类型,通过继承DefaultTypeConverter,实现自己的DateTypeConverter * @author lcq * */ public class DateTypeConverter extends DefaultTypeConverter { @Override public Object convertValue(Map<String, Object> context, Objectvalue, Class toType) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); try { if (toType == Date.class) { String[] params = (String[]) value; return dateFormat.parse(params[0]); } else if (toType == String.class) { Date date = (Date) value; return dateFormat.format(date); } } catch (ParseException e) { // TODO Auto-generatedcatch block e.printStackTrace(); } return super.convertValue(context, value, toType); } } 例如定义的action为: [java] package com.lcq.action; import java.util.Date; public class HelloWorldAction3 { private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String addUI(){ return "success"; } public String execute(){ return "success"; } } 5. 访问和添加request/session/application属性,并在页面进行打印输出 //从struts2封装的ActionContext中获取request/session/application [java] ActionContext ctx = ActionContext.getContext(); ctx.getApplication().put("app", "application scope"); ctx.getSession().put("session", "sessionscope"); ctx.put("request", "request scope"); jsp中: [java] ${applicationScope.app }<br> ${sessionScope.session }<br> ${requestScope.request }<br> 6. 得到request/session/application对象: 在action中利用ServletActionContext.getxxxx()方法得到 7. 文件上传实现: 1)上传页面:upload.jsp [java] <form enctype="multipart/form-data" action="${pageContext.request.contextPath}/employee/upload.action" method="post"> file:<input type="file"name="image"> <input type="submit" value="upload"> </form> 2) xml中的配置 [html] <action name="upload" class="com.lcq.action.FileUpLoadAction" method="execute"> <result name="success">/WEB-INF/page/uploadMessage.jsp</result> </action> 3)Action中的方法 [java] public String execute() throws Exception{ //构建真实的存放路径 String realPath = ServletActionContext.getServletContext().getRealPath("/image"); System.out.println(realPath); if(image != null){ File savefile = new File(new File(realPath),imageFileName); if(!savefile.getParentFile().exists()){ savefile.getParentFile().mkdirs(); } FileUtils.copyFile(image, savefile); ActionContext.getContext().put("message", "上传成功"); } return "success"; } 4)结果页面输出上传信息 [html] <body> message } </body> 8. 多文件上传只要修改为:同时在action中将相应的参数变为数组即可 [html] <form enctype="multipart/form-data" action="${pageContext.request.contextPath}/employee/upload.action" method="post"> file1:<input type="file"name="image"><br> file2:<input type="file"name="image"><br> file3:<input type="file"name="image"><br> <input type="submit" value="upload"> action中 [java] private File[] image;// 定义上传文件的文件属性 private String[] imageFileName;// 得到文件的名称 ........ ........ ........ public String execute() throws Exception { // 构建真实的存放路径 StringrealPath = ServletActionContext.getServletContext().getRealPath( "/image"); System.out.println(realPath); if (image != null) { for (int i = 0; i < image.length; i++) { Filesavefile = new File(new File(realPath), imageFileName); if(!savefile.getParentFile().exists()) { savefile.getParentFile().mkdirs(); } FileUtils.copyFile(image, savefile); } ActionContext.getContext().put("message", "上传成功"); } return "success"; } 9. 编写自定义拦截器: 1) 继承自interceptor接口来实现。 [java] public class PermissionInterceptor implements Interceptor { public void destroy() { } public void init() { } public String intercept(ActionInvocation invocation) throws Exception { Object user = ActionContext.getContext().getSession().get("user"); if(user!=null) return invocation.invoke(); //如果user不为null,代表用户已经登录,允许执行action中的方法 ActionContext.getContext().put("message", "你没有权限执行该操作"); return "success"; } } 2) 在xml中的配置为: [html] <interceptors> <interceptor name="permission" class="com.lcq.Interceptor.PermissionInterceptor" /> <interceptor-stack name="permissionStack"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="permission" /> </interceptor-stack> </interceptors> <global-results> <result name="success">/WEB-INF/page/message.jsp</result> </global-results> <action name="userAction" class="com.lcq.action.UserAction" method="execute"> <interceptor-ref name="permissionStack" /> </action> 10. 对action的所有方法进行输入校验 1) 要进行验证的内容: [html] <body> <s:fielderror/> <form action="${pageContext.request.contextPath}//person/manage_save" method="post"> 用户名:<input type="text"name="username">用户名不能为空<br> 手机号:<input type="text"name="mobile">不能为空,并且要符合手机号的格式1,3/5/8,后面是9个数字<br> <input type="submit" value="提 交"> </form> </body> 2) 在action中继承ActionSupport重写validate()方法: [java] @Override public void validate() {//对action的所有方法进行校验 if(this.username == null || "".equals(this.username.trim())){ this.addFieldError("username", "用户名不能为空"); } if(this.mobile == null || "".equals(this.mobile.trim())){ this.addFieldError("mobile", "手机号不能为空"); }else{ if(!Pattern.compile("^1[358]\\d{9}{1}quot;).matcher(this.mobile).matches()){ this.addFieldError("mobile", "手机号格式不对"); } } } 3) 在validate方法中将错误信息放在错误集合中,转到input页面,所以在xml中的配置是: [html] <struts> <package name="person" namespace="/person" extends="struts-default"> <action name="manage_*" class="com.lcq.action.PersonAction" method="{1}"> <result name="input">/index.jsp</result> <result name="message">/WEB-INF/page/message.jsp</result> </action> </package> </struts> 4) 如果只是对个别的方法进行校验则只要改正validate方法为validateXxxx()就行,其中Xxxx是要校验的方法的名称。 [java] public void validateUpdate() {//对action的update()方法进行校验 if(this.username == null || "".equals(this.username.trim())){ this.addFieldError("username", "用户名不能为空"); } if(this.mobile == null || "".equals(this.mobile.trim())){ this.addFieldError("mobile", "手机号不能为空"); }else{ if(!Pattern.compile("^1[358]\\d{9}{1}quot;).matcher(this.mobile).matches()){ this.addFieldError("mobile", "手机号格式不对"); } } } 11. 基于xml的输入校验 1) 只要在要校验的action所在包下建立相应的action的xml验证文件即可,在xml中编写: 2) 如果只是对action中的指定方法进行校验则只要修改xml的文件名即可,修改为PersonAction-person-manage_update-validation.xml则该文件只对action中的update方法进行校验 [html] <validators> <field name="username"> <field-validator type="requiredstring"> <param name="trim">true</param> <message>用户名不能为空!</message> </field-validator> </field> <field name="mobile"> <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> </validators> 12. struts2对异常的处理机制,要编写自己的异常处理类,在struts.xml中进行配置。 13. OGNL表达式语言。www.atcpu.com 14. EL表达式:${username}可以访问值栈(action。。。)对象中的所有属性,是因为struts2对HttpServletRequest对象进行了封装,但是不能访问:request、application、session、parameters、attr等对象。如果要访问这些对象,要使用#语法进行访问,比如:#application.username或者#application[‘username’],特别注意在EL表达式中只能使用值栈中属性。 15. ognl表达式进行迭代和投影。并且能够使用集合。 16. 可以不用ognl表达式,直接用jstl和el结合来代替使用。 17. 利用token标签防止表单的重复提交问题 1)在jsp页面的表单中添加<s:token></s:token>; 2)在对应的action中添加拦截器和不跳转对应的页面: <interceptor-ref name="defaultStack" /> <interceptor-ref name="token" /> <result name="invalid.token">/updatePerson.jsp</result> | |
![]() | ![]() |