过滤器
Filter
功能:
1、用来拦截传入的请求和传出的相应。
2、修改或以某种方式处理正在客户端和服务端之间交换的数据流。
如何使用?
与使用Servlet类似,Filter是JavaWeb提供的一个借口,开发者只需要自定义一个类并且实现该接口即可
package com.janeroad.filter;
import javax.servlet.*;
import java.io.IOException;
public class CharacterFilter implements Filter { [@Override](https://my.oschina.net/u/1162528) public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("UTF-8"); filterChain.doFilter(servletRequest,servletResponse); } }
web.xml中配置Filter
<filter>
<filter-name>charcater</filter-name> <filter-class>com.southwind.filter.CharacterFilter</filter-class> </filter> <filter-mapping> <filter-name>charcater</filter-name> <url-pattern>/login</url-pattern> <url-pattern>/test</url-pattern> </filter-mapping>
注意:doFilter方法中处理完业务逻辑之后,必须添加 filterChain.doFilter(servletRequest,servletResponse);
否则请求/相应无法向后传递,一直停留在过滤器中。
Filter的生命周期
当Tomcat启动时,通过反射机制调用Filter的无参构造函数创建实例化对象,同时调用init方法实现初始化,doFilter 方法调用多次,当Tomcat服务关闭的时候,调用destory来销毁Filter对象
无参构造函数:只调用一次,当Tomcat启动时调用(Filter一定要进行配置)
init方法:只调用一次,当Filter的实例化对象创建完成之后调用
doFilter:调用多次,访问Filter的业务逻辑都写在Filter中
destory:只调用一次,Tomcat关闭时调用
同时配置多个Filter,Filter的调用顺序是由web.xml中的配置顺序来决定的,写在上面的配置先调用,因为web.xml是从上到下顺序读取的
<filter>
<filter-name>my</filter-name> <filter-class>com.southwind.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>my</filter-name> <url-pattern>/login</url-pattern> </filter-mapping> <filter> <filter-name>charcater</filter-name> <filter-class>com.southwind.filter.CharacterFilter</filter-class> </filter> <filter-mapping> <filter-name>charcater</filter-name> <url-pattern>/login</url-pattern> <url-pattern>/test</url-pattern> </filter-mapping>
1、MyFilter
2、CharacterFilter
也可以通过注解的方式来简化web.xml中的配置
<filter>
<filter-name>my</filter-name> <filter-class>com.southwind.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>my</filter-name> <url-pattern>/login</url-pattern> </filter-mapping>
等于
@WebFilter("/login")
public class MyFilter implements Filter { }
实际开发中Filter的使用场景:
1、统一处理中文乱码
2、屏蔽敏感词
package com.southwind.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/test") public class WordFilter implements Filter { [@Override](https://my.oschina.net/u/1162528) public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("UTF-8"); //将"敏感词"替换成*** String name = servletRequest.getParameter("name"); name = name.replaceAll("敏感词","***"); servletRequest.setAttribute("name",name); filterChain.doFilter(servletRequest,servletResponse); } }
import javax.servlet.ServletException;
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.IOException; @WebServlet("/test") public class TestServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = (String) req.getAttribute("name"); System.out.println("servlet:"+name); } }
3、控制资源的访问权限
package com.southwind.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebFilter("/download.jsp") public class DownloadFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; HttpSession session = request.getSession(); String name = (String) session.getAttribute("name"); if(name == null){ //不是登录状态 response.sendRedirect("/login.jsp"); }else{ filterChain.doFilter(servletRequest,servletResponse); } } }
文件上传下载
- JSP
1、input的type设置file
2、form表单的method设置post,get请求会将文件名传给服务端,而不是文件本身
3、form表单的enctype设置multipart/form-data,以二进制的形式传输数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form enctype="multipart/form-data" action="/upload" method="post"> <input name="desc" type="text"/><br/> <input name="text" type="file"/><br/> <input type="submit" value="上传"/> </form> </body> </html>
- Servlet
fileupload组件可以将所有的请求信息都解析成FileItem对象,可以通过FileItem对象的操作完成上传,面向对象的思想
package com.janeroad.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; 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.*; import java.util.List; @WebServlet("/upload") public class UploadServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(); ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); List<FileItem> list = servletFileUpload.parseRequest(req); for(FileItem fileItem : list){ if(fileItem.isFormField()){ String name = fileItem.getFieldName(); String value = fileItem.getString("UTF-8"); System.out.println(name+":"+value); }else{ String fileName = fileItem.getName(); long size = fileItem.getSize(); System.out.println(fileName+":"+size+"Byte"); InputStream inputStream = fileItem.getInputStream(); String path = req.getServletContext().getRealPath("file/"+fileName); OutputStream outputStream = new FileOutputStream(path); int temp = 0; while((temp = inputStream.read())!=-1){ outputStream.write(temp); } outputStream.close(); inputStream.close(); System.out.println("上传成功"); } } } catch (FileUploadException e) { e.printStackTrace(); } } }
来源: 真相只有一个