Struts2之文件上传与下载

0x02 写在终极

到此甘休作者能体会理解的MVVM框架的法力算是基本完毕了,遇到的急需尤其点儿,才能也不行点儿,能想到的就那多少个了,欢迎回复斟酌,也欢迎加小编QQ16141860沟通。在此以前平昔是在TestArea那一个库房里展开测试,今后以此小框架整理了下,放到AyxMVVM仓Curry了。今后稍微想法还不太成熟,使用进程中遭受难点也会随时勘误,未来就都修改到AyxMVVM中了,TestArea中的MyMVVM不再维护了。其余给仓库起名真是件小事,干脆统一都用Ayx+XXX的不二法门,那样既简单重新的概率又越发小。Ayx是本人名字拼音的首字母,想想看以拼音A开头的姓氏之少就能体会通晓大约不会产出重复了。最后,三月十八日看了微软的金秋出品公布会后信教充值成功。对UWP十三分感兴趣,下一步打算攻读一下。

import org.apache.struts2.ServletActionContext;

用正视注入的情势计划ViewModel并登记新闻

星罗棋布目录:

MVVM形式解析和在WPF中的达成(一)MVVM格局简介

MVVM形式解析和在WPF中的完结(二)数据绑定

MVVM格局解析和在WPF中的达成(三)命令绑定

MVVM情势解析和在WPF中的完结(四)事件绑定

MVVM形式解析和在WPF中的完毕(五)View和ViewModel的通讯 

