preface

Hello everyone, I am Bigsai, today we will learn the file upload and download of Springmvc.

File upload and download is a very important part of Internet Web application, and it is one of the important channels of information exchange and transmission. You’ve probably been uploading and downloading files on the Web a lot. You’ve probably been immersed in the mysteries of Internet technology, and this article explains them to you.

This article has been included in the public account bigsai (wechat bigsai) and Erudite Valley

Case analysis

You may be asking: What can I possibly learn from this passage?

It is my responsibility to tell you that through this article, you have learned the Springmvc file upload (single file, multiple file) file download knowledge and content use, and can implement some basic cases based on these.

Core ideas disassemble

You might ask: How does such a complete project work?

Before I rush, LET me tell you that a file upload and download project is a B-S web project involving the front-end and server side. From a macro perspective, it looks like this:

However, there are differences between them from the two functions of file upload and download. The main core of file upload is that the server accepts and stores the files uploaded by users:

The more important part of the file download is that the server returns the binary file to the user after the user requests it:

Therefore, the project structure of file upload and file download is similar in general, but each part is different in specific implementation. We need to pay more attention to the realization and difference of file upload and download server.

Knowledge points involved in the case

In this case, the following knowledge points are used:

HTML page form:

In the front-end whether HTML or JSP template engine writing uploaded pages. The

tag means an uploaded form.
  • Forms can contain several input tags, and input tags have different types such as text fields, checkboxes, checkboxes, files, and so on.
  • We usually write several using formsThe tag represents the data that we want to send to the server, and then the button on the tag submits the data request to the server.
  • Method indicates the request type (usually POST), Action indicates the URL to be requested, and encType indicates the data type to be transferred.

For Springmvc:

The case file upload and download is based on Springmvc, which we integrate in the Springboot project.

  • This case uses Springmvc as the framework of the project’S MVC architecture, and separates the Model, View and Controller to reduce the coupling of the project.
  • This case uses Springmvc’s MultipartFile interface and ResponseEntity interface to upload and download files.

Create the Springmvc project

Springmvc is a Web framework with MVC architecture. There are many ways to create Springmvc projects. You can choose to create Springmvc projects directly through IDEA, or you can create Web projects through Maven and add Springmvc dependencies. However, there are too many configurations in these two ways and Tomcat needs to be configured. Under the condition that the effects are consistent, we try to simplify the work of developing configuration classes, so we do not adopt the above two ways to create projects.

Springboot simplifies the development of Spring projects, out of the box, and embedded Tomcat, so we choose to create a project based on Springboot and integration of Springmvc is convenient and fast, more can go straight to the theme of operation.

Project creation

First, open IDEA, create the project, select The Spring Initializr type to initialize and click Next.And then you get a page that selects the project name and some configuration, and we fill in com for groups, and we fill in Fileupload for artifacts. Click next.Then, when selecting the corresponding module dependency, select the Spring Web module, which is the Web module that contains SpringmvcNext, select the directory where you want to create the project and click Next

In this way, you can get a complete Springboot project containing the Web module (Springmvc), in which you can write our project code.

catalogue

By default, there are several files and folders in the SpringBoot-based Springmvc project, which have different responsibilities:

  • java: Used to write Java server-side code, such as Controller, Dao, Service, etc.
  • application.properties: Write configuration content of some projects and frameworks and integrate configuration with third-party frameworks
  • static: static resource directory, used to store HTML, JavaScript, images and other resources.
  • teamplates: used to write template engines such as Thymeleaf, not used here
  • pom.xml: Write maven project JAR package resource dependencies. This can be done if the project needs to introduce additional dependencies or change the packaging.

For file uploading of Web projects, certain configuration is required to meet our usage requirements. We do the following configuration in application.propertis:

# allow file uploads in the project
spring.servlet.multipart.enabled=true
# temporary directory for uploading files (usually not modified)
#spring.servlet.multipart.location=
The maximum size of a file to be uploaded is 1M (default: 1M).
spring.servlet.multipart.max-file-size=104857600
The maximum size of an upload request is 10M.
spring.servlet.multipart.max-request-size=104857600
# file size threshold, when larger than this threshold will be written to disk, otherwise stored in memory, (default value 0 is generally not changed)
spring.servlet.multipart.file-size-threshold=0
# determine if you want to parse the file lazily.
spring.servlet.multipart.resolve-lazily=false
Copy the code

Of course, you can make your own changes to the configuration if you have other requirements such as file size. Now that the project with the Springmvc environment has been created, all that is left is to write the front-end and server-side code to run the tests.

Single file upload

Please follow me to upload the Springmvc single file. A complete file upload project consists of two parts: the front-end interface and the server program.

The front end design

