Struts2的文件上传与下载

 

 

时间:2017-1-11 15:47

关于flask_script

flask_script扩展提供于Flask插入外部脚本的机能,包括运转一个支出用之服务器,一个定制的Python
shell,设置数据库的脚本,cronjobs,及其它运行于web应用之外的一声令下执行职责;使得脚本和系统分离;

Flask
Script和Flask本身的劳作措施接近,只待定义及添加从命行中被Manager实例调用的命;

法定文档:http://flask-script.readthedocs.io/en/latest/

比方采用flask-script需要先安装

pip install flask_script

 

 

始建并运行命令

 

首先,创建一个Python模板运行命令脚本,可自从名叫吧manager.py;

于拖欠文件被,必须来一个Manager实例,Manager类追踪所有以指令行中调用的吩咐和处理过程的调用运行状况;

Manager就生一个参数——Flask实例,也得以是一个函数或另的返Flask实例;

调用manager.run()启动Manager实例接收命令行中之命;

图片 1😉

#-*-coding:utf8-*-  
from flask_script import Manager  
from debug import app  

manager = Manager(app)  

if __name__ == '__main__':  
    manager.run()  

图片 2😉

附带,创建并进入命令;

产生三种方法创建命令,即开立Command子类、使用@command修饰符、使用@option修饰符;

 

——使用commons-fileupload组件上传

第一种——创建Command子类

Command子类必须定义一个run方法;

比方:创建Hello命令,并以Hello命令加入Manager实例;

图片 3😉

from flask_script import Manager  ,Server
from flask_script import Command  
from debug import app  

manager = Manager(app)  


class Hello(Command):  
    'hello world'  
    def run(self):  
        print 'hello world'  

#自定义命令一:
manager.add_command('hello', Hello())  
# 自定义命令二:

manager.add_command("runserver", Server()) #命令是runserver
if __name__ == '__main__':  
    manager.run()  

图片 4😉

行如下命令:

python manager.py hello
> hello world

 python manager.py runserver 
> hello world

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

第二种——使用Command实例的@command修饰符

图片 5😉

#-*-coding:utf8-*-  
from flask_script import Manager  
from debug import app  

manager = Manager(app)  

@manager.command  
def hello():  
    'hello world'  
    print 'hello world'  

if __name__ == '__main__':  
    manager.run()  

图片 6😉

拖欠方法创建命令的周转方式跟Command类创建的运转方式相同;

python manager.py hello
> hello world

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

第三种——使用Command实例的@option修饰符

复杂情况下,建议采用@option;

可以起差不多个@option选项参数;

 

图片 7😉

from flask_script import Manager  
from debug import app  

manager = Manager(app)  

@manager.option('-n', '--name', dest='name', help='Your name', default='world')    #命令既可以用-n,也可以用--name,dest="name"用户输入的命令的名字作为参数传给了函数中的name
@manager.option('-u', '--url', dest='url', default='www.csdn.com')  #命令既可以用-u,也可以用--url,dest="url"用户输入的命令的url作为参数传给了函数中的url

def hello(name, url):  

'hello world or hello <setting name>'  
    print 'hello', name  
    print url  

if __name__ == '__main__':  
    manager.run()  

图片 8😉

运作方式如下:

python manager.py hello
>hello world
>www.csdn.com

python manager.py hello -n sissiy -u
www.sissiy.com
> hello sissiy
>www.sissiy.com

python manager.py hello -name sissiy -url
www.sissiy.com
> hello sissiy
>www.sissiy.com

 

——Struts2文件及传

默认情况下,Struts2框架下commons-fileupload组件进行上传操作,所以需要导入commons-fileupload.jar。

Struts2应用了一个interceptor帮助我们就文件上传操作:
    <interceptor name=”fileUpload”
class=”org.apache.struts2.interceptor.FileUploadInterceptor”/>