MVVM情势解析和在WPF中的完结(六)用正视注入的形式配置ViewModel并登记消息

    public void setFilename(String filename) {

MVVM形式解析和在WPF中的实现(六)

            public void setFileFileName(String fileFileName) {

0x01 ViewModel和MessageManager的重视性注入

运用静态类ViewModelManager来当作IoC
Container。往IoC
Container里注册依赖关系一般有二种艺术,一种是将借助关系以某种格局(例如xml)保存在外部,一种是在程序中注册到多个列表里。我使用第2种做法,因为相比较简单:)

次第在运维时使用ViewModelManager.Register将依靠关系注册到ViewModelManager中,View在构造函数中调用ViewModelManager.SetViewModel(this);来设置View的DataContext并经过重视的消息注册器注册音讯,音信注册器能够为空,代表View不接受音讯。它们的涉及如图所示:

 图片 1

亟待验证的有八个地点:

3个是View和ViewModel的照应关系。一般的话二个View对应着一种ViewModel,那样注册起来是没难题的。但这几个并不相对,理论上来说贰个View能够将DataContext设置为随意ViewModel,若是多少个View能够安装三种ViewModel该怎么着处理吧,那时候能够在ViewModelManager注册时添加Token属性,然后用SetViewModel(this,token)的办法钦命特定的ViewModel为DataContext。

另1个是音讯注册的界定。因为相似的话ViewModel都以和绑定的View通讯。所以暗中认可景况下,新闻注册到独门三个MessageManager中,这么些MessageManager保存ViewModel中,ViewModel使用那几个MessageManager发送音信,发送的音信由View接收。但倘使需求和别的View通讯,要求把音讯注册到MessageManager.Default中,那一个指标是static的,要达到规定的标准那些指标只要在View设置ViewMode时那般来SetViewModel(this,isGlobalMsg:true)即可。假如ViewModel又想和绑定的View单独通讯,有时候还亟需和别的View通讯,能够在新闻注册器中登记时将须求单独通讯的消息设置三个Group,ViewModel在殡葬音信时加三个Group过滤一下即可。1个Group能够精晓为新闻的独立一个坦途。

顺带一提,好吧只是顺带一提的是,在给View注入ViewModel时,顺便把ViewModel的UIDispatcher属性设置为了View的Dispatcher,固然我不清楚那有啥样用。但这么在ViewModel中利用UIDispatcher时即为相关的View的Dispatcher。如若要动用MainWindow的Dispatcher能够因而DispatcherHelper.Dispatcher恐怕App.Current.MainWindow.Dispatcher获得。

 

0x00 最初的想法

此次首要研商下给View钦定ViewModel的业务。一般的话给View内定ViewModel常用的艺术有二种,一种是在View的后台代码中写DataContext
= new
ViewModel(),还有一种是在XAML中钦命View的DataContext。那三种艺术都使得View对ViewModel爆发了借助,那种状态下得以考虑用正视注入的办法使裁撤View对ViewModel的直接注重。依赖注入一般的话能够透过构造函数注入、通过安装属性注入,那三种格局对于View来说都不对劲。由此能够使用IoC
Container,让View主动去取得相应的ViewModel。

实际给View钦命3个ViewModel并不属于频仍的操作,而且改起来也很简单,费半天劲搞个依靠注入确实不太至于。就如上篇作品中废了半天劲搞了个View和ViewModel的通讯一样,用到的概率比较小,而且也有其余办法化解,纵然这种方式并不适合MVVM方式。然则View除了依靠ViewModel之外对音信注册器也是会发生依赖的,而且某类别型的View一般的话都凭借固定类型的ViewModel和音讯注册器,由此能够二回注入四个依靠,那样一般就值了,至少作者认为是值了,所以有了ViewModelManager那一个类。

            filename = URLEncoder.encode(filename, “utf-8”);

0x03 关于AyxMVVM

https://github.com/durow/AyxMVVM

——Struts2汉语件上传细节

                return fileFileName;

                return NONE;

二 、Struts中的文件下载
    通过<result type=”stream”>来完成。

 

    在FileUploadInterceptor中有如下代码:

 

        System.out.println(“进行下载…”);

    struts.messages.upload.error.SizeLimitExceededException=Request
exceeded allowed size limit! Max size allowed is: {0} but request was:
{1}!

        </action>

        假诺要同时上传八个文本,那么具有”file”的name属性值必须一律。 

 

            public String execute() throws Exception {

             * String contentTypeName = inputName + “ContentType”;

    然后一贯在execute()方法中return SUCCESS即可。

            /*

                <param
name=”fileUpload.allowedExtensions”>txt,mp3,doc</param>

 

    struts.messages.error.uploading=Error uploading: {0}
    // 上传文件过大:{0} “{1}” “{2}” {3}

            }

    }

        protected Long maximumSize;    // 表示每一个上传文件的高低

 

    // 上传错误:{0}

    // 要下载文件的称谓

                <param
name=”contentDisposition”>attachment;filename=${downloadFileName}</param>

 

DownloadAction:

    struts.messages.error.file.too.large=The file is to large to be
uploaded: {0} “{1}” “{2}” {3}
    // 上传文件不容许:{0} “{1}” “{2}” {3}

import java.net.URLEncoder;

    下载的供给
    两个头、一个流
        *   Content-Type:表示传递给客户端文件的MIME类型。
            >  
通过文件名称调用ServletContext的getMimeType()方法取得MIME类型。
        *   Content-Disposition:
            >  
它的默许值为inline,表示在浏览器窗口中开辟(当打不开时会弹框)。
            >  
attachment;filename=xxx:表示项目为附件,并在弹框的界面中展示下载的文本名。
        *   流:要下载的文书数量。
            >   本身new
一个输入流即可,然后经过IOUtils完结流的数量写入。

}

    <package name=”default” namespace=”/”
extends=”struts-default”>

    }

        filename = new String(filename.getBytes(“iso-8859-1”), “utf-8”);

③ 、多文本上传时各类文件大小控制以及上传文件的扩充名限制

package com.wyc.action;

        // 直接return SUCCESS即可。 

             * String inputName = (String)
fileParameterNames.nextElement();

    例如:
        <action name=”upload” class=”com.wyc.action.UploadAction”>

            public String getFileFileName() {

    // 获取下载文件MIME类型

    多文本上传时,要将Action中的属性表明为List集合大概数组:
        private List<File> file;
        private List<String> fileContentType;
        private List<String> fileFileName;
    然后在excuete()方法中展开操作。

            <result name=”input”>/upload.jsp</result>

 

            public void setFile(File file) {

        FileInputStream fis = new FileInputStream(“f:/upload/” +
filename);

     * 获取下载文件名称

            </result>

五 、示例代码:

                <param
name=”contentType”>${contentType}</param>

            private File file; //
上传文件,名称必须与表单页面中的name值相同

    页面中:

 

            // 火狐浏览器

import java.util.Base64;

            filename = “=?utf-8?B?” +
base64Encoder.encode(filename.getBytes(“utf-8”)) + “?=”;

 

    struts.messages.error.content.type.not.allowed=Content-Type not
allowed: {0} “{1}” “{2}” {3}
    // 上传文件扩充名差别意:{0} “{1}” “{2}” {3}

    private String filename;

                System.out.println(“上传文件的称号:” + fileFileName);
 

            <!– 调用当前Action中的getContentType()方法,获得其回来值
–>

② 、服务器端
    使用commons-fileupload。
    *   DiskFileItemFactory
    *   ServletFileUpload
    *   FileItem

     */

            }

        </action>

        return fis;

私下认可意况下,Struts2框架使用commons-fileupload组件进行上传操作,所以供给导入commons-fileupload.jar。

            BASE64Encoder base64Encoder = new BASE64Encoder();

        <form action=”${pageContext.request.contextPath }/upload”
method=”post” enctype=”multipart/form-data”>

                System.out.println(“上传文件的体系:” +
fileContentType);

            // IE浏览器

            <param name=”inputStream”></param>

            // 别的浏览器

    {3}:上传文件的品种(对struts.messages.error.file.too.large是上传文件的轻重缓急)

    钦点stream结果类型 须要钦赐四个inputName参数,该参数钦命三个输入流,提供被下载文件的输入。

            }

