session and cookie of Java Web

Keywords: Java

summary
This blog post mainly discusses the following contents:

  • Session
  • Cookie
  • File upload and download

Session

session management

HTTP protocol is a stateless protocol
Session: a session is an uninterrupted sequence of requests and responses between a client and a server.
Using the HttpSession object

  1. Create or return the session object associated with the customer request
HttpSession session = request.getSession(true);
  1. Add or remove the name / value pair attribute in the session object
Integer accessCount = (Integer)session.getAttribute("accessCount");
  1. Invalidate the session if necessary
session.invalidate();

Cookie

Cookies are the information stored by the server on the client's hard disk when the client accesses the Web server, which seems to be a "snack" given by the server to the client. A Cookie is actually a piece of text information. When a client accesses the same Web server in the future, the browser will send them to the server as they are.

1. Send cookies to clients

  1. Create Cookie object
Cookie userCookie = new Cookie("username","hacker");
  1. Set the maximum lifetime of cookies
userCookie.setMaxAge(60*60*24*7);//Set to one week
  1. Send Cookie object to customer
response.addCookie(userCookie);

2. Read cookies from the client

  1. Call the getCookies method of the request object, which returns an array of Cookie objects
Cookie [] cookies = request.getCookies();
  1. Loop over Cookie array
String cookieName = "username";
String cookieValue = null;
Cookie [] cookies = request.getCookies();
if(cookies!=null){
	for(int i = 0; i<cookies.length; i++){
		Cookie cookie = Cookies[i];
		if(cookie.getName().equals(cookieName))
			cookieValue = cookie.getValue();
	}
}

File upload and download

Import the relevant support jar packages: commons-fileupload.jar,commons-io.jar
For file upload, the browser submits the file to the server in the form of stream during the upload process. It is troublesome to directly use Servlet to obtain the input stream of the uploaded file and then parse the request parameters. Therefore, the file upload component of apache's open source tool common fileUpload is generally selected. The jar package of the common file upload upload component can be downloaded from the apache official website or found under the lib folder of struts. The function of struts upload is based on this implementation. Common file upload depends on the common IO package, so you also need to download this package. Because I use maven to manage the project, I need to configure it in the pom file (the location of everyone's jar package depends on the actual situation)
XML code

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>

1. File upload

File upload page and message prompt page
upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>File upload</title>
</head>
<body>
     <form action="${pageContext.request.contextPath}/Servlet/UploadhandleServlrt" enctype="multipart/form-data" method="post">
         Upload user:<input type="text" name="username"> <br/>
         Upload file 1:<input type="file" name="file1" id="file1"><br/>
         Upload file 2:<input type="file" name="file2" id="file2"><br/>
         <input type="submit" value="upload">
     </form>
</body>
</html>

message.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Message prompt</title>
</head>
<body>
      ${message}
</body>
</html>

Servlet handling file upload

package com.demo;


import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.UUID;

