servlet實現文件上傳下載以及Filter過濾器使用

servlet實現上傳下載

文件上傳頁面三要素
  • 提供form表單,method必須是post
  • form表單的enctype必須是multipart/form-data
  • 提供 input type=“file” 類型輸入

jar包:
commons-fileupload.jar
commons-io.jar

文件上傳:
主流程類:

package com.booy;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
//文件上傳
@WebServlet(name = "uploadServlet",value = "/uploadServlet")
//文件註解,註解必須寫,文件大小限制,不寫參數默認不限制大小
@MultipartConfig(maxFileSize = 1024*1024*10,maxRequestSize = 1024*1024*100)
public class uploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //設置編碼
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //輸出流
        PrintWriter out = response.getWriter();
        //接收文件
        Collection<Part> parts = request.getParts();
        //文件保存的位置
        String basePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File dir = new File(basePath);
        //如果沒有文件夾就創建
        if(!dir.exists()){
            dir.mkdirs();
        }
        if(parts!=null){
            for (Part part:parts){
                //通過文件名,判斷是文件還是普通項,普通項沒有文件名
                String fileName = part.getSubmittedFileName();
                if(fileName==null){
                    //不是文件就獲取用戶名
                    String name = part.getName();
                    String value = request.getParameter(name);
                    System.out.println(name+"-->"+value);
                }else{
                    System.out.println("文件名是:"+fileName);
                    if(fileName==""){
                        continue;
                    }
                    //通過uuid拼接的新文件名
                    String newFileName = UploadUtils.createNewFileName(fileName);
                    //新文件夾名
                    String newdirname = UploadUtils.createNewPath(basePath, fileName);
                    //保存文件
                    part.write(newdirname+"/"+newFileName);
                    //清理緩存
                    part.delete();
                    //響應內容
                    out.write("<h2>上傳成功:</h2>"+fileName+"<br>");
                }
            }
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

工具類:UploadUtils
文件上傳用到工具類中的文件名和文件夾重新生成方法,文件下載用到了文件查詢方法

package com.booy;

import java.io.File;
import java.util.HashMap;
import java.util.UUID;
//工具操作類
public class UploadUtils {
    //文件重新生成文件名,通過uuid
    public static String createNewFileName(String oldFilename){
        //生成UUID並通過replace方法去掉“-”
        String uuid = UUID.randomUUID().toString().replace("-","");
        //新文件名爲uuid+原文件名
        String newFileName=uuid+"_"+oldFilename;
        return newFileName;
    }
    //文件夾重命名
    public static String createNewPath(String basePath,String oldfileName){
        //獲取舊文件名的hashCode
        int hashCode = oldfileName.hashCode();
        //舊文件名的hashCode取後四位
        int dir1 = hashCode&0xf;
        //舊文件名的hashCode取第二個後四位
        int dir2 = (hashCode&0xf0)>>>4;
        //拼接新的文件路徑
        String newPath = basePath+"/"+dir1+"/"+dir2;
        //如果沒有就創建文件夾
        File dir = new File(newPath);
        if(!dir.exists()){
            dir.mkdirs();
        }
        return newPath;
    }
    //查找文件夾下面的文件放於Map集合中
    public static void listFiles(File dir, HashMap<String, String> map){
        //獲取文件對象列表
        File[] files = dir.listFiles();
        //判斷文件列表不爲空
        if(files!=null){
            //遍歷文件列表
            for(File file:files){
                //如果是文件夾繼續遍歷
                if(file.isDirectory()){
                    listFiles(file,map);
                }else{
                    //獲取文件的帶uuid的名稱
                    String uuidfilename = file.getName();
                    //indexOf拆分,截取原來的文件名
                    String filename = uuidfilename.substring(uuidfilename.indexOf("_")+1);
                    //存放Map中
                    map.put(uuidfilename,filename);
                }
            }
        }
    }
}

jsp頁面上傳展示:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上傳</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/uploadServlet" enctype="multipart/form-data" method="post">
    上傳用戶:<input type="text" name="username"><br/>
    上傳文件1:<input type="file" name="file1"><br/>
    上傳文件2:<input type="file" name="file2"><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

文件下載:
主流程類

package com.booy;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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;

@WebServlet(name = "ListFileServlet", value = "/ListFile")
public class ListFileServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //定義集合遍歷文件
        HashMap<String, String> hashMap = new HashMap<>();
        //獲取文件路徑
        String basePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        //查找文件
        UploadUtils.listFiles(new File(basePath),hashMap);
        //把文件寫入域中
        request.setAttribute("maps",hashMap);
        //轉發到指定頁面處理
        request.getRequestDispatcher("/list.jsp").forward(request,response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

下載功能類:

package com.booy;

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

//文件下載
@WebServlet(name = "DownServlet",value ="/down")
public class DownServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //設置字符編碼
        request.setCharacterEncoding("utf-8");
        //獲取帶UUID的文件名
        String uuidfilename = request.getParameter("filename");
        //設置文件夾基本位置
        String basePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        //如果帶UUID的文件名不爲空,並且去掉左右空格的長度不爲0才進行下面操作
        if(uuidfilename!=null&&uuidfilename.trim().length()!=0){
            //_爲分隔符截取出不帶UUID的文件名
            //uuidfilename.substring(0,uuidfilename.indexOf("_"));截取_前面的
            String filename = uuidfilename.substring(uuidfilename.indexOf("_") + 1);
            //獲取新的文件夾路徑
            String newPath = UploadUtils.createNewPath(basePath, filename);
            //創建file
            File file = new File(newPath+"/"+uuidfilename);
            if(file.exists()){
                ServletOutputStream os = response.getOutputStream();
                //響應頭設置下載
                response.setHeader("content-disposition","attachmen;filename="+ URLEncoder.encode(filename,"utf-8"));
                FileInputStream fis = new FileInputStream(file);
                byte[] bytes = new byte[1024*4];
                int len = -1;
                while ((len=fis.read(bytes))!=-1){
                    os.write(bytes,0,len);
                }
            }else{
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("文件已刪除");
            }
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
    }
}

jsp展示頁

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>文件下載</title>
</head>
<body>
<h2>下載列表</h2>
<c:forEach var="entry" items="${maps}">
    ${entry.value} <a href="${pageContext.request.contextPath}/down?filename=${entry.key}">下載</a>
</c:forEach>
</body>
</html>

過濾器
Filter也稱之爲過濾器,它是Servlet技術中最激動人心的技術,WEB開發人員通過Filter技術,對web服務器管理的所有web資源:例如Jsp, Servlet, 靜態圖片文件或靜態html文件等進行攔截,從而實現一些特殊的功能。例如實現URL級別的權限訪問控制、過濾敏感詞彙、壓縮響應信息等一些高級功能。

Servlet API中提供了一個Filter接口,開發web應用時,如果編寫的Java類實現了這個接口,則把這個java類稱之爲過濾器Filter。通過Filter技術,開發人員可以實現用戶在訪問某個目標資源之前,對訪問的請求和響應進行攔截。

編寫過濾器

1、編寫java類實現Filter接口
2、重寫doFilter方法
3、設置攔截的url

註解式配置

在自定義的Filter類上使用註解@WebFilter(“/*”)

過濾器的攔截匹配路徑通常有三種形式:
(1)精確攔截地址匹配 ,比如/index.jsp
(2)後綴攔截地址匹配,比如*.jsp、.html、.jpg
(3)通配符攔截匹配/*,表示攔截所有、注意過濾器不能使用/匹配。

過濾器鏈
通常客戶端對服務器請求之後,服務器調用Servlet之前會執行一組過濾器(多個過濾器),那麼這組過濾器就稱爲一條過濾器鏈。

每個過濾器實現某個特定的功能,當第一個Filter的doFilter方法被調用時,web服務器會創建一個代表Filter鏈的FilterChain對象傳遞給該方法。在doFilter方法中,開發人員如果調用了FilterChain對象的doFilter方法,則web服務器會檢查FilterChain對象中是否還有filter,如果有,則調用第2個filter,如果沒有,則調用目標資源。

過濾器的優先級

在一個web應用中,可以開發編寫多個Filter,這些Filter組合起來稱之爲一個Filter鏈。這些過濾器的執行順序由filter-mapping的順序決定,前面filter-mapping優先級高於後面的。
注意:
(1)如果爲註解的話,是按照類名的字符串順序進行起作用的
(2)如果web.xml,按照 filter-mapping註冊順序,從上往下
(3)web.xml配置高於註解方式
(4)如果註解和web.xml同時配置,會創建多個過濾器對象,造成過濾多次。

過濾器實現自動登錄:
登錄頁面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登錄</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/LoginServlet" method="post">
    登錄名:<input type="text" name="username" placeholder="請輸入用戶名">
    <br>&nbsp;&nbsp;碼:<input type="text" name="password" placeholder="請輸入密碼">
    <br>
    自動登錄:<input type="checkbox" name="auto">
    <input type="submit" value="提交">
</form>
</body>
</html>

主頁面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  我是主頁,welcom home ${username}!
  </body>
</html>

登錄Servlet:

package com.booy;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Base64;

@WebServlet(name = "LoginServlet",value = "/LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String auto = request.getParameter("auto");
        if(username.equals("booy")&&password.equals("123456")){
            System.out.println("登錄成功");
            request.getSession().setAttribute("username",username);
            if(auto!=null){
                String userInfo = username+"#"+password;
                String base64Info = Base64.getEncoder().encodeToString(userInfo.getBytes());
                Cookie userInfoCookie = new Cookie("userInfo", base64Info);
                userInfoCookie.setMaxAge(60*60*24*7);
                userInfoCookie.setPath("/");
                userInfoCookie.setHttpOnly(true);
                response.addCookie(userInfoCookie);
                System.out.println("自動登錄Cookie創建了");
            }
            response.sendRedirect(request.getContextPath()+"/index.jsp");
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

自動登錄Filter:

package com.booy;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Base64;

@WebFilter(filterName = "AutoFilter",value = "/index.jsp")
public class AutoFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //強轉
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        Object username = request.getSession().getAttribute("username");
        if(username!=null){
            chain.doFilter(req, resp);
        }
        //獲取Cookie
        Cookie[] cookies = request.getCookies();
        if(cookies!=null){
            for(Cookie cookie:cookies){
                if(cookie.getName().equals("userInfo")){
                    String base64Info = cookie.getValue();
                    byte[] decode = Base64.getDecoder().decode(base64Info);
                    String userInfo = new String(decode);
                    System.out.println(userInfo);
                    String[] userInfos = userInfo.split("#");
                    if(userInfos[0].equals("booy")&&userInfos[1].equals("123456")){
                        System.out.println("用戶自動登錄成功");
                        request.getSession().setAttribute("username",userInfos[0]);
                    }else{
                        Cookie cookie1 = new Cookie("userInfo","");
                        cookie1.setMaxAge(0);
                        cookie1.setPath("/");
                        response.addCookie(cookie1);
                    }
                }
            }
        }
        chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章