public class DownloadAction extends ActionSupport {

import com.opensymphony.xwork2.ActionSupport;

            </interceptor-ref>

        protected Set<String> allowedExtensionsSet =
Collections.emptySet();    // 表示上传文件的壮大名

叁 、文件乱码难题
    超链接下载的公文是普通话名,会油然则生乱码情形,服务器会出错。

        return filename;

    消除措施:
        在getInputStream()方法中丰裕:
            filename = new String(filename.getBytes(“iso-8859-1”),
“utf-8”);

1、客户端
    *   method=”post”
    *   <input type=”file” name=”xx” />
    *   encType=”multipart/form-data”

    public String getDownloadFileName() throws
UnsupportedEncodingException{

<!DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts
Configuration 2.3//EN”
http://struts.apache.org/dtds/struts-2.3.dtd“>

                <param name=”inputStream”></param>

 

    }

    在StreamResult类中有五个属性:
        *   protected String contentType = “text/plain”;    //
该属性用于安装下载文件的MIME类型
        *   protected String contentDisposition = “inline”;    //
该属性用于安装举办下载操作以及下载文件的称号
        *   protected InputStream inputStream;    //
该属性用于读取要下载的文本

                return fileContentType;

    </package>

   
当中contentType、contentDisposition、inputStream能够在struts.xml文件中开始展览配备:

Struts2应用了一个interceptor协理大家做到文件上传操作:
    <interceptor name=”fileUpload”
class=”org.apache.struts2.interceptor.FileUploadInterceptor”/>

     * 消除浏览器差别难题

import java.io.FileNotFoundException;

——Struts2文件上传

        return filename;

一 、控制上传文件大小
    在default.properties文件中定义了上传文件的大大小小:
        struts.multipart.maxSize=2097152 上传文件大小默许2M
    超出文件大小时,跳转到input视图,通过<s:actionerror
/>展现错误消息。

    public String getContentType(){

                // 完毕文件上传

        </action>

 

        } else {

                <!–
${inputStream}表示调用当前Action的getInputStream()方法,是ognl表明式,如若不安装,则暗许”inputStream”,可查阅StreamResult源码 –>

    # dedicated messages used to handle various problems with file
upload – check {@link
    JakartaMultiPartRequest#parse(HttpServletRequest, String)}

    struts.messages.error.file.extension.not.allowed=File extension not
allowed: {0} “{1}” “{2}” {3}

    要是采用pell、cos实行理文件件上传,必须导入其jar包。

    在struts-default.xml文件中得以找到stream结果视图:
        <result-type name=”stream”
class=”org.apache.struts2.dispatcher.StreamResult”/>

——使用commons-fileupload组件上传

 

            }

兑现公文上传操作:

肆 、在Struts第22中学暗中同意使用的是commons-fileupload实行文件上传
    在default.properties文件中:
        # struts.multipart.parser=cos
        # struts.multipart.parser=pell
        struts.multipart.parser=jakarta    //
jakarta代表apache开源项目
    能够修改暗许上传格局。

肆 、动态获取下载文件名和文件类型
    在struts.xml文件中动用ognl表明式动态获取。

    {1}:上传文件的真实名称

        <result type=”stream”>

            private String fileContentType; //
上传文件类型,名称格式:name + ContentType

            }

