SpringMvc - file upload and download

Keywords: Spring MVC

SpringMvc - file upload and download

File download using ResponseEntity

First, create a directory under the webapp directory to store the content to be downloaded. First, casually put in a picture

Then, open maven management, find lifecycle -- > > package, and double-click to repackage. Package the directory just created into the package to be deployed

Next, create a tag or page responsible for receiving the download request, and then write the controller method

It's in a bad state today. The controller didn't write an annotation statement. There was a long mistake. I thought what happened

In the controller

As mentioned above, ResponseEntity should be used as the return value of the controller method. It is generally used as a file download

In the following method, the return value type is a byte array of ResponseEntity type

Every other sentence has been written.

@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
    //Get ServletContext object
    ServletContext servletContext = session.getServletContext();
    //Get the real path of the file in the server under webapp
    String realPath = ((ServletContext) servletContext).getRealPath("/static/img/1.jpg");
    //Create input stream
    InputStream fileDown = new FileInputStream(realPath);
    //To create a byte array, is.available is to judge whether there is a file to be downloaded
    byte[] bytes = new byte[fileDown.available()];
    //Read stream into byte array
    fileDown.read(bytes);
    //Create an HttpHeaders object and set the response header information
    MultiValueMap<String, String> headers = new HttpHeaders();
    //Set the download method and the name of the downloaded file. This sentence can only change the file name, and others cannot be changed. Attachment means that the file will be downloaded as an attachment
    headers.add("Content-Disposition", "attachment;filename=1.jpg");
    //Set the response status code. HttpStatus is an enumeration class that encapsulates the browser's response status code. I just want to return 200.OK
    HttpStatus statusCode = HttpStatus.OK;
    //Create ResponseEntity object
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
    //Close input stream
    fileDown.close();
    return responseEntity;
}

Realize file upload function

First, introduce dependencies

<!--File upload dependency-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

Then configure it in the configuration file of spring MVC. Spring MVC encapsulates the uploaded file into a MultipartFile object, through which you can obtain file related information, so you need to register the implementation class CommonsMultipartResolver of this interface in the configuration file. There should be an id. here, SpringMVC finds the bean according to the id. if there is no id, it means that the bean is not registered, and the id is set to multipartResolver

Then check whether mvc and context are introduced into the namespace, whether access to static resources is open, whether mvc annotation driver is open, and whether component scanning is open

<!--
register CommonsMultipartResolver,Give Way SpringIOC Containers are automatically scanned and must be set id by multipartResolver,otherwise IOC The container could not scan for this registered bean
    -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

In html

When uploading files, you usually upload local files to the server. Now you can use the form form to submit data and the file type of the input control

When using the form, you should pay attention to the post request first, then the submission address, and then the attribute enctype = multipart / form data. When using the input control, specify the attribute type as file, the name value is the submission parameter, the controller method should accept, and the name value should be consistent with the parameter name in the controller method, Or use the @ PathVariable annotation to declare who the parameter with this name is assigned to. Then get a submit button

<body>
<a th:href="@{/testDown}">File download</a><br>
<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
<input type="file" name="photo"/><br>
<input type="submit" name="upload"/>
</form>
</body>

Controller method

At the beginning, it is said that SpringMvc encapsulates the uploaded file as a Multipart file object, so it creates a Multipart type parameter to receive the file submitted by the form, so the parameter name should be the same as the file name.

In the upload method, you can find the file name of the uploaded file in the mutlipart object

Then find the path [directory] to save after the file is uploaded. The method to obtain the path of the project on the server. What you have learned is the getRealPath method of the ServletContext object.

When the file upload function is added in the actual development, the saved directory of the uploaded file does not necessarily exist, so it needs to be created.

Use the file object instead of the obtained path to save the file, and then judge the file object. If it does not exist, create one.

Finally, determine the path and file name of the file.

Call the method transferTo of the MultipartFile object to upload the file to the final directory.

Finally, you can see the newly created folder and uploaded files in the directory of the folder [target] where maven actually runs

In practice, it is found that if the file name is the same, the last uploaded file will be overwritten. To solve this problem, you can splice a file name with a content that will never be repeated. When splicing the file name to form a new file name, you need to obtain the suffix of the file, intercept the file name using the substring method, and tell the program to intercept from the last point with the lastIndexOf method in the method. In this way, you can get the complete file suffix, and then splice the String with the never repeated String variable you prepared

@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
    //Gets the file name of the uploaded file
    String fileName = photo.getOriginalFilename();
    //Handling file name duplication
    String lastName = fileName.substring(fileName.lastIndexOf("."));
    fileName = UUID.randomUUID().toString() + lastName;
    //Gets the path to the photo directory in the server
    ServletContext servletContext = session.getServletContext();
    String photoPath = servletContext.getRealPath("photo");
    File file = new File(photoPath);
    if(!file.exists()){
        file.mkdir();
    }
    String finalPath = photoPath + File.separator + fileName;
    //Realize the upload function
    photo.transferTo(new File(finalPath));
    return "success";
}

Posted by yoki on Wed, 24 Nov 2021 12:07:09 -0800