File upload, download and three-tier architecture
1. File upload
- method requires post submission, and get limits the size of the data.
- enctype needs to use multipart/form-data or it will directly error (binary data is required).
- A fifile control is required.
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <span style="color: red">${errorMsg}</span><br/> <form action="/fileType" method="post" enctype="multipart/form-data"> <p>Account number:<input type="text" name="username"/></p> <%--input Note type Choice file That is, an upload file control is selected--%> <p>Head portrait:<input type="file" name="Default"/></p> <input type="submit" value="register"> </form> </body> </html>
Note: getParameter() cannot obtain enctype="multipart/form-data" submitted data.
2. Servlet3.0 File Upload
1. API
HttpServletRequest provides two methods for parsing uploaded files from requests
Return value | Method | Effect |
---|---|---|
Part | getPart(String name) | File used to get the name specified in the request |
Collection | getParts() | Get all the files in the request |
Common methods used in Part s:
Return value | Method | Effect |
---|---|---|
void | write(String fifileName) | Save received files directly to disk |
void | getContentType() | Get file type MIME |
String | getHeader(String name) | Get Request Header Information |
long | getSize() | Get the size of the file |
( To tag the Servlet @MultipartConfig and use getPart() to get the file name d in the request into the Part object, then use the write method to save the file to the specified directory
2. Code examples
@WebServlet("/fileUpload") @MultipartConfig public class FileUploadServlet extends HttpServlet { protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Ordinary control data or getParameter method System.out.println("username:" + req.getParameter("username")); // File Control Data Acquisition Part part = req.getPart("headImg"); // Save to disk part.write("D:/headImg.png"); } }
3. Details of file upload
1. Get the upload file name
( Previously copied files (autobiographies), known file type; Now it is user transfer, program receive, receive the file, which involves saving to disk using what file name and file type, all need to get the file name and file type first. You can use the Part API to get:
Return value | Method | Effect |
---|---|---|
String | getHeader("contentdisposition") | Before Tocmat 8.0, using the request header to get the file name, truncate the string |
String | getSubmittedFileName() | Direct access to file names provided after Tomcat 8.0 |
2. Overwrite existing files with the same file name
( If uploading files with the same name will overwrite files previously uploaded by the server, the solution is to give the file a unique name and make sure it is not overwritten. Here we use UUID.
// File Control Data Acquisition Part part = req.getPart("headImg"); // Get the upload file name String realFileName = part.getSubmittedFileName(); // Get upload file extension String ext = realFileName.substring(realFileName.lastIndexOf(".")); // Generate unique string stitching filenames String fileName = UUID.randomUUID().toString() + ext; // Save to disk part.write("D:/" + fileName);
3. File save location problem
( The file is somewhere on disk, not under the project, and cannot be accessed by using the HTTP protocol. So you need to store the file uploaded by the user in the project to be accessed by the HTTP protocol, and the location path saved cannot be written as an absolute path. What can you do? The absolute path to the ServletContext object can be obtained through the getRealPath("Relative path to folder where uploaded files are saved in the project").
( Create a new folder named upload under the project's web directory and modify the code for UploadServlet.java as follows:
@WebServlet("/fileUpload") @MultipartConfig public class FileUploadServlet extends HttpServlet { protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // File Control Data Acquisition Part part = req.getPart("headImg"); // Get the upload file name String realFileName = part.getSubmittedFileName(); // Get upload file extension String ext = realFileName.substring(realFileName.lastIndexOf(".")); // Generate unique string stitching filenames String fileName = UUID.randomUUID().toString() + ext; // Get the absolute path to the upload directory under the project and stitch it into a file's save path String realPath = getServletContext().getRealPath("/upload") +"/"+ fileName; // Save to disk part.write(realPath); } }
3.1 Unable to get upload directory under Project
This does not work because IDEA tools are deployed using a packaged web project (war), so the location is biased and you need to restore the original directory structure of the web project and adjust the deployment. The adjustment steps are as follows:
-
Create classes directory under WEB-INF to store class files
-
Modify project class file output location to/WEB-INF/class (File -> Project Structure)
-
Adjust project deployment to External Source
After that, you can get the upload directory under your project, but previous redeployments were invalid, and you can use compiling classes instead of redeploying them later.
4. File type constraints
UploadServlet.java
@WebServlet("/fileUpload") @MultipartConfig public class FileUploadServlet extends HttpServlet { protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // File Control Data Acquisition Part part = req.getPart("headImg"); // Determine whether the uploaded file type is legal or not if(!part.getContentType().startsWith("img/")) { req.setAttribute("errorMsg", "Please upload pictures"); req.getRequestDispatcher("/register.jsp").forward(req, resp); return; } String realFileName = part.getSubmittedFileName(); // Get file extension String ext = realFileName.substring(realFileName.lastIndexOf(".")); // Generate unique string stitching filenames String fileName = UUID.randomUUID().toString() + ext; // Get the absolute path to the upload directory under the project and stitch it into a file's save path String realPath = getServletContext().getRealPath("/upload") +"/"+ fileName; // Save to disk part.write(realPath); } }
register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>register</title> </head> <body> <span style="color: red">${errorMsg}</span><br/> <form action="/fileUpload" method="post" enctype="multipart/form-data"> <p>Account number:<input type="text" name="username"/></p> <p>Head portrait:<input type="file" name="headImg"/></p> <input type="submit" value="register"> </form> </body> </html>
5. File Size Constraints
File upload limit size can improve server hard disk usage and prevent users from maliciously uploading files causing server disk resource constraints. You can limit this by setting the @MutipartConfifig property as follows:
- maxFileSize
: Single upload file size limit in bytes - maxRequestSize: Displays the size of the data in the request in bytes
IV. File Download
Save downloads of resources from the server to the user's computer.
1. Simple implementation of file download
Create a new download directory on the web with two resources, dog.rar and cat.rar
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>download</title> </head> <body> <h3>File Download</h3> <a href="/download/dog.rar">dog.rar</a><br/> <a href="/download/cat.rar">cat.rar</a><br/> </body> </html>
2. File download restrictions
( The download function has been implemented, but the file is not safe outside the WEB-INF. Users only need to get the hyperlink to download it. In the actual development, our files usually need user's permission to download, so the file should be placed under the WEB-INF, so users can not access it directly, they must request to be handled by the Servlet. We can write download restriction actions in its service method.
2.1 Mobile Download Resources under WEB-INF
2.2 Modify download.jsp to modify the link address bar for download resources
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>download</title> </head> <body> <h3>File Download</h3> <a href="/download?fileName=dog.rar">dog.rar</a><br/> <a href="/download?fileName=cat.rar">cat.rar</a><br/> </body> </html>
2.3 Writing DownloadServlet.java
Get the corresponding file response to the browser based on the request pass file name parameter.
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //Get the name of the file the user wants to download String fileName = req.getParameter("fileName"); //Get Browser Type String header = req.getHeader("User-Agent"); //Set download file name based on browser type //Trinomial operation String mozilla = header.contains("Mozilla") ? URLEncoder.encode(fileName, "UTF-8") : new String(fileName.getBytes("UTF-8"), "ISO-8859-1"); //Set Download File Name resp.setHeader("Content-Disposition", "attachment;filename=" + mozilla); //Get the path to the file String realPath = req.getServletContext().getRealPath("/WEB-INF/download/"); //Use the copy method of the tool class File to get the file input stream, and the response will be browsed //Files.copy (source file, output) // Path path = Paths.get("C:/", "Xmp");Path is used to represent file paths and files. There are several ways to construct a Path object to represent a file path, or a file: //resp.getOutputStream() responds to an output stream and loads are used to Files.copy(Paths.get(realPath, fileName), resp.getOutputStream()); }
3. Download file name problem (can be used)
By default, the Tomcat server does not tell the browser the name of the file, so you need to set the response header manually to tell the browser the name of the file, as follows:
// Don't forget, just give your browser a recommended name when you know you need to set it up resp.setHeader("Content-Disposition", "attachment;filename=File Name");
Handling file names in
- IE uses URL encoding: URLEncoder.encode (fifileName,'UTF-8')
- Non-IE uses ISO-8859-1 encoding: new String (fifileName.getBytes("UTF-8"), "ISO-8859-1")
See the previous copy for the code
Three-tier architecture
1. Introduction to Three-tier Architecture
( Best practices in Web development: a hierarchical development model (divide and conquer at the technical level). 3-tier architecture: In general, the three-tier architecture is to divide the entire business application into: the presentation layer, the business logic layer, and the data access layer. The purpose of hierarchy is for the idea of "high cohesion and low coupling". In the design of software architecture, hierarchical structure is the most common and important conclusion.
Construct.
- Predentation Layer: MVC, responsible for handling operations related to interface interaction.
- Business Layer: Service responsible for complex business logic calculations and judgments.
- Persistent Layer: DAO responsible for persistent storage of business logic data
2. Business Tier Naming Specification
- Package name:
- Company domain name reversal. Module name. service: Store business interface code.
- Corporate domain name reversal. Module name. service.impl: The implementation class that holds the business-tier interface.
- Class name:
- IXxxService: Business-tier interface, where Xxx represents a corresponding model, such as the name IUserService for manipulating User.
- XxxServiceImpl: The implementation class corresponding to the business-tier interface, such as User, whose name is UserServiceImpl.
- XxxServiceTest: A test class implemented by the business tier.