`
george.gu
  • 浏览: 71180 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

File upload and download in Java Web Application.

阅读更多

最近在项目中遇到一个下载文件的老问题。之所以说是老问题,因为在以前的很多项目中都遇到过,但是当时赶进度,所以在找到解决方案后就草草了事,没有深入的研究、总结一下各种方法,实乃憾事。

既然再次遇到,就不能放过。争取在依然很紧张的项目进度中,找出一点时间总结一下Java Web Application开发中涉及到的文件上传、下载解决方案。鉴于博客是写给自己看的,加上时间紧张,所以我会持续更新,不求一气呵成。

 

Upload File through Html FORM:

/html/body/form/@enctype: ENCTYPE determines how the form data is encoded. Whenever data is transmitted from one place to another, there needs to be an agreed upon means of representing that data.
FORM ENCTYPE has three different values:

  1. application/x-www-form-urlencoded : All characters are encoded in URL encoding before sent (this is default). Only value attribute inside form will be processed.
  2. multipart/form-data : data will be transformed in byte code stream. This value is required when you are using forms that have a file upload control. In
  3. text/plain : Spaces are converted to "+" symbols, but no special characters are encoded

So if you want to upload file through web, you have to first set form ENCTYPE to be "multipart/form-data".

Using pure Servlet:

In fact, file download and upload in Java Web Application are to manage files through InputStream from HttpServletRequest and OutputStream from HttpServletResponse.

Even we can simply the development and configuration by using some framework, but anyway we should know what is the kernel for file uploading and download.

File Upload web interface:

 

fileUpload.html

<html>

  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <title>Upload a File</title>

  </head>

  <body>

    <h1>Upload File </h1>

    <h2>Warning: Please make sure your web browser support file uploading.</h2>

    <form action="servlet/uploadServlet" method="POST" enctype="multipart/form-data ">

        Select a file to upload: <input type="file" size="40" name="upl-file"/> </BR>

         <input type="submit" value="Upload"/> <input type="reset" value="Reset"/>

    </form>

  </body>

</html>

 

Read file from HttpServletRequest Inputstream:

 

            /**

              * Servlet.doPost: reads the uploaded data from the request and writes it to

              * a file.

              */

            public void doPost(HttpServletRequest request, HttpServletResponse response) {

                        DataInputStream in = null;

                        try {

                                    // get content type of client request

                                    String contentType = request.getContentType();

 

                                    // make sure content type is multipart/form-data

                                    if (contentType != null

                                                            && contentType.indexOf("multipart/form-data ") != -1) {

                                                // open input stream from client to capture upload file

                                                in = new DataInputStream(request.getInputStream()) ;

                                                // get length of content data

                                                int formDataLength = request.getContentLength();

                                                byte dataBytes[] = new byte[1024];

                                                int bytesRead;

                                                while ((bytesRead = in.read(dataBytes)) != -1) {

                                                            // write the data to server file.

                                                }

 

                                                // here you can perform some other checks.

                                    }

                        } catch (Exception e) {

                        }

            }

This is just a draft demo on how to upload file through servlet. There is no control on large files and user rights.

 

Download file through HttpServletResponse OutputStream

 

            /**

              * Servlet.doPost: get data to be sent to client and output it through Response.outputStream. Web browser will pop-up a save file window to let User download file.

              */

            public void doPost(HttpServletRequest request, HttpServletResponse response) {

                        response.setContentType("text/csv");

                        response.setHeader("Content-Disposition",

                                                "attachment; filename=unknownModels.csv");

                         OutputStream out;

                        // PrintWriter printWriter;

                         try {

                                    out  = response.getOutputStream();

                                    // printWriter = response.getWriter();

    ...

                                     // output your content with printWriter. It will output content to client.

    ...

                                     out.flush();

                                    // printWriter.flush();

                         } catch (IOException e) {

                                    System.err.println("Met a error when download file.");

                                    System.exit(1);

                        }

            }

Content-Disposition used to define download file or open a file in web browsers:

  1. attachment; filename=myfile.txt: download a file with default name myfile.txt

  2. inline; filename=myfile.txt: open the file in web browser. default file name myfile.txt


Using commons-fileupload.jar to Upload file

TBD

 

Using Struts1

File upload through Struts1:

In struts-config_1_3.dtd, we can find controller definition to control file uploading through struts1.*

 

struts-config/controller:
                @bufferSize            The size of the input buffer used when processing
                                      file uploads.
                                      [4096]
                @maxFileSize         The maximum size (in bytes) of a file to be accepted as a
                                     file upload.  Can be expressed as a number followed by a
                                     "K", "M", or "G", which are interpreted to mean kilobytes,
                                      megabytes, or gigabytes, respectively.
                                      ["250M"]
                @memFileSize         The maximum size (in bytes) of a file whose contents will
                                         be retained in memory after uploading. Files larger than
                                     this threshold will be written to some alternative storage
                                     medium, typically a hard disk. Can be expressed as a number
                                     followed by a "K", "M", or "G", which are interpreted to
                                     mean kilobytes, megabytes, or gigabytes, respectively.
                                     ["256K"]
                @multipartClass       The fully qualified Java class name of the multipart
                                      request handler class to be used with this module.
                                      ["org.apache.struts.upload.CommonsMultipartRequestHandler"]
                @nocache             Set to "true" if you want the controller to add HTTP
                                      headers for defeating caching to every response from
                                      this module.  [false]
                @tempDir             Temporary working directory to use when processing
                                      file uploads.
                                      [{Directory provided by servlet container}]

By default struts 1 provide org.apache.struts.upload.CommonsMultipartRequestHandler to process file uploading transform. CommonsMultipartRequestHandler encapsulate apache-commons-fileupload for file uploading processing. If you want to know how CommonsMultipartRequestHandler  manage file uploading or you want to implement your own MultipartRequestHandler, please refer to struts source code for that.

 

 

Your form should extends ActionForm and contains a FileForm named with same value as html:file/@name.
Then config your upload Action in struts-config.xml to map to this form-bean.

 

After that, we can use FormFile.getInputStream() to get file data and no need to care about file uploading processing.

File download through Struts1:

Struts 1 provide DownloadAction:

org.apache.struts.actions.DownloadAction.

Here is a snapshot of org.apache.struts.actions.DownloadAction.java:

 

public abstract class DownloadAction extends BaseAction {
    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     * Return an <code>ActionForward</code> instance describing where and how
     * control should be forwarded, or <code>null</code> if the response has
     * already been completed.
     *
     * @param mapping  The ActionMapping used to select this instance.
     * @param form     The optional ActionForm bean for this request (if
     *                 any).
     * @param request  The HTTP request we are processing.
     * @param response The HTTP response we are creating.
     * @return The forward to which control should be transferred, or
     *         <code>null</code> if the response has been completed.
     * @throws Exception if an exception occurs.
     */
    public ActionForward execute(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {
        StreamInfo info = getStreamInfo(mapping, form, request, response);
        String contentType = info.getContentType();
        InputStream stream = info.getInputStream();

        try {
            response.setContentType(contentType);
            copy(stream, response.getOutputStream());
        } finally {
            if (stream != null) {
                stream.close();
            }
        }

           // Tell Struts that we are done with the response.
        return null;
    }
    
    /**
     * Returns the information on the file, or other stream, to be downloaded
     * by this action. This method must be implemented by an extending class.
     *
     * @param mapping  The ActionMapping used to select this instance.
     * @param form     The optional ActionForm bean for this request (if
     *                 any).
     * @param request  The HTTP request we are processing.
     * @param response The HTTP response we are creating.
     * @return The information for the file to be downloaded.
     * @throws Exception if an exception occurs.
     */
    protected abstract StreamInfo getStreamInfo (ActionMapping mapping,
        ActionForm form, HttpServletRequest request,
        HttpServletResponse response)
        throws Exception;
    
    
    /**
     * Copy bytes from an <code>InputStream</code> to an
     * <code>OutputStream</code>.
     *
     * @param input  The <code>InputStream</code> to read from.
     * @param output The <code>OutputStream</code> to write to.
     * @return the number of bytes copied
     * @throws IOException In case of an I/O problem
     */
    public int copy(InputStream input, OutputStream output)
        throws IOException {
        byte[] buffer = new byte[getBufferSize()];
        int count = 0;
        int n = 0;

        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }

        return count;
    }

    ......    
}

 

 

So we should define an Action that extends DownloadAction and implement method:

StreamInfo getStreamInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response);

Inside your implementation, you can read file from file system or get them from romote server, and then format it into a StreamInfo object which will be used by DownloadAction to open a InputStream.

Using Struts2

Struts2 vs Struts1:

Since Struts2 realize webwork2 and provides different configuration as struts1. So it is more like a new MVC framework rather than upgrade of struts1. Here are some new features in struts2:

  1.     Action should implement ActionSupport
  2.     Each action's parameter fields will represent dedicated HTML/form data, so there is no need to define ActionForm (form-beans/form-bean in struts1) again.
  3.     Struts2 introduce AOP interceptor and IOC (like /package/action/param)
  4.     Configuration file changed a lot.
  5.     ...

File uploading through struts2:

For file uploading, struts2 introduce three new parameters in Action to represent File information:

  • File XXX:                  represent the File to be uploaded. XXX is the value of attribute: HTML/form/file/@name. 
  • String XXXFileName:      represent the original file name of file XXX.
  • String XXXContentType:  represent the content type of file XXX. 

If you want to upload a set of files, those three parameters should be defined as:

  • File[] XXX:                  represent the File to be uploaded. XXX is the value of attribute: HTML/form/file/@name.   All the file upload form should use same file/@name definition.
  • String[] XXXFileName:          represent the original file names of file XXX.
  • String[] XXXContentType:     represent the content types of files XXX. 

So you should define your own upload Action as following:

 

  1. First extend ActionSupport and contain those three necessary parameters
  2. Then you can use File XXX to read data from InputStream.

Because in my current project, we do not use struts2, so I do not study the source code of struts2. But anyway, we can image there is a MultipartRequestHandler which will process file uploading and convert it into Action.XXX for us.

 

File Download through Struts2

About download, we can talk about it later.

But anyway, I am always thinking that even framework provide encapsulation of complex operation for us, but the kernel should always the same: send file data through Response OutputStream.

 

Attach file management in SOAP

TBD

 

分享到:
评论

相关推荐

    Java for the Web with Servlets,JSP,and EJB,A Developer's Guide to J2EE Solutions

    These technologies are explained in the context of real-world projects, such as an e-commerce application, a document management program, file upload and programmable file download, and an XML-based ...

    Java for the Web with Servlets, JSP, and EJB

    These technologies are explained in the context of real-world projects, such as an e-commerce application, a document management program, file upload and programmable file download, and an XML-based ...

    Selenium.WebDriver.Recipes.in.Csharp.2nd.Edition.1484217

    How to use Selenium WebDriver for select lists, navigation, assertions, frames, file upload and pop-up dialogs How to debug test scripts and test data How to manage and deal with browser profiles and ...

    Android代码-AndServer

    Upload file to android application. Download file from android application. Support high concurrency. Dependencies Gradle compile 'com.yanzhenjie:andserver:1.0.3' Maven com.yanzhenjie andserver...

    EurekaLog_7.5.0.0_Enterprise

    12)..Changed: VCL/CLX/FMX now will assign Application.OnException handler when low-level hooks are disabled EurekaLog 7.2 Hotfix 6 (7.2.6.0), 14-July-2015 1)....Added: csoCaptureDelphiExceptions ...

    Geoserver用户手册

    6.3 Java Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 6.4 GML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...

    Spring.MVC.A.Tutorial.2nd.Edition.1771970316

    Converters and Formatters Chapter 7: Validators Chapter 8: The Expression Language Chapter 9: JSTL Chapter 10: Internationalization Chapter 11: File Upload Chapter 12: File Download Chapter 13: ...

    PROGRAMMING ACTIONSCRIPT 3.0

    Working with file upload and download671 Example: Building a Telnet client. 682 Example: Uploading and downloading files... 685 Chapter 23: Client system environment..695 Basics of the client system ...

    Getting.started.with.Spring.Framework.2nd.Edition1491011912.epub

    Getting started with Spring ...Chapter 13 – More Spring Web MVC – internationalization, file upload and asynchronous request processing Chapter 14 – Securing applications using Spring Security

    spring-boot-file-upload-download-rest-api-example:Spring Boot文件上传下载Rest API示例

    打开src/main/resources/application.properties文件,然后将属性file.upload-dir更改为要存储上载文件的路径。 file.upload-dir=/Users/callicoder/uploads 2.使用maven运行应用 cd spring-boot-file-upload-...

    计算机网络第六版答案

    23. The five layers in the Internet protocol stack are – from top to bottom – the application layer, the transport layer, the network layer, the link layer, and the physical layer. The principal ...

    Java邮件开发Fundamentals of the JavaMail API

    Instructions on how to download and install the JavaMail API are contained in the course. In addition, you will need a development environment such as the JDK 1.1.6+ or the Java 2 Platform, Standard...

    P.A.T.C.H. - Ultimate Patching System [FULL]

    In addition, you will be able to create small-sized patches (and upload them) quickly with included tools! It includes Unity integrated tools and standalone version (if someone prefers to use it). ...

    Network Spy {Dynamic IP Server}

    each dominator control a specific clients list, the clients made by dominator X1 will connect server X1 only, clients in 1st run download all its dependency from web site, clients check if server ...

    php.ini-development

    Expressions in the INI file are limited to bitwise operators and parentheses: ; | bitwise OR ; ^ bitwise XOR ; & bitwise AND ; ~ bitwise NOT ; ! boolean NOT ; Boolean flags can be turned on using ...

    google api php client

    Uncompress the zip file you download, and include the autoloader in your project: ```php require_once '/path/to/google-api-php-client/vendor/autoload.php'; ``` For additional installation and setup ...

    ssh(structs,spring,hibernate)框架中的上传下载

    WEB-INF下的applicationContext.xml为Spring的配置文件,struts-config.xml为Struts的配置文件,file-upload.jsp为文件上传页面,file-list.jsp为文件列表页面。  本文后面的章节将从数据持久层->业务层->Web层的...

    Vagaa哇嘎画时代--体验群体智慧的力量!

    4.1 You are responsible for paying all applicable taxes and other costs you may incur in connection with your use of the Software including but not limited to all hardware and software costs and ...

    SU-FTP-Server-Windows-v15.1.2

    3) Vulnerability which allows for the injection of additional email headers by using a crafter subject in an upload or download request. Installation Instructions ------------------------- This ...

Global site tag (gtag.js) - Google Analytics