Struts 的文件上传和下载

文件上传

struts 2 并不能自己对二进制流的文件数据去请求,它还是需要哦借助于其他的上传框架去处理,它只是在这些上传的框架基础上进行了封装。

我们解压struts 的核心jar包,找到下面这个文件:default.properties

Struts 2框架有两个核心配置文件,其中struts.xml文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等。除此之外,Struts 2框架还包含struts.properties文件,该文件定义了Struts 2框架的大量属性,开发者可以通过改变这些属性来满足应用的需求。

大家可以自己看看,其中有关于文件上传的配置上传的框架。

这里写图片描述

Struts 为我们提供了这3中上传文件的框架,jakarta是默认的(采用默认的是不需要重写Struts.properties),如果要换这3种种的其他一种,我们需要重新写一个Struts.properties。存放到src,这样编译之后,文件会在web-inf/classes下,这样Struts就不会加载默认的原先它自己文件,而是加载你自己指定的,这点和Strut.xml很类似,以及模板文件。

指定了上传文件的框架,还需要导入相应的jar包。

这里写图片描述

完成上面准备工作,下面我们就要开始进行文件的上传了。

  <s:form action="upload" method="post" enctype="multipart/form-data">
  <s:textfield name="filetitle" label="文件标题"/>
  <s:file label="文件选择" name="upload" /><!--该控件用于生成文件的上传域  -->
  <s:submit value="上传"/>
  </s:form>

注意:上传文件的form必须要有

method="post" enctype="multipart/form-data">
    private String filetitle;//这个是文件title
    private File  upload;//封装的文件内容
    private String uploadContentType;//这个属性是封住文件的类型
    private String uploadFileName;//这个属性是封装文件的名字
    //上面这三个封装属性是规定死的,你用struts,就必须这样写
    private String savePath;//这个属性可以设置文件存放的位置,它的值是可以动态设置的,在配置文件上传的action中。此外,你还需要在web工程创建你设置的对应的文件夹。

    public String getSavePath() {
        return ServletActionContext.getServletContext().getRealPath("/WEB-INF"+savePath);
    }

    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }

    public String getFiletitle() {
        return filetitle;
    }

    public void setFiletitle(String filetitle) {
        this.filetitle = filetitle;
    }

    public File getUpload() {
        return upload;
    }

    public void setUpload(File upload) {
        this.upload = upload;
    }

    public String getUploadContentType() {
        return uploadContentType;
    }

    public void setUploadContentType(String uploadContentType) {
        this.uploadContentType = uploadContentType;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    public void setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
    }

    @Override
    public String execute() throws Exception {
        // TODO Auto-generated method stub
        System.out.println(upload.getName());
        //upload_296043e8_a58d_4e59_8565_3bfdf68a1f2f_00000001.tmp
        FileOutputStream fos = new FileOutputStream(getSavePath()+"\\"+getUploadFileName());
        FileInputStream fis = new FileInputStream(getUpload());
        byte[] buffer = new byte[1024];
        int len =0;
        while((len=fis.read(buffer))!=-1){//读1024个字节,返回是真正读到的个数
            fos.write(buffer,0,len);//将每次读到的保存到数组中,然后一次写进去
        }
        return SUCCESS;
    }

文件上传的action配置

 <action name="upload" class="com.example.test.action.UploadAction" >
    <result name="success">/show.jsp</result>
        <param name="savePath">/uploadFiles</param>//动态设置action的savePath属性值。
 </action>

//显示上传的图片

    <img src="./uploadFiles/logo.jpg"/>
    <img src="<s:property value="'uploadFiles/'+uploadFileName"/>"/>

注意上传的文件在tomcat的服务端才有,不是你上传之后,工程下就有对应的文件的。

手动实现文件的过滤

web是不允许用户任意上传应用的,特别是可执行文件,可能会含有病毒。

我们可以在action的校验方法中,实现对文件的过滤。

对文件类型、大小的过滤

