[JAVA] Implement file download with Spring MVC

I downloaded the file.

For XML files, just for the controller

Controller.java



	@Autowired
	ResourceLoader resourceLoader;

    @RequestMapping(value = "/file_download", produces = MediaType.APPLICATION_XML_VALUE)
    public Resource xmlfile() {

        Resource resource = resourceLoader.getResource("classpath:sample.xml");
       try{
        return new FileSystemResource(resource.getFile().toString());
        } catch (FileNotFoundException e) {
    	e.getStackTrace();
        }
    }

If you write something like that, you can go, but this is displayed in the browser and it ends, so After all I want it in the download folder. Make a note of how to do it

Composition of things to do

  1. Read the file
  2. Convert to byte format
  3. Write to OutputStream

Three processes are performed like this. Finally, return an appropriate view (null is fine) to complete the download function.

1. Read the file

First, let's set the file. Set the file in ** src / main / resources **.

image.png

This time, set this sample.xml

Create the part of the controller that reads the file.

XMLController.java


@RestController
public class XMLController {

	@Autowired
	ResourceLoader resourceLoader;

	@RequestMapping(value="/personize", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	public String personize(HttpServletResponse response) {
		
		Resource resource = resourceLoader.getResource("classpath:sample.xml");
        }
}

This is all you need to read the file. ** ResourceLoader is automatically registered in the DI container when the context is created ** (like), so there is no need to even describe it in the xml file. Thank you @Autowired.

2. Convert to byte format

Let's divide the processing. Create a new private method.

XMLController.java


	/**
	 *Convert from InputStream to byte string
	 * @param filepath
	 * @return
	 */
	private byte[] StreamToByte(Resource resource) {
		
	int nRead;
    InputStream is = null;
    byte[] fileContent = new byte[16384];
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
	
    //Convert file to byte format
    try {
        is = new FileInputStream(resource.getFile().toString());
        
        while ((nRead = is.read(fileContent, 0, fileContent.length)) != -1) {
        	  buffer.write(fileContent, 0, nRead);
        	}

        	buffer.flush();
        	
        	return buffer.toByteArray();
    } catch (FileNotFoundException e) {
    	e.getStackTrace();
    } catch (IOException e) {
		//TODO auto-generated catch block
		e.printStackTrace();
	}
    return null;
	}

What Spring is doing is only the ** resource.getFile (). ToString () ** part of line 15. This is the ** getFile () ** method, which allows you to get the files under src / main / resource in File format. It is affirmative that it is converted to an absolute address by toString ().

Well, since it's a big deal, I also explain the Java code

XMLController.java


        while ((nRead = is.read(fileContent, 0, fileContent.length)) != -1) {
        	  buffer.write(fileContent, 0, nRead);
        	}

        buffer.flush();

This is the main part of writing to BufferdOutputStream. Data is stored in the buffer and executed in flash. It looks like C, but it's already a fixed phrase. After that, I got the exception with try ~ catch.

3. Write to OutputStream

Write to the output stream of response First of all, let's set the header of what kind of file.

XMLController.java


	@RequestMapping(value="/personize", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	public String personize(HttpServletResponse response) {
		
		Resource resource = resourceLoader.getResource("classpath:sample.xml");
		
		byte[] fileContent = null;
		
		fileContent = StreamToByte(resource);
        
//		//File writing
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + "sample.xml");
        response.setContentLength(fileContent.length);

       }

setContentType specifies a type called a binary file. The file name is specified in response.setHeader, but this is the name of the file that is actually downloaded. response.setContentLength is the size of the file.

Now let's write the created binary to OutputStream This is also written in another method.

XMLController.java


	/**
	 *Write download file
	 * @param response
	 * @param fileContent
	 */
	public void OutputSreamWrite(HttpServletResponse response, byte[] fileContent) {
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            os.write(fileContent);
            os.flush();
        } catch (IOException e) {
            e.getStackTrace();
        }
	}

There will be no particular difficulty. Write with os.write and run the stream with os.flush.

Incorporate this method into your controller.

XMLController.java


	@RequestMapping(value="/personize", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	public String personize(HttpServletResponse response) {
		
		Resource resource = resourceLoader.getResource("classpath:sample.xml");
		
		byte[] fileContent = null;
		
		fileContent = StreamToByte(resource);
        
//		//File writing
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + "sample.xml");
        response.setContentLength(fileContent.length);
		
        OutputSreamWrite(response, fileContent);
        
        return null;
	}

With that feeling, the final form of the controller will be like this

XMLController.java


package tsugaruinfo.controller;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Controller
public class XMLController {

