本文主要包括以下内容
- 文件上传,多文件上传
- 自定义拦截器
- 用户输入验证
- 国际化
文件上传
- 将头设置为enctype=”multipart/form-data”
<body><form action="${pageContext.request.contextPath}/upload/upload1.action" method="post" enctype="multipart/form-data">文件:<input type="file" name="image"/><br/><input type="submit" value="上传"/></form></body>
- 写接收处理的方法,有两种,一种是自己实现IO流,一种是使用FileUtils
package cn.itcast.action;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;import javax.servlet.ServletContext;import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;public class UploadAction1 extends ActionSupport implements Serializable {private File image;//对应的就是表单中文件上传的那个输入域的名称,Struts2框架会封装成File类型的private String imageFileName;// 上传输入域FileName 文件名private String imageContentType;// 上传文件的MIME类型public File getImage() {return image;}public void setImage(File image) {this.image = image;}public String getImageFileName() {return imageFileName;}public void setImageFileName(String imageFileName) {this.imageFileName = imageFileName;}public String getImageContentType() {return imageContentType;}public void setImageContentType(String imageContentType) {this.imageContentType = imageContentType;}public String execute(){System.out.println(imageContentType);try {//处理实际的上传代码//找到存储文件的真实路径System.out.println(imageFileName);ServletContext sc = ServletActionContext.getServletContext();String storePath = sc.getRealPath("/files");//构建输入输出流/*OutputStream out = new FileOutputStream(storePath+"\\"+imageFileName);InputStream in = new FileInputStream(image);byte b[] = new byte[1024];int len = -1;while((len=in.read(b))!=-1){out.write(b, 0, len);}out.close();in.close();*/FileUtils.copyFile(image, new File(storePath,imageFileName));ActionContext.getContext().put("message", "上传成功!");return SUCCESS;} catch (Exception e) {e.printStackTrace();return ERROR;}}
}
多文件上传实现
package cn.itcast.action;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;import javax.servlet.ServletContext;import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;public class UploadAction2 extends ActionSupport implements Serializable {private File[] images;//对应的就是表单中文件上传的那个输入域的名称,Struts2框架会封装成File类型的private String[] imagesFileName;// 上传输入域FileName 文件名private String[] imagesContentType;// 上传文件的MIME类型public File[] getImages() {return images;}public void setImages(File[] images) {this.images = images;}public String[] getImagesFileName() {return imagesFileName;}public void setImagesFileName(String[] imagesFileName) {this.imagesFileName = imagesFileName;}public String[] getImagesContentType() {return imagesContentType;}public void setImagesContentType(String[] imagesContentType) {this.imagesContentType = imagesContentType;}public String execute(){try {if(images!=null&&images.length>0){ServletContext sc = ServletActionContext.getServletContext();String storePath = sc.getRealPath("/files");for(int i=0;i<images.length;i++)FileUtils.copyFile(images[i], new File(storePath,imagesFileName[i]));}ActionContext.getContext().put("message", "上传成功!");return SUCCESS;} catch (Exception e) {e.printStackTrace();return ERROR;}}
}
自定义拦截器
1、编写一个类,实现 com.opensymphony.xwork2.interceptor.Interceptor
2、主要实现public String intercept(ActionInvocation invocation) throws Exception{}方法
该方法的返回值就相当于动作的返回值如果调用了String result = invocation.invoke();得到了动作类的返回的值。public String intercept(ActionInvocation invocation) throws Exception {//判断用户是否登录HttpSession session = ServletActionContext.getRequest().getSession();Object obj = session.getAttribute("user");if(obj==null){return "login";}else{return invocation.invoke();//调用动作方法}}
3、拦截器定义好后,一定要在配置文件中进行注册:
<interceptors> 只是定义拦截器,并没有起作用 <interceptor name="permissionInterceptor" class="cn.itcast.interceptor.PermissionInterceptor"></interceptor></interceptors>
4、配置文件中的动作,要通过
<interceptor-ref name="permissionInterceptor"></interceptor-ref>使用该拦截器
注意:一旦动作中使用了自定义的拦截器,那么默认的就不起作用了。一般应该采用如下的做法:
<interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="permissionInterceptor"></interceptor-ref>
多个动作类都要使用的话,可以通过package来进行组合。
<package name="mypackage" extends="struts-default"><interceptors> <!-- 只是定义拦截器,并没有起作用 --><interceptor name="permissionInterceptor" class="cn.itcast.interceptor.PermissionInterceptor"></interceptor><interceptor-stack name="mydefaultstack"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="permissionInterceptor"></interceptor-ref></interceptor-stack></interceptors><!-- 配置全局错误结果 :范围只是本包--><global-results><result type="dispatcher" name="error">/customer/error.jsp</result></global-results></package><package name="interceptor" extends="mypackage"><action name="visitIndex" class="cn.itcast.action.VisitAction" method="execute"><interceptor-ref name="mydefaultstack"></interceptor-ref><result name="success">/index.jsp</result><result name="login">/login.jsp</result></action></package>
用户输入验证
1、编程方式:
动作类中的所有方法进行验证:步骤:a、动作类继承ActionSupportb、覆盖调用public void validate()方法c、在validate方法中,编写不符合要求的代码判断,并调用父类的addFieldError(String fieldName,String errorMessage)如果fieldError(存放错误信息的Map)有任何的元素,就是验证不通过,动作方法不会执行。Struts2框架会返回到name=input的resultd、在name=input指定的页面上使用struts2的标签显示错误信息。<s:fielderror/>动作类中指定的方法进行验证:编写步骤与上面相同验证方法书写有要求:public void validateXxx() Xxx代表的是要验证的动作方法名,其中要把动作方法名的首字母变为大写。
2、基于XML配置文件的方式:
动作类中的所有方法进行验证:在动作类的包中,建立一个名称为:动作简单类名-validation.xml ,比如要验证的动作类名是UserAction UserAction-validation.xml内容如下:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC"-//OpenSymphony Group//XWork Validator 1.0.3//EN""http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd"><validators><field name="username"><!-- 内置验证器都是定义好的,在xwork-core.jar com.opensymphony.xwork2.validator.validators包中的default.xml文件中 --><field-validator type="requiredstring"><!-- 不能为null或者""字符串,默认会去掉前后的空格 --><message>用户名不能为空</message></field-validator></field></validators>动作类中指定的方法进行验证:配置文件的名称书写有一定要求。动作类名-动作名(配置文件中的动作名)-validation.xmlUserAction-user_add-validation.xml
3、自定义基于XML的验证器
a、编写一个类,继承FieldValidatorSupport类。b、在public void validate(Object object)编写你的验证逻辑不符合要求的就向fieldErrors中放消息c、一定注册你的验证器才能使用在WEB-INF/classes目录下建立一个名称为validators.xml的配置文件,内容如下:<validators><validator name="strongpassword" class="cn.itcast.validators.StrongPasswordValidator"/></validators>d、日后就可以像使用Struts2提供的16个验证器方式去使用了。
实例
package cn.itcast.validators;import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;public class StrongPasswordValidator extends FieldValidatorSupport {public void validate(Object object) throws ValidationException {String fieldName = getFieldName();//取得字段名String filedValue = (String)getFieldValue(fieldName, object);//取得用户输入的当前字段的值if(!isPasswordStrong(filedValue)){addFieldError(fieldName, object);}}private static final String GROUP1 = "abcdefghijklmnopqrstuvwxyz";private static final String GROUP2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";private static final String GROUP3 = "0123456789";protected boolean isPasswordStrong(String password) {boolean ok1 = false;boolean ok2 = false;boolean ok3 = false;int length = password.length();for(int i=0;i<length;i++){if(ok1&&ok2&&ok3)break;String character = password.substring(i,i+1);if(GROUP1.contains(character)){ok1 = true;continue;}if(GROUP2.contains(character)){ok2 = true;continue;}if(GROUP3.contains(character)){ok3 = true;continue;}}return ok1&&ok2&&ok3;}
}
Struts2对于i18n的支持
全局资源文件/包范围资源文件/动作类的资源文件全局资源文件:放到WEB-INF/classes目录下包范围资源文件:服务于Java类中的包下的动作类的。 取名:package_语言_国家.properties动作类的资源文件:放到与动作类相同的包中取名:动作类名_语言_国家.properties
jsp中如何读取国际化的消息
<body><s:i18n name="itcast"><s:text name="welcome"><s:param>yr</s:param><s:param>study</s:param></s:text></s:i18n><s:i18n name="cn/itcast/action/package"><s:text name="welcome"><s:param>wxy</s:param><s:param>find boy friend</s:param></s:text></s:i18n></body>
动作类中如何读取国际化的消息
public class I18nAction extends ActionSupport implements Serializable {public String execute(){//取出资源文件中的welcome的值
// String value = getText("welcome");String value = getText("welcome", new String[]{"朱巧玲","学习"});//封装到请求范围中ActionContext.getContext().put("message", value);return SUCCESS;}
}