File download of spring MVC framework

File download of spring MVC framework

There are two ways to download files, one is to download through hyperlinks, and the other is to download by program coding. It is simple to download through hyperlink, but it is easy to expose the real location of the downloaded files, and only the files stored in the directory where the Web application is located can be downloaded. Downloading by program coding can increase security access control, provide downloaded data from any location, and store the files in a directory other than the Web application, You can also save files to a database.

Two headers need to be set to realize file download by using the program:
1-the web server needs to tell the browser that the type of content it outputs is not an ordinary text file or HTML file, but a download file to be saved locally. This requires setting the value of content type to application/x-msdownload
2-The web server wants the browser not to directly process the corresponding entity content, but to save the corresponding entity content to a file. This requires setting the content disposition header, which specifies the way the receiver processes the data content. In HTTP applications, only attachment is the standard way, and attachment requires user intervention, You can also specify the filename parameter after the attachment, which is the file name that the server recommends the browser to save the entity content to the file.

Let's learn the case of file download.
1 - create a web application and import relevant jar packages.
2 - deploy DispatcherServlet in web.xml and set encoding filter.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         id = "WebApp_ID" version="4.0">
    <!--deploy DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <!--Represents the load when the container starts servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--Any request passed DispatcherServlet-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- to configure CharacterEncodingFilter Solve the problem of Chinese garbled code-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <!-- The configuration encoding format is UTF-8 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>


3 - in the src directory, create the controller package. In this package, create the controller class FileDownController. In this class, write three methods to display, download and convert the character encoding format of the file name.

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;

import java.util.ArrayList;

@Controller
public class FileDownController {
    //Show files to download
    @RequestMapping("/showDownFiles")
    public String show(HttpServletRequest request, Model model){
        String realpath = "D:\\study" ; //Pathname
        File dir = new File(realpath) ; //catalogue
        File [] files = dir.listFiles() ; //All files in the directory
        //Get the names of all files in the directory
        ArrayList<String> fileName = new ArrayList<>() ;
        for(int i=0; i<files.length; i++){
            fileName.add(files[i].getName()) ; //Get the file name and store it in the collection
        }
        model.addAttribute("files", fileName) ; //Exposed as model data, it can be retrieved using EL expressions on jsp pages
        return "showDownFiles" ;
    }
    //Perform Download
    @RequestMapping("/down")
    public String down(@RequestParam  String filename, HttpServletRequest request, HttpServletResponse response){
        String aFilePath = null ; //The path to the file to download
        FileInputStream in = null ; //Input stream
        ServletOutputStream out = null ; //Output stream
        try{
            aFilePath = "D:\\study" ;
            //Sets the header used by the downloaded file
            response.setHeader("Content-Type", "application/x-msdownload") ;
            response.setHeader("Content-Disposition", "attachment;filename="  + toUTF8String(filename)) ;

            //Read in file
            in = new FileInputStream(aFilePath + "\\" + filename) ;
            //Get the output stream of the response file, which is used to output binary data to the client
            out = response.getOutputStream() ;

            out.flush() ;
            int aRead = 0 ;
            byte [] b = new byte[1024] ;
            while((aRead=in.read(b)) != -1 && in != null){
                out.write(b) ; //Write
            }
            out.flush() ;
            in.close() ;
            out.close() ;
        }catch(Exception e){
            e.printStackTrace();
        }
        return null ;
    }
    //Character encoding conversion method of Chinese file name when downloading and saving
    private String toUTF8String(String str) {
        StringBuffer sb = new StringBuffer() ;
        int len = str.length() ;
        for(int i=0; i<len; i++){
            //Extract each character of the string
            char c = str.charAt(i) ;
            if(c >= 0 && c <= 255){
                sb.append(c) ;
            }else{
                byte [] b ;
                try{
                    b = Character.toString(c).getBytes("utf-8") ;
                }catch(Exception e){
                    e.printStackTrace();
                    b = null ;
                }
                for(int j=0; j<b.length; j++){
                    int k = b[j] ;
                    if(k < 0){
                        k &= 255 ;
                    }
                    sb.append("%" + Integer.toHexString(k).toUpperCase()) ;
                }
            }
        }
        return sb.toString() ;
    }
}


4 - create the configuration file springmvc-servlet.xml in the src directory, scan the controller package in the configuration file, and configure the view parser.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--Using the scanning mechanism, scan the controller class-->
    <context:component-scan base-package="controller"/>
    <mvc:annotation-driven />

    <!--Configure view parser-->
    <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" id = "internalResourceViewResolver">
        <!--prefix-->
        <property name = "prefix" value = "/WEB-INF/jsp/"/>
        <!--suffix-->
        <property name = "suffix" value = ".jsp"/>
    </bean>

    <!--use Spring of CommonsMultipartResolver to configure MultipartResolver For file upload-->
    <!--Configure the default encoding method. The maximum value of files allowed to be uploaded is in bytes,Temporary path to configuration file-->
    <bean id = "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver"
          p:defaultEncoding="UTF-8"
          p:maxUploadSize="5400000000000"
          p:uploadTempDir="WEB-INF">
    </bean>

</beans>


5 - create a file list page showDownFiles.jsp under the JSP directory of WE-INF

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/10/2
  Time: 16:25
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<table>
    <tr>
        <td>Name of downloaded file</td>
    </tr>
    <!--ergodic Model Medium files-->
    <c:forEach items = "${files}" var = "filename">
        <tr>
            <td><a href = "${pageContext.request.contextPath}/down?filename=${filename}">${filename}</a></td>
        </tr>
    </c:forEach>
</table>
</body>
</html>

Keywords: Spring mvc

Added by climbjm on Thu, 07 Oct 2021 05:01:22 +0300