For the front end, we use HTML that you’re no doubt familiar with instead of using another template engine. The form form is the core component of HTML file uploads, and you need to know some of its properties before using it.

The encType property of a form describes the general flow of a form file transfer. As you know, forms have one crucial property: EncType. Entype values generally have the following three types:

  • application/x-www-form-urlencoded: The default encoding, which encodes all characters before sending (by default) using URL encoding, similar to get requests. But this method can be inefficient if you send large amounts of binary data.
  • multipart/form-data: Does not encode characters. You must use this value when using forms that contain file upload controls. Usually used to send binary data to the server, and our files are mostly transferred in binary mode.
  • text/plain: Spaces are converted to “+” plus signs, but no special character encoding.

Therefore, in this single file upload case, note the following:

  • The encType of the form must be of type multipart/form-data, representing binary transfer.
  • Define a label in a form whose input is the file attribute, representing file uploads.
  • The method of the form form must be POST.
  • Enctype must be multipart/form-data, indicating binary transmission.

Static (index1.html); static (index1.html); static (index1.html);

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Single file upload</title>
</head>
<body>
<h2>Single file upload</h2>
<form  action="onfile" method="post" enctype='multipart/form-data'>
    <input type="file" name="file" ><br>
    <input type="submit" value="Submit">
</form>
</body>
</html>
Copy the code

Where action=”onfile” means the request address is onfile, which is in the project, so use the relative address. If the upload is for other interfaces, you can also fill in the corresponding absolute address. So the front-end page is written, we also need to write file upload corresponding server module.

Server Design

The server side is mainly responsible for the file acceptance. On the front end, it looks easy to implement the page of the file upload, but in reality, the file acceptance on the server side is not that easy, because it is not only the one (or more) binary files that are passed, but also some header information, file names, and so on. The packaged data may be fine if it is parsed as text data, but a single error in the binary data may result in a corrupted entire file. And file uploads have a history in our Java Web stack:

Prior to Servlet 3.0, file uploads were received on the server side using Request.getinputStream () to retrieve binary data from the form, but were cumbersome and complex to parse. For file upload such a very basic module in the receiving time may cost a lot of cost and energy to solve it, and many primary siege lion is likely to be unfamiliar with IO module cannot achieve the upload file in the server side receiving.

Therefore, some responsible companies and organizations have contributed their parsing methods for everyone to use, and we do not need to understand the underlying content of the file transfer. Among these open source processing methods, the most popular are Commons – Fileupload and Commons – IO, which are owned by Apache. Add two JAR packages to the project and you’ll see how the API works. With these two JARS, you can easily upload files in a normal Web project by simply learning the API!

After Servlet 3.0, as servlet versions are updated, designers may see problems in Java Web development where the native API support for file uploading is not very friendly, so the support for file uploading in the API has been optimized to simplify Java Web development. In Servlet3.0, Part is mainly added to read file data and information. In Part, the name of the transferred file, header information, binary files are directly separated, and the file upload function can be realized through a simple API. No external JAR packages need to be added.

File upload and download is a common module of Web development, and Springmvc as an excellent Web framework, a lot of modules and content for a higher degree of encapsulation and integration, and so commonly used file upload must be indispensable, So Springmvc uploads files based on apache’s open source commons-Fileupload and Commons-io packages. The secondary integration and encapsulation to Springmvc and the encapsulation of methods and content to the MultipartFile interface make it more convenient for us to use, and it is easy to achieve single file and multi-file upload.

The above file upload server implementations can be roughly shown in the following figure:

From the picture above you can understand the principle of Springmvc file upload implementation, then you can play your hand! Springmvc handles uploading files very simply, we need to create one in the Java directoryuploadController.javaSo I’m going to create this Controller, and I’m going to annotate it with @Controller. Write the following code in Controller:

 @PostMapping("onfile")
 @ResponseBody
 public String onfile(MultipartFile file) throws IOException {
     File file1 =new File("F:/fileupload/"+file.getOriginalFilename());// Create a file object
     if(! file1.exists()) file1.createNewFile();// Create the file on disk
     file.transferTo(file1);// Store the accepted files
     return "sucucess";
 }
Copy the code

Among them:

  • PostMapping(“onfile”) means that the request is POST and the relative address of the requested URL in the project is onfile
  • @responseBody means that instead of returning a Web page, we’re returning a string or json string, and we’re going to use a success word to represent the interface.
  • Public String onFile (MultipartFile File) public String onFile (MultipartFile file) The parameter name (file in this case) should be the same as the name of the front-end interface (input type=”file”,name= name in “file”). Through this interface, you can perform various operations on the file more easily. In this case, the uploaded file is saved to the local F disk.