落实公文上传操作:

    页面中:

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

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

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

        </form>

        如果只要又达到传多个文本,那么有”file”的name属性值必须同。 

    Action中:
        public class UploadAction extends ActionSupport {

            /*

             * 在Action类中需声明三单特性

             */

            private File file; //
上污染文书,名称必须和表单页面中之name值相同

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

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

 

            /*

             *
在FileUploadInterceptor中发生如下三行代码,所以起名必须使正式

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

             * String contentTypeName = inputName + “ContentType”;

             * String fileNameName = inputName + “FileName”;

             */

            @Override

            public String execute() throws Exception {

                System.out.println(“上污染文书之档次:” +
fileContentType);

                System.out.println(“上污染文书的名号:” + fileFileName);
 

 

                // 完成文件及污染

                //
使用FileUtils的copyFile()方法将文件的输入流输出至指定位置

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

 

                return NONE;

            }

            public File getFile() {

                return file;

            }

            public void setFile(File file) {

                this.file = file;

            }

            public String getFileContentType() {

                return fileContentType;

            }

            public void setFileContentType(String fileContentType) {

                this.fileContentType = fileContentType;

            }

            public String getFileFileName() {

                return fileFileName;

            }

            public void setFileFileName(String fileFileName) {

                this.fileFileName = fileFileName;

            }

        }

——Struts2挨文件上传细节

1、控制及传文件大小
    在default.properties文件被定义了上传文件之轻重缓急:
        struts.multipart.maxSize=2097152 上传文件大小默认2M
    超出文件大小时,跳反到input视图,通过<s:actionerror
/>显示错误信息。

    可以当struts.xml文件被再定义常量来修改达传文件大小限制。

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

 

2、修改显示错误信息
   
默认在页面中显的错误信息是英文的,可以于Struts2基本包下之struts-message.properties文件被找到预定义上污染错误信息,在国际化文件被通过覆盖对诺key显示错误信息:

    // 上污染错误:{0}

    struts.messages.error.uploading=Error uploading: {0}
    // 上污染文书了大:{0} “{1}” “{2}” {3}

    struts.messages.error.file.too.large=The file is to large to be
uploaded: {0} “{1}” “{2}” {3}
    // 上污染文书未容许:{0} “{1}” “{2}” {3}

    struts.messages.error.content.type.not.allowed=Content-Type not
allowed: {0} “{1}” “{2}” {3}
    // 上传文书扩展名非容许:{0} “{1}” “{2}” {3}

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

 

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

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

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

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

    {1}:上传文书的实事求是名称

    {2}:上传文书保留及即目录的称号

    {3}:上传文书之项目(对struts.messages.error.file.too.large是上传文件的分寸)

 

 

3、多文本及传时每个文件大小控制及达传文书的扩充名限制

    多文件上传时,要用Action中之性声明也List集合或者数组:
        private List<File> file;
        private List<String> fileContentType;
        private List<String> fileFileName;
    然后每当excuete()方法被展开操作。

    怎样界定每一个及传文书的深浅及其上传文件之类型?

    在FileUploadInterceptor中发生如下代码:

        protected Long maximumSize;    // 表示每个上传文书之大大小小

        protected Set<String> allowedTypesSet =
Collections.emptySet();    // 表示达成污染文书的类

        protected Set<String> allowedExtensionsSet =
Collections.emptySet();    // 表示达成污染文书之恢宏名

 

     
 使用安排文件设置及传文书到底大小,对有上传form有效,如果单想对脚下form进行安装,可以装fileUplpad拦截器属性:
        *  
maximumSize:上传文书之太特别尺寸(以字节为单位),默认为2M。
        *   allowedTypes:允许上传的文件类型,各品种中以逗号分隔。
        *  
allowedExtendsions:允许上传文书扩展名,各扩展名以内以逗号分隔。

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

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

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

            </interceptor-ref>

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

        </action>

    如果对fileUpload进行参数设置,当出错时,在页面通过<s:filedError
/>回显错误信息。      