public class UploadHandleServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //Get the storage directory of the uploaded files, store the uploaded files in the WEB-INF directory, and do not allow direct access from the outside world to ensure the safety of the uploaded files
        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        //Save directory of temporary files generated during upload
        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        File tempfile = new File(tempPath);
        if (!tempfile.exists() && !tempfile.isDirectory()) {
            System.out.println(savePath + "Directory does not exist, need to create!");
            //Create temporary directory
            tempfile.mkdir();
        }
        //Message prompt
        String message = "";
        try {
            //Using Apache file upload component to process file upload steps:
            //1. Create a DiskFileItemFactory factory
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //Set the buffer size of the factory. When the uploaded file size exceeds the buffer size, a temporary file will be generated and stored in the specified temporary directory.
            factory.setSizeThreshold(1024 * 100);
            //Set the saving directory of temporary files generated during uploading
            factory.setRepository(tempfile);
            //2. Create a file upload parser
            ServletFileUpload upload = new ServletFileUpload(factory);
            //Monitor file upload progress
            upload.setProgressListener(new ProgressListener() {
                @Override
                public void update(long l, long l1, int i) {
                    System.out.println("File size:" + l1 + ",Currently processed:" + l);
                }
            });
            //Solve the Chinese garbled code of uploaded file name
            upload.setHeaderEncoding("UTF-8");
            //3. Judge whether the submitted data is the data of the uploaded form
            if (!ServletFileUpload.isMultipartContent(req)) {
                //Get data in the traditional way
                return;
            }
            //Set the maximum size of a single file to be uploaded. At present, it is set to 1024 * 1024 bytes, that is, 1MB
            upload.setFileSizeMax(1024 * 1024);
            //Set the maximum value of the total number of uploaded files. The maximum value = the sum of the maximum sizes of multiple files uploaded at the same time. At present, it is set to 10MB
            upload.setSizeMax(1024 * 1024 * 10);
            //4. The servlet fileUpload parser is used to parse the uploaded data. The parsing result returns a list < FileItem > collection, and each FileItem corresponds to an input item of the Form
            List<FileItem> list = upload.parseRequest(req);
            for (FileItem item : list) {
                //If the fileitem encapsulates the data of ordinary input items
                if (item.isFormField()) {
                    String name = item.getFieldName();
                    //Solve the Chinese garbled code problem of data of common input items
                    String value = item.getString("UTF-8");
                    System.out.println(name + " = " + value);
                } else {
                    //If the uploaded file is encapsulated in fileitem
                    //Get the name of the uploaded file
                    String filename = item.getName();
                    System.out.println(filename);
                    if (filename == null || filename.trim().equals("")) {
                        continue;
                    }
                    filename = filename.substring(filename.lastIndexOf("\\") + 1);
                    //Get the extension of the uploaded file. If you need to limit the uploaded file type, you can judge whether the uploaded file type is legal through the file extension
                    String fileTye = filename.substring(filename.lastIndexOf(".") + 1);
                    System.out.println("The extended name of the uploaded file is: " + fileTye);
                    //Get the input stream of the uploaded file in item
                    InputStream in = item.getInputStream();
                    //Get the name of the file to save
                    String saveFileName = makeFileName(filename);
                    //Get the save directory of the file
                    String realSavePath = makePath(saveFileName, savePath);
                    //Create a file output stream
                    FileOutputStream out = new FileOutputStream(realSavePath + "\\" + saveFileName);
                    //Create a buffer
                    byte buffer[] = new byte[1024];
                    //Identification to judge whether the data in the input stream has been read
                    int len = 0;
                    //The loop reads the input stream into the buffer, (len = in. Read (buffer)) > 0 indicates that there is data in the in
                    while ((len = in.read(buffer)) > 0) {
                        //Use the FileOutputStream output stream to write the buffer data to the specified directory (savePath + "\" + filename)
                        out.write(buffer, 0, len);
                    }
                    //Close input stream
                    in.close();
                    //Close output stream
                    out.close();
                    //Delete temporary files generated when processing file upload
                    item.delete();
                    message = "File uploaded successfully";
                }
            }
        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            message = "Single file exceeds maximum!!!";
            e.printStackTrace();
            req.setAttribute("message", message);
            req.getRequestDispatcher("/message.jsp").forward(req, resp);
            return;
        } catch (FileUploadBase.SizeLimitExceededException e) {
            message = "The total size of uploaded files exceeds the maximum limit!!!";
            e.printStackTrace();
            req.setAttribute("message", message);
            req.getRequestDispatcher("/message.jsp").forward(req, resp);
            return;
        } catch (Exception e) {
            message = "File upload failed!";
            e.printStackTrace();
        }
        req.setAttribute("message", message);
        req.getRequestDispatcher("/message.jsp").forward(req, resp);

    }

    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    /**
     * Generate the file name of the uploaded file. The file name is: uuid + "" + the original name of the file
     * @param filename
     * @return
     */
    private String makeFileName(String filename) {
        return UUID.randomUUID().toString() + "_" + filename;
    }

    /**
     * In order to prevent too many files under a directory, hash algorithm should be used to break up the storage
     * @param filename
     * @param filePath
     * @return
     */
    private String makePath(String filename, String filePath) {
        int hashcode = filename.hashCode();
        int dir1 = hashcode & 0xf;
        int dir2 = (hashcode&0xf0) >> 4;
        String dir = filePath + "\\" + dir1 + "\\" + dir2;
        File file = new File(dir);
        if (!file.exists()) {
            file.mkdirs();
        }
        return dir;
    }
}

File upload details

  1. In order to ensure the security of the server, the uploaded files should be placed in a directory that cannot be directly accessed by the outside world, such as the WEB-INF directory.
  2. To prevent file overwriting, a unique file name should be generated for the uploaded file.
  3. In order to prevent too many files under a directory, hash algorithm should be used to break up the storage.
  4. To limit the maximum number of uploaded files.
  5. To limit the type of uploaded file, judge whether the suffix is legal when receiving the uploaded file name.

Configure the UploadHandleServlet in the Web.xml file

   <servlet>
        <servlet-name>UploadhandleServlrt</servlet-name>
        <servlet-class>com.demo.UploadHandleServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UploadhandleServlrt</servlet-name>
        <url-pattern>/Servlet/UploadhandleServlrt</url-pattern>
    </servlet-mapping>