	@Autowired
	ResourceLoader resourceLoader;
	
	DomController(){
		
	}
	
	@RequestMapping(value="/personize", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	public String personize(HttpServletResponse response) {
		
		Resource resource = resourceLoader.getResource("classpath:sample.xml");
		
		byte[] fileContent = null;
		
		fileContent = StreamToByte(resource);
        
//		//File writing
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + "sample.xml");
        response.setContentLength(fileContent.length);
		
        OutputSreamWrite(response, fileContent);
        
        return null;
	}
	
	/**
	 *Convert from InputStream to byte string
	 * @param filepath
	 * @return
	 */
	private byte[] StreamToByte(Resource resource) {
		
	int nRead;
    InputStream is = null;
    byte[] fileContent = new byte[16384];
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
	
    //Convert file to byte format
    try {
        is = new FileInputStream(resource.getFile().toString());
        
        while ((nRead = is.read(fileContent, 0, fileContent.length)) != -1) {
        	  buffer.write(fileContent, 0, nRead);
        	}

        	buffer.flush();
        	
        	return buffer.toByteArray();
    } catch (FileNotFoundException e) {
    	e.getStackTrace();
    } catch (IOException e) {
		//TODO auto-generated catch block
		e.printStackTrace();
	}
    return null;
	}
	
	/**
	 *Write download file
	 * @param response
	 * @param fileContent
	 */
	public void OutputSreamWrite(HttpServletResponse response, byte[] fileContent) {
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            os.write(fileContent);
            os.flush();
        } catch (IOException e) {
            e.getStackTrace();
        }
	}
}


It's been a little longer. However, the troublesome processing is separated, so when creating a new download function from now on, I try to use the troublesome processing. Since I explain each process individually, I wondered if I should understand the small finished product rather than grasping the whole at once.

Let's run

Let's access the actual address.

image.png

image.png

I was able to download sample.xml from the server.

reference

http://bookmount8.blog.fc2.com/blog-entry-49.html?

Recommended Posts

Implement file download with Spring MVC
I tried to implement file upload with Spring MVC
Implement image input / output with Spring MVC
Download with Spring Boot
Java Config with Spring MVC
Implement GraphQL with Spring Boot
File upload with Spring Boot
Local file download memorandum in Spring Boot
How to achieve file download with Feign
Implement CRUD with Spring Boot + Thymeleaf + MySQL
Implement paging function with Spring Boot + Thymeleaf
Just input and output images with Spring MVC
Test controller with Mock MVC in Spring Boot
How to create an Excel form using a template file with Spring MVC
[Note] Configuration file when using Logback with Spring Boot
[Spring] Read a message from a YAML file with MessageSource
Spring Security usage memo: Cooperation with Spring MVC and Boot
Spring with Kotorin --- 5. Actuator
Comfortable download with JAVA
Implement a simple Rest API with Spring Security with Spring Boot 2.0
Download Java with Ansible
Self-made Validation with Spring
File upload with Spring Boot (do not use Multipart File)
Spring with Kotorin ―― 1. SPRING INITIALIZR
Implement REST API with Spring Boot and JPA (Application Layer)
Implement REST API with Spring Boot and JPA (Infrastructure layer)
Extract SQL to property file with jdbcTemplate of spring boot
Overwrite bean definition in spring xml configuration file with another xml
To receive an empty request with Spring Web MVC @RequestBody
Implement REST API with Spring Boot and JPA (domain layer)
Implement a simple Rest API with Spring Security & JWT with Spring Boot 2.0
Generate barcode with Spring Boot
Hello World with Spring Boot
Spring with Kotorin --8 Repository layer
Get started with Spring boot
Hello World with Spring Boot!
Spring with Kotorin --6 Asynchronous processing
iOS: File upload with SFTP
Run LIFF with Spring Boot
SNS login with Spring Boot
Implement jCaptcha reload with ajax
Spring Boot starting with copy
Operation Spring Awakening Spring MVC Part 1
Spring with Kotorin ―― 7. Service layer
Login function with Spring Security
Using Mapper with Java (Spring)
Spring Boot starting with Docker
Hello World with Spring Boot
Set cookies with Spring Boot
Use Spring JDBC with Spring Boot
Operation Spring Awakening Spring MVC Part 4
Add module with Spring Boot
Getting Started with Spring Boot
Link API with Spring + Vue.js
Operation Spring Awakening Spring MVC Part 3
Create microservices with Spring Boot
Send email with spring boot
[Introduction] Build MVC with Scala
Operation Spring Awakening Spring MVC Part 2
Implement search function with form_with
Implement a simple Web REST API server with Spring Boot + MySQL