For several lines of core code in the function, each performs its own functions. In addition to the explanation in the notes, the general process can be referred to as the figure below:

Run the test

To launch the project, type in your browserhttp://localhost:8080/index1.html, select File upload, click Upload and you can see the uploaded file locally.At this point, the single file upload is complete. The front end needs to pay attention to the method type and encType parameter of the single file upload, and the server can easily accept the file using the MultipartFile interface.

Multi-file upload

This is about single file uploads, and a lot of times you’re going to need more than just single file uploads. For example, you must be familiar with this page:

As you can see above, this file uploads more than one image at a time, and the number is uncertain, but all belong to the same name and collection of content. This is multi-file uploading. This situation is easy to handle both on the front end and the server side.

The front end design

To upload multiple images, create an index2.html page in static directory. The specific contents are as follows:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Multi-file upload</title>
</head>
<body>
<h2>Upload multiple files in the same category</h2>
<form name="onfile"  action="onfiles2" method="post" enctype="multipart/form-data">Image:<input type="file" name="img"><br>
    <input type="file" name="img"><br>
    <input type="file" name="img"><br>
    <input type="file" name="img"><br>
    <input type="submit" value="Submit">
</form>
</body>
</html>
Copy the code

The front-end page is then written, where the action will be changed to OnFiles2, which is the interface to be written on the server. Also notice that all of these input types are file and all of them are img which means upload a collection of images named IMG.

Server Design

On the server side, we can actually receive such multiple files with the array MultipartFile[]. We write the following code in the controller:

@PostMapping("onfiles2")
@ResponseBody
public String onfiles2(MultipartFile img[]) throws IOException {
   for(int i=0; i<img.length; i++) {if(! img[i].isEmpty())// The file is not empty
       {
           File imgfile =new File("F:/fileupload/"+img[i].getOriginalFilename()); imgfile.createNewFile(); img[i].transferTo(imgfile); logger.info(img[i].getOriginalFilename()); }}return "sucucess";
}
Copy the code

This process is similar to the previous one, except that each file is received through MultipartFile[], except when the file is empty.

Run the test

Open the browser like this and type:http://localhost:8080/index2.html, upload file test effect:

Such a set of similar photo album upload function is complete, of course, the actual development of file upload requirements must be strict than this lot, might be in the format of the file, have a certain size according to your request, this requires you to on the front end and the service side should be the file suffix, validated the information such as size, in order to achieve their scene demand.

File download

File download estimate you will often encounter in daily life, and you download is actually the server (server) resources, there are a variety of file types, the browser can also identify a lot of resources, in fact, you are now visiting the web page is the server HTML files, image files and other resources, However, these resources can be displayed by the browser rather than saved locally.

Direct access to resources vs. download resources

If you access resources that cannot be parsed by the browser, such as doc and ZIP files, the resources are downloaded to the local PC by default. When you use downloads in Springmvc, whatever resources are returned to the client as downloads. The difference can be seen in the following figure:

In the implementation of file download, servlet itself is also to achieve file download, but it is a little cumbersome to use. The idea is to write a section to the output stream of an HttpServletResponse Response. Springmvc encapsulates the file download in the ResponseEntity class, which makes it easy for us to use. Here is the actual file download function.

First, we create the Download folder on disk F and add corresponding files in it. This folder is our resource on the server side.

The front end design

Create index3.html in static directory (index3.html)

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Springmvc file download</title>
</head>
<body>
<h2>Springmvc file download</h2>Personal photo<a href="/download/ personal photograph.png">Personal photo. PNG</a><br>Personal resume<a href="/download/ resume. PDF">Resume. PDF</a>
</body>
</html>
Copy the code

Href is the hyperlink to download, download is the interface name to download, and at the end of the link is the name of the resource to download.

Server Design

The file download works by the server returning binary streams and information to the client, and Springmvc does this via ResponseEntity. We write the following interface in controller to implement the download function:

@GetMapping("download/{filename}")
public ResponseEntity<byte[]>download(@PathVariable String filename) throws IOException {
    // Download file path (absolute path here)
    String filepath= "F:/download/"+filename;
    File file =new File(filepath);
    // Create a stream of byte input. Buffer is not used here
    InputStream in = new FileInputStream(file);
    //available: Gets the maximum number of bytes of the file read by the input stream
    byte[] body = new byte[in.available()];
    // Read bytes into an array
    in.read(body);
    // Set the request header
    MultiValueMap<String, String> headers = new HttpHeaders();
    headers.add("Content-Disposition"."attchement; filename=" + file.getName());
    // Set the response status
    HttpStatus statusCode = HttpStatus.OK;
    in.close();
    ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(body, headers, statusCode);
    return entity;/ / return
}
Copy the code

