您的位置:首页 > 编程语言 > Java开发

【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】

2015-09-09 09:18 736 查看
一、struts2文件上传

  1.上传文件的时候要求必须使得表单的enctype属性设置为multipart/form-data,把它的method属性设置为post

  2.上传单个文件的时候需要在Action类中添加属性并提供每个属性的标准get/set方法:

private File uploadImage;//上传的文件
private String uploadImageContentType;//上传的文件类型
private String uploadImageFileName;//上传文件的名字
......
每个属性的get/set方法略。
......


    定义这些属性的时候必须严格按照要求来,否则不能被识别。upload是表单中name属性的名字。

  3.上传文件的一般步骤:

ServletContext sc=ServletActionContext.getServletContext();
String path=sc.getRealPath("/04_fileupload/uploadfiles");
//获取目标文件夹的真实路径

File desc=new File(path,uploadImageFileName);//拼接目标文件名称和目标文件夹
FileUtils.copyFile(uploadImage, desc);//使用FileUtils类完成复制,实际上是完成了上传功能。

uploadImage.delete();//删除临时文件
//这一步在有些版本中并不是必须的,在一些高级版本中会自动删除临时文件,但是在一些低级版本中的myeclipse中并不会自动删除临时文件,所以为了保险起见,还是手动删除最好。

uploadImage实际上是临时文件。


  4.上传成功之后的文件应当到tomcat服务器下相应的工程目录下找,而不应当到myeclipse下的对应目录找。

二、struts2上传文件之参数配置

  1.设置上传文件的总大小

<constant name="struts.multipart.maxSize" value="1024"></constant>


    这里的1024单位是字节。

  2.设置允许上传的文件类型、文件后缀名、单个文件上传的大小。

    (1)在struts-default.xml文件中,声明了一个文件上传的拦截器

<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>


    (2)在给出的拦截器类中,能够找到相关的配置参数:

/* <!-- START SNIPPET: parameters -->
* <p/>
* <ul>
* <p/>
* <li>maximumSize (optional) - the maximum size (in bytes) that the interceptor will allow a file reference to be set
* on the action. Note, this is <b>not</b> related to the various properties found in struts.properties.
* Default to approximately 2MB.</li>
* <p/>
* <li>allowedTypes (optional) - a comma separated list of content types (ie: text/html) that the interceptor will allow
* a file reference to be set on the action. If none is specified allow all types to be uploaded.</li>
* <p/>
* <li>allowedExtensions (optional) - a comma separated list of file extensions (ie: .html) that the interceptor will allow
* a file reference to be set on the action. If none is specified allow all extensions to be uploaded.</li>
* </ul>
* <p/>
* <p/>
* <!-- END SNIPPET: parameters -->
*/


    (3)配制方法:在struts.xml文件中,或者在其它自定义struts.xml配置文件中的action标签节点下:

       <interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">1024000</param>
<param name="fileUpload.allowedExtensions">.txt</param>
<param name="fileUpload.allowedTypes">text/plain</param>
</interceptor-ref>


<%@ page isELIgnored="false" language="java" import="java.util.*" pageEncoding="utf-8"
contentType="text/html; charset=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Insert title here !</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>

<body>
<%
session.setAttribute("user", "张三");
%>
</body>
</html>


/05_interceptor/login.jsp
    (5)测试结果:

        首先访问query.jsp

        


        单击链接之后:

        


        这时候,直接访问login.jsp文件,然后再次访问query.jsp文件,并单击链接,这时候就会提示已经验证成功

        


    (6)注意事项

        在拦截器中不能调用invoke方法,如果调用了该方法,测试就会失败。

五、struts2手动验证

  1.struts2验证方法有两种:

    (1)手工编写代码实现(基本验证)

    (2)基于XML配置文件的方式(验证框架)

  2.验证的原理:ActionSupport类实现了Validateable接口,想要进行验证需要实现Validateable接口,所以我们只需要继承ActionSupport类就可以了。

    使用的方法是Validateable接口定义的validate方法。当Action初始化的时候,会自动调用该方法,所以,之前的动作和配置都不需要改动,只需要重写validate方法即可。在validate方法中进行一些判断,比如用户名是否已经存在、密码长度是否正确等,如果有错误,使用addFieldError方法添加错误类型即可。

  3.小练习:

    Action类:

package com.kdyzm.validate;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.opensymphony.xwork2.ActionSupport;

public class ValidateAction extends ActionSupport{
private static final long serialVersionUID = -3130043637195994925L;
private String username;
private String password;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String add() throws Exception{
return "success";
}
@Override
public void validate() {
if(username==null||"".equals(username))
this.addFieldError("error", "用户名不能为空!");
if(password==null||"".equals(password))
this.addFieldError("error", "密码不能为空!");
String regex="^[0-9a-zA-Z]{6,12}$";
Pattern p=Pattern.compile(regex);
Matcher m=p.matcher(password);
boolean result=m.matches();
if(result==false)
this.addFieldError("error", "密码长度为6-12位!");
}
public String login()throws Exception{
System.out.println("业务逻辑处理!");
return "success";
}
}


    其余配置不做解释,直接看结果:

    


    由于密码长度不合法,所以会提示以下的错误:

    


  4.对action的指定方法进行验证:重点

    如果仅仅想对Action的某个指定方法进行验证,则只需要这样做就可以了:

    如果Action中的指定方法名为:public String add(),则校验方法的方法名为:public void validateAdd(),这样通过反射机制就能够比较轻松的完成这个验证了。

    所以在Action中如果有这种以validate开头的方法,一定是某种校验方法。

    上述小练习中将validate方法改成validateLogin方法也可以,并不影响任何东西。

  5.各个方法执行的顺序:

    先执行set方法将变量获取到;然后执行validateXXX方法,校验是否合法;最后执行login等业务逻辑处理的方法。如果校验方法报错了,则最后的login等处理业务逻辑的方法将不能运行。

  6.执行addFieldError方法的底层代码是什么?

public synchronized void addFieldError(String fieldName, String errorMessage) {
final Map<String, List<String>> errors = internalGetFieldErrors();
List<String> thisFieldErrors = errors.get(fieldName);

if (thisFieldErrors == null) {
thisFieldErrors = new ArrayList<String>();
errors.put(fieldName, thisFieldErrors);
}

thisFieldErrors.add(errorMessage);
}


  7.实际上的输入校验流程是什么?

    (1)类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性

    (2)如果在执行类型转换的过程中出现了异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息封装到fieldErrors中,然后执行第三步。如果类型转换没有出现异常,则直接进入第三步。

    (3)系统通过反射技术调用action中的validateXXX()方法,Xxxx是方法名。

    (4)调用action中的validate方法。

    (5)经过上面的4步,如果系统中的fieldErrors中存在错误信息(存放错误信息的集合的size()>0),系统就会就会自动将请求转发到名称为input的视图。如果系统中的fieldErrors没有任何错误信息,系统就会执行action中的处理方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: