轻量级JavaEE企业应用实战(十七)

基于Annotation的输入校验

虽然这些Annotation实质上也属于Struts2的零配置特性,但是这些并不是Convention插件提供的,而是由XWork提供的,因此不需要Convention插件

使用Annotation修饰Action里各属性对应的setter方法

public class RegistAction extends ActionSupport {
    private String name;
    //省略其他属性

    @RequiredStringValidator(key="name.required", message="")
    @RegexFieldValidator(expression="\\w{4,25}", key="name.regex",
    message="")
    public void setName(String name) {
        this.name = name
    }
    public void getName() {
        return name;
    }
}

手动完成输入校验

1.重写validate()方法:会校验所有的处理逻辑

public class RegistAction extends ActionSupport {
    private String name;
    ...

    public void validate() {
        ...
    }
}

2.重写validateXxx方法
如果想输入校验只针对某个逻辑,仅仅校验某个处理方法,重写validate方法显然不够,validate无法准确知道需要校验某个处理方法

public class RegistAction extends ActionSupport {
    private String name;
    ...

    public String regist() {
        return SUCCESS;
    }
    public void validateRegist() {
        if(!name.contains("1")) {
            addFieldError("user", "错误信息");
        }
    }
}

无论用户向Action的哪个方法发送请求,Action内的validate方法都会被调用;如果该Action内还有该方法对应的validateXxx方法,则会在validate方法前调用。

Struts2的输入校验步骤

1.类型转换器负责对字符串的请求参数执行类型转换,并将这些值设置成Action的属性值
2.在执行类型转换过程中可能出现异常,如果出现,则将异常信息保存到A ctionContext中,conversionError拦截器负责将其封装到FieldError里,然后执行下一步;如果没有异常,则直接下一步
3.使用Struts2应用中所配置的校验器进行输入校验
4.通过反射调用validateXxx()方法,即处理用户请求的处理逻辑所对应的方法
5.调用Action类里的validate()方法
6.如果上述步骤都未出现FieldError,则调用Action里处理用户请求的处理方法;如果出现,则转入input逻辑视图所指定的视图资源

使用Struts2控制文件上传

为了能上传文件,我们必须将表单的method设置为post;将enctype设置为multipart/form-data,只有这种情况下,浏览器才会把用户选择文件的二进制数据发送给服务器
Struts2的文件上传还没来得及使用Servlet 3.0 API,因此还需要Common-FileLoad和COS等文件上传组件
Struts2不会自己去处理multipart/form-data的请求,它需要调用其他上传框架来解析二进制请求数据。

在struts.properties配置文件:
struts.multipart.parser=cos //指定使用COS的文件上传解析器
struts.multipart.parser=pell //使用pell的文件上传解析器
struts.multipart.parser-jakarta //默认使用jakarta的Common-fileload~

<s:form action="uploadPro" enctype="multipart/form-data">
    <s:file name="upload" label="选择文件" /><br />
    <s:submit value="上传" />
</s:form>

public class UploadAction extends ActionSupport {
    private String title; //请求参数属性
    private File upload; //上传文件域的属性
    private String uploadContentType; //上传文件类型的属性
    private String uploadFileName; //上传文件名称
    ...  //省略get和set

    private String savePath; //struts.xml配置的属性
    public void setSavePath(String value) {
        this.savePath = value;
    }
    public String getSavePath() throws Exception {
        return ServletActionContext.getServletContext()
        .getRealPath("/WEB-INF/" + savePath);
    }

    @Override
    public String execute() throws Exception {
        FileOutputStream fos = new FileOutputStream(
            getSavePath() + "\\" + getUploadFileName());
        FileInputStream fis = new FileInputStream(getUpload());
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len == fis.read(buffer) > 0)) {
            fos.write(buffer, 0, len)
        };
        return SUCCESS;
    }
}

手动实现文件过滤

大部分时候,WEB应用不允许浏览者自由上传,尤其是不能上传可执行文件,防止病毒;通常可以上传图片、压缩文件等;除此之外,还需要限制文件的大小,因此必须在上传中进行文件过滤;

1.在Action中定义一个专用于文件过滤的方法,方法命名任意,该方法的逻辑就是判断上传文件的类型是否为允许类型

过滤文件类型
public String filterType(String[] types) {
    //获取希望上传的文件类型
    String fileType = getUploadContentType();
    for(String type : types) {
        if(type.equals(fileType)){
            return null;
        }
    }
    return ERROR;
}

2.为了程序可以动态配置允许上传的文件列表,为该Action增加了一个allowTypes属性,该属性列出所有允许上传的文件类型。

private String allowTypes;
//省略get和set

3.利用输入校验判断用户输入的文件是否符合要求;如果不符合,则加入FieldError中

public void validate() {
    String filterResult = filterType(getAllowTypes().split(","));
    if(filterResult != null) {
        addFieldError("upload", "错误信息");
    }
}

validate方法添加了FieldError,这样将自动返回input逻辑视图名;只有当文件类型是允许上传时,才会调用真正的上传逻辑;

配置文件
<action name="uploadPro" class="com.action.UploadAction">
    <param name="allowTypes">image/png, image/gif, image/jpg</param>
</action>

<s:fielderror />

拦截器实现文件过滤

Struts2提供了一个文件上传的拦截器,通过配置该拦截器可以实现文件过滤;
配置fileUpload拦截器,需指定两个参数:
allowedTypes //允许上传的文件类型,多个类型之间以英文逗号隔开
maximumsize //允许上传文件的大小,单位是字节

<action name="uploadPro" class="com.action.UploadAction">
    <interceptor-ref name="fileUpload">
        <param name="allowedTypes">image/png,image/gif</param>
        <param name="maximumSize">2000</param>
    </interceptor-ref>
    <interceptor-ref name="defaultStack">
</action>


interceptor-ref的配置问题:
defaultStack是系统默认使用的defaultStack;引入自己配置的拦截器后,会覆盖掉系统默认的default;如果需要继续起作用,需要手动引入;

<interceptors> 
    <interceptor name="myInterceptor"class="com.interceptor.
        MyInterceptor" />
    <interceptor-stack name="myInterceptorStack"> 
        <interceptor-ref name="myInterceptor" />
        <interceptor-ref name="defaultStack" />
    </interceptor-stack> 
</interceptors> 
注意两个interceptor-ref的顺序, 顺序不同, 执行效果也不同: 
先配置的先执行/后配置的先退出(先进后出)

使用Struts2控制文件下载

使用超链接下载时,如果文件名为中文,则会导致下载失败;所以应用程序需要在用户下载之前进行进一步检查,比如判断是否有权限等,就需要Struts2控制下载;

public class FileDownloadAction extends ActionSupport {
    private String inputPath;
    ..

    public InputStream getTargetFile() throws Exception {
        return ServletActionContext.getServletContext().
            getResourceAsStream(inputPath);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值