2. File download

Lists the file resources available for download

package com.demo;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


public class ListFileServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        Map<String, String> fileNameMap = new HashMap<String, String>();
        listfile(new File(uploadFilePath), fileNameMap);
        req.setAttribute("fileNameMap", fileNameMap);
        req.getRequestDispatcher("/listfile.jsp").forward(req, resp);
    }

    public void listfile(File file, Map<String, String> map) {
        if (!file.isFile()) {
            File files[] = file.listFiles();
            for (File f : files) {
                listfile(f, map);
            }
        } else {
            String realName = file.getName().substring(file.getName().indexOf("_") + 1);
            map.put(file.getName(), realName);
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

Briefly, the listfile method in ListFileServlet is used to list all files in the directory. Recursion is used inside the listfile method. In actual development, we will certainly create a table in the database, which will store the uploaded file name and the specific storage directory of the file. We can know the specific storage directory of the file through the query table, Recursive operation is not required. In this example, the database is not used to store the uploaded file name and the specific storage location of the file, and the storage location of the uploaded file is scattered by the hash algorithm. Therefore, recursion is required. During recursion, the obtained file name is stored in the Map set passed from the outside to the listfile method, This ensures that all files are stored in the same Map set.
Realize file download

package com.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



public class DownLoadServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //Get the file name to download
        String fileName = request.getParameter("filename");
        fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
        //All uploaded files are saved in subdirectories under the / WEB-INF/upload directory
        String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
        //Find the directory where the file is located by the file name
        String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
        //Get the file to download
        File file = new File(path + "\\" + fileName);
        //If the file does not exist
        System.out.println(file);
        if(!file.exists()){
            request.setAttribute("message", "The resource you want to download has been deleted!!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
            return;
        }
        //Processing file name
        String realname = fileName.substring(fileName.indexOf("_")+1);
        //Set the response header to control the browser to download the file
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
        //Read the file to be downloaded and save it to the file input stream
        FileInputStream in = new FileInputStream(path + "\\" + fileName);
        //Create output stream
        OutputStream out = response.getOutputStream();
        //Create buffer
        byte buffer[] = new byte[1024];
        int len = 0;
        //Loop reads the contents of the input stream into the buffer
        while((len=in.read(buffer))>0){
            //Output the contents of the buffer to the browser to realize file download
            out.write(buffer, 0, len);
        }
        //Close file input stream
        in.close();
        //Close output stream
        out.close();
    }

    /**
     * @Method: findFileSavePathByFileName
     * @Description: Find the path of the file to be downloaded through the file name and the root directory where the uploaded file is stored
     * @param filename File name to download
     * @param saveRootPath The root directory where the uploaded file is saved, that is, the / WEB-INF/upload directory
     * @return The storage directory of the file to download
     */
    public String findFileSavePathByFileName(String filename,String saveRootPath){
        int hashcode = filename.hashCode();
        int dir1 = hashcode&0xf;  //0--15
        int dir2 = (hashcode&0xf0)>>4;  //0-15
        String dir = saveRootPath + "\\" + dir1 + "\\" + dir2;  
        File file = new File(dir);
        if(!file.exists()){
            //Create directory
            file.mkdirs();
        }
        return dir;
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

The listfile.jsp page showing the downloaded file:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" 	uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML>
<html>
<head>
    <title>Download file display page</title>
</head>

<body>
<!-- ergodic Map aggregate -->
<c:forEach var="me" items="${fileNameMap}">
    <c:url value="/servlet/DownLoadServlet" var="downurl">
        <c:param name="filename" value="${me.key}"></c:param>
    </c:url>
    ${me.value}<a href="${downurl}">download</a>
    <br/>
</c:forEach>
</body>
</html>

Note the two packages of C tags that need to be imported in Maven's pom.xml file!

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
	<groupId>taglibs</groupId>
	<artifactId>standard</artifactId>
	<version>1.1.2</version>
</dependency>

Configure ListFileServlet and DownLoadServlet in the Web.xml file

ListFileServlet
com.demo.ListFileServlet

<servlet-mapping>
    <servlet-name>ListFileServlet</servlet-name>
    <url-pattern>/servlet/ListFileServlet</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>DownLoadServlet</servlet-name>
    <servlet-class>com.demo.DownLoadServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>DownLoadServlet</servlet-name>
    <url-pattern>/servlet/DownLoadServlet</url-pattern>
</servlet-mapping>

Posted by rcoursey on Wed, 24 Nov 2021 12:58:46 -0800