4、在Struts2面临默认使用的是commons-fileupload进行文件及传
    在default.properties文件中:
        # struts.multipart.parser=cos
        # struts.multipart.parser=pell
        struts.multipart.parser=jakarta    //
jakarta代表apache开源项目
    可以修改默认上传方法。

    如果采取pell、cos进行文件上传,必须导入其jar包。

——文件下充斥

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

    下载的求
    两个头、一个流
        *   Content-Type:表示传递让客户端文件之MIME类型。
            >  
通过文件名称调用ServletContext的getMimeType()方法得到MIME类型。
        *   Content-Disposition:
            >  
它的默认值为inline,表示于浏览器窗口中开拓(当起不开时见面弹框)。
            >  
attachment;filename=xxx:表示项目也附件,并当弹框的界面被展示下载的公文称。
        *   流:要下载的文件数量。
            >   自己new
一个输入流即可,然后经IOUtils完成流动的数量写入。

2、Struts中之文本下充斥
    通过<result type=”stream”>来完成。

    指定stream结果类型 需要指定一个
inputName参数,该参数指定一个输入流,提供于下载文件的入口。

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

    在StreamResult类中产生三只属性:
        *   protected String contentType = “text/plain”;    //
该属性用于安装下载文件之MIME类型
        *   protected String contentDisposition = “inline”;    //
该属性用于安装进行下载操作与下载文件的名目
        *   protected InputStream inputStream;    //
该属性用于读取要下载的文书

   
其中contentType、contentDisposition、inputStream可以在struts.xml文件被开展安排:

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

            <result type=”stream”>

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

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

                <!–
${inputStream}表示调用当前Action的getInputStream()方法,是ognl表达式,如果无装,则默认”inputStream”,可查阅StreamResult源码 –>

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

            </result>

        </action>

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

    然后一直当execute()方法中return SUCCESS即可。

3、文件乱码问题
    超链接下载的公文是中文名,会并发乱码情况,服务器会出错。

    解决方式:
        在getInputStream()方法中增长:
            filename = new String(filename.getBytes(“iso-8859-1”),
“utf-8”);

4、动态获取下载文件名和文件类型
    在struts.xml文件被使ognl表达式动态获取。

        <result type=”stream”>

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

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

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

            <!–
${inputStream}表示调用当前Action的getInputStream()方法,如果不装,则默认”inputStream”,可查阅StreamResult源码
–>

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

        </result>

5、示例代码:

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

DownloadAction:

package com.wyc.action;

 

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

import java.util.Base64;

 

import org.apache.struts2.ServletActionContext;

 

import sun.misc.BASE64Encoder;

 

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

 

public class DownloadAction extends ActionSupport {

 

    // 要下载文件的称号

    private String filename;

 

    public InputStream getInputStream() throws FileNotFoundException,
UnsupportedEncodingException{

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

 

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

        return fis;

    }

 

    // 获取下载文件MIME类型

    public String getContentType(){

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

    }

 

    /*

     * 获取下载文件名称

     * 解决浏览器差异问题

     */

    public String getDownloadFileName() throws
UnsupportedEncodingException{

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

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

            // IE浏览器

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

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

            // 火狐浏览器

            BASE64Encoder base64Encoder = new BASE64Encoder();

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

        } else {

            // 其他浏览器

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

        }

        return filename;

    }

 

    @Override

    public String execute() throws Exception {

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

        // 直接return SUCCESS即可。 

        return SUCCESS;

 

    }

 

    public String getFilename() {

        return filename;

    }

 

    public void setFilename(String filename) {

        this.filename = filename;

    }

}

 


struts.xml

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

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

<struts>

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

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

 

            <result type=”stream”>

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

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

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

                <!–
${inputStream}表示调用当前Action的getInputStream()方法,如果不安装,则默认”inputStream”,可查看StreamResult源码
–>

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

            </result>

        </action>

    </package>

</struts>

发表评论

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

网站地图xml地图