    假若针对fileUpload实行参数设置,当出错时,在页面通过<s:filedError
/>回显错误新闻。      

贰 、修改彰显错误新闻
   
私下认可在页面中展现的错误音讯是英文的,能够在Struts2骨干包下的struts-message.properties文件中找到预订义上传错误新闻,在国际化文件中通过覆盖对应key展现错误音讯:

        }

                <!–
${inputStream}表示调用当前Action的getInputStream()方法,假若不设置,则暗中同意”inputStream”,可查阅StreamResult源码
–>

        return
ServletActionContext.getServletContext().getMimeType(filename);

            <interceptor-ref name=”defaultStack”>
                <!– 对fileUpload下的allowedExtension属性赋值 –> 

 

            <!–
${inputStream}表示调用当前Action的getInputStream()方法,假设不设置,则暗中同意”inputStream”,可查看StreamResult源码
–>

        </result>

    public String execute() throws Exception {

            @Override

            <result type=”stream”>

                this.file = file;

=============================================================================

                this.fileContentType = fileContentType;

</struts>

                this.fileFileName = fileFileName;

    inputStream能够在Action获得,在Action类中定义一个措施:
        public InputStream getInputStream() throw FileNotFound {
            FileInputStream fis = new FileInputStream(“F;/upload/” +
filename);
            return fis;
        }

     
 使用安插文件设置上传文件总大小,对具有上传form有效,假诺只想对当前form进行安装,能够设置fileUplpad拦截器属性:
        *  
maximumSize:上传文件的最大尺寸(以字节为单位),暗中同意为2M。
        *   allowedTypes:允许上传的文件类型,各个型之间以逗号分隔。
        *  
allowedExtendsions:允许上传文件增加名,各扩张名以内以逗号分隔。

    @Override

import sun.misc.BASE64Encoder;

             */

    struts.messages.upload.error.IOException=Error uploading: {0}!

            filename = URLEncoder.encode(filename, “utf-8”);

                //
使用FileUtils的copyFile()方法将文件的输入流输出到内定地方

<?xml version=”1.0″ encoding=”UTF-8″?>

 

时间:2017-1-11 15:47

        return SUCCESS;

 

             *
在FileUploadInterceptor中有如下三行代码,所以起名必须要标准

            }

            public String getFileContentType() {

                return file;

    /*

    Action中:
        public class UploadAction extends ActionSupport {

            }

            <input type=”submit” value=”上传” />


                <!–
调用当前Action中的getContentType()方法,获得其归来值 –>

                <param
name=”inputStream”>${inputStream}</param>

            <result type=”stream”>

    <constant name=”struts.multipart.maxSize” value=”86170804″/>

<struts>

        </form>

            public void setFileContentType(String fileContentType) {

        } else if (agent.contains(“FireFox”)) {

struts.xml

            /*

             * 在Action类中须要注明多少个属性

        protected Set<String> allowedTypesSet =
Collections.emptySet();    // 表示上传文件的项目

    如何界定每3个上传文件的尺寸及其上传文件的连串?

import com.opensymphony.xwork2.ActionContext;

        this.filename = filename;

import java.io.UnsupportedEncodingException;

             * String fileNameName = inputName + “FileName”;

            private String fileFileName; // 上传文件名,名称格式:name +
FileName

            public File getFile() {

一 、文件下载格局:
    超链接
    服务器编码,通过流向客户端写回。

 

        <action name=”download”
class=”com.wyc.action.DownloadAction”>

            <param
name=”contentDisposition”>attachment;filename=${downloadFileName}</param>

 

        <action name=”download”
class=”com.wyc.action.DownloadAction”>

 

 

    }

 

    {2}:上传文件保留到暂且目录的名号

import java.io.FileInputStream;

    能够在struts.xml文件中重复定义常量来修改上传文件大小限制。

        }

    public String getFilename() {

             */

    }

                <param name=”contentType”>text/plain</param>

import java.io.InputStream;

    public InputStream getInputStream() throws FileNotFoundException,
UnsupportedEncodingException{

 

        if(agent.contains(“MSIE”)){

 

——文件下载

    {0}:<input type=“file” name=“uploadImage”>中name属性的值

                FileUtils.copyFile(file, new File(“f:/upload”,
fileFileName));

        String agent =
ServletActionContext.getRequest().getHeader(“User-Agent”);

    }

            <input type=”file” name=”file” />

 

            </result>

            <param name=”contentType”>${contentType}</param>

 

 

                <param
name=”contentDisposition”>attachment;filename=a.txt</param>

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图