在前面的代码的基础上,添加如下内容:

    private String allowTypes;//并且提供对应的set、get方法
    public String checkFile(){
        String[] types = getAllowTypes().split(",");
        for(String type:types){
            if(type.equals(uploadContentType)&&upload.length()<2000){
                return null;
            }
        }
        return ERROR;
    }

    @Override
    public void validate() {
        // TODO Auto-generated method stub
        if(checkFile()!=null){
            addFieldError("error", "文件上传类型有误");
        }
    }
  <result name="input">/error.jsp</result>//配置错误的视图
  <param name="allowTypes">image/png,image/jpeg</param>//这个name你可以随便定义,只要与action中的一致就好,允许的类型值,可以参考httpcontenttype的

对文件大小限制,主要就是同upload是对文件封装,可以通过length去获取文件的大小,大小是以字节B为单位的。

使用拦截器实现文件的过滤

我们在原来的代码基础上,注释校验那个方法,在struts的配置文件中,做如下添加:

    <interceptor-ref name="fileUpload">
        <param name="allowTypes">image/png,image/jpeg</param>
        <param name="maximumSize">2000</param>
        </interceptor-ref>
        <interceptor-ref name="defaultStack"/>

便可轻松实现文件类型、大小的过滤。

注意:这里的两个参数的name是不可以修改,是struts规定好的。

文件输出错误提示

编写国际资源文件,存放在src下,同时在struts.xml配置一下。

struts.messages.error.content.type.not.allowed=\u6587\u4EF6\u7C7B\u578B\u4E0D\u5141\u8BB8  
struts.messages.error.file.too.large=\u4E0A\u4F20\u6587\u4EF6\u592A\u5927

第一个常量是文件类型不匹配
第二个常量是文件大小不匹配
struts.messages.error.uploading 该常量是文件上传未知的错,既不是文件类型不允许,也不是文件大小。

是先检查文件大小是否合格。

文件上传常量配置
<constant name="struts.multipart.saveDir" value="d:"/> struts 上传文件是使用指定的临时文件夹
<constant name="struts.multipart.maxSize" value="20"/> 指定上传表单最大字节数
struts 文件下载

你可以使用超链接去下载文件,也可以通过表单。

定义action

public class DownAction extends ActionSupport {
    //该参数是用定义服务器资源的路径
    //在这是通过依赖注入的方式,在struts.xml动态设置
    private String inputPath;

    public void setInputPath(String inputPath) {
        this.inputPath = inputPath;
    }

    //定义一个返回inputstream 方法 
    //该方法是作为下载文件的入口
    //inputName 的配置的值,就是该方法的名字,去除get,首字母小写

    public InputStream getTargetFile() throws Exception{
        InputStream in =  ServletActionContext.getServletContext().getResourceAsStream(inputPath);
        return in;
    }
    @Override
    public String execute() throws Exception {
        // TODO Auto-generated method stub
        InputStream in = getTargetFile();
        OutputStream out = new FileOutputStream(new File("d:\\test.jpg"));
        int size = 0;
        byte[] buffer = new byte[1024];
        while((size=in.read(buffer))!=-1){
            out.write(buffer, 0, size);
        }
        out.flush();
        out.close();

        return super.execute();
    }
}

注意:虽然获取流的那个方法不是重写,是你自己定义getXxxxx,尽量还是取名字右意义的。

<action  name="down" class="com.example.test.action.DownAction">
   <param   name="inputPath">WEB-INF/image/woman1.jpg</param>//注意action下的参数,应该在action下面
   <result name="success" type="stream">//注意返回的结果集是一个流,并不是真正的视图
   //这边的参数是result结果集的参数
   <param name="contentType">image/jpg</param>//下载的文件类型,和互联网标准的mime一致
   <param name="inputName">targetFile</param>//对应获取流的方法
   <param name="contentDisposition">attachment;filename="womanlaoqiang.jpg"</param>
   <param name="bufferSize">2048</param>//文件缓冲区大小
   </result>
 </action>

contentDisposition 是用来进行文件下载处理方式,以及下载文件的名字。

处理方式包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件,默认是内联,会强行打开。

这里写图片描述

界面

 <s:form method="post" action="down">
 <s:submit value="下载"/>
 </s:form> 
 //表单、超链接下载均可以
 <a href="down">下载</a> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值