That’s how you download files. If you download files using a traditional servlet, you might need to set all kinds of information in the HttpServletResponse Response. The ResponseEntity of Springmvc only needs to set the binary body, header information and status code of the file to download the file, which is better in ease of use and simplicity.

Run the test

Open your browser and enter:http://localhost:8080/index3.html; Click the file to download, and the function of file download is realized. The running picture is as follows:

At this point you have encountered a very common file download problem: the Chinese file name is displayed incorrectly. This solution is also easy to solve by urL-encoding the filename following the Content-Disposition Content with (replace the above for the part) :

headers.add("Content-Disposition"."attchement; filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
Copy the code

Restart the program, refresh the page and click the download link again. You should see that the file has been downloaded successfully:

Summary and Expansion

Now that you’ve mastered Springmvc’s single file uploads, multiple file uploads, and file downloads, are you ready to build your own little website and put it in? But Springmvc file upload and download although simple, but you still need to master its principle, learn IO file transfer in Java, so that in various scenarios of file transfer tasks can be competent.

conclusion

indicates that the client wants to upload a file, while the server uses either MultipartFile or MultipartFile[] to receive a single file or multiple files, respectively. In the case of local storage, you only need to create the corresponding file on the local disk and call transferTo() method MultipartFile to save the uploaded file.

The front end of file download needs a url link for the request, and the server needs to write the interface corresponding to this link. ResponseEntity returns the binary file to the client for file download. ResponseEntity is very easy to use when you create it and you just pass in the binary body and the header and the status code and you can return it successfully, and these Springmvc things are pretty well wrapped up and you can just use them.

Whether file upload, multiple file upload or file download, a complete case generally requires this process:

  • Formulate requirements and general page styles
  • Write front-end HTML pages
  • Write the request that the server responds to
  • Start the program to run the tests

If there is a problem in the process, you can find the root cause according to the error prompt of the compiler and the error log of the runtime to fix it, so that the complete case can be successfully completed!

Case development

Do you think you got it right? Well, let’s expand and improve. I’ll give you a requirement: single file and multiple file mixed upload

Suppose Xiao Ming needs to implement a file upload function, and he needs to upload a resume and several photos (less than 3). How should this project be designed? Its plan page might look something like this:

I think you’re smart enough not to be stumped. What do you think about HTML in the front end?

There are two kinds of documents for categories: resume and photo. For each of them, there is only one resume and there may be multiple photos.

So our HTML page can be designed like this:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Upload personal Information</title>
</head>
<body>
<h2>Upload personal Information</h2>
<form name="onfile"  action="infoupload" method="post" enctype="multipart/form-data">Name:<input type="text" name="name" ><br>Age:<input type="text" name="age"> <br>Image:<input type="file" name="img">
         <input type="file" name="img">Resume:<input type="file" name="resume"><br>
    <input type="submit" value="Submit">
</form>
</body>
</html>

Copy the code

This is different from the single file upload where there are multiple input tags, and the action will be changed to infoupload which means that you need to write an interface to handle the file upload. Write the following code in Controller:

 private  static Logger logger= LoggerFactory.getLogger(uploadController.class);
    @PostMapping("infoupload")
    @ResponseBody
    public String onfile(String name,String age, MultipartFile img[],MultipartFile resume) throws IOException {
        logger.info(name);// The transfer name is printed in the log
        logger.info(age);
        / / receive img []
        for(int i=0; i<img.length; i++) {if(! img[i].isEmpty())// The file is not empty
            {
                File imgfile =new File("F:/fileupload/"+img[i].getOriginalFilename()); imgfile.createNewFile(); img[i].transferTo(imgfile); }}/ / receive the resume
        File resumefile =new File("F:/fileupload/"+resume.getOriginalFilename());
        // Create a file on disk where the file exists but has no content
        resumefile.createNewFile();
        // Copy the accepted file to the created file
        resume.transferTo(resumefile);
        return "sucucess";
    }

Copy the code

The main difference is that the function has multiple parameters, each of which corresponds to the content of the form input tag on the front page (the same name). The file type in the form corresponds to the MultipartFile type in Springmvc’s Controller, and the text type in the form corresponds to the String type in the Controller. If a single file is uploaded, the server receives it with the MultipartFile type parameter. If multiple files are uploaded, the server receives it with MultipartFile[]. Upload types and numbers are defined according to your own design requirements.

We start the program to open the browser type http://localhost:8080/index4.html select file to upload, then can you see in the local file is saved successfully.

That concludes this article, which briefly explains the implementation of file upload, multi-file upload, and file download in Springmvc, which you are now familiar with. Green mountains do not change, green water flow, we see you next time! Class is over!

Welcome to follow, like! Bigsai is waiting for you to share more.