拦截请求,过滤响应
实现 Filter 接口
根据过滤器的配置方式分别
配置文件(web.xml)配置,执行顺序由标签的配置顺序决定
注解配置,执行顺序由filterName属性值的字母顺序决定
无法实现Filter接口
找到apache-tomcat-8.5.75->lib->Servlet-api.jar导入
- @WebFilter(urlPatterns = {"/*"})
- public class CharsetFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- }
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- servletRequest.setCharacterEncoding("UTF-8");
- servletResponse.setCharacterEncoding("UTF-8");
- servletResponse.setContentType("text/html;charset=UTF-8");
- filterChain.doFilter(servletRequest, servletResponse);
- }
- @Override
- public void destroy() {
- }
- }
web.xml配置Filter
- <filter>
- <filter-name>Charserfilter-name>
- <filter-class>com.xxx.controller.filter.CharsetFilterfilter-class>
- filter>
- <filter-mapping>
- <filter-name>Charserfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
- @WebFilter(urlPatterns = {"*.do"})
- public class BanFilter implements Filter {
- // 存放违规字符的集合
- private List
words = new ArrayList<>(); -
- // 加载时读取文件字符存入集合
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\Knowledge\\编程\\00-资料库\\05-File\\words.txt"), "utf-8"))) {
- String str = null;
- while ((str = reader.readLine()) != null) {
- words.add(str);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- // 过滤违规字符
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- String text = servletRequest.getParameter("text");
- // 创建请求对象的代理对象,
- // 在代理对象的方法执行过程中判断当前方法是不是getParameter
- // 是则获取值进行相应修改
- // 最后将代理传递给servlet
- ServletRequest requestProxy = (ServletRequest) Proxy.newProxyInstance(servletRequest.getClass().getClassLoader(),
- servletRequest.getClass().getInterfaces(), new InvocationHandler() {
- // method:真实对象调用某个方法的方法对象
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- // 调用真实对象方法
- Object returnValue = method.invoke(servletRequest, args);
- // 获取真实对象调用的方法的方法名
- String methodName = method.getName();
- if (methodName.equals("getParameter")) {
- String value = (String) returnValue;
- for (String word : words) {
- if (value.contains(word)) {
- value = value.replace(word, "*");
- }
- }
- return value;
- }
- return returnValue;
- }
- });
- // 放行时传递的是代理对象
- filterChain.doFilter(requestProxy,servletResponse);
- }
-
- @Override
- public void destroy() {
-
- }
- }
基于会话完成登录状态的保存,向系统中发送请求时,通过过滤器拦截请求,验证会话中是否存储了登录状态,如果有,则放行,如果没有,则重定向到登录页面(登录成功必须向会话对象中保存登录状态)
重点在登录校验过滤器的url-pattern的配置上
- // 对特定资源进行登录校验
- @WebFilter(urlPatterns = "*.do")
- public class LoginFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {}
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- HttpServletRequest req = (HttpServletRequest) servletRequest;
- HttpServletResponse resp = (HttpServletResponse) servletResponse;
- // 获取Session值
- Object loginUser = req.getSession().getAttribute("user");
- // 未登录状态
- if (null == loginUser) {
- // 跳转回主页面
- resp.sendRedirect("/html/main.html");
- // 登录状态
- } else {
- // 放行
- filterChain.doFilter(req, resp);
- }
- }
- @Override
- public void destroy() {}
- }
重点在需要放行的资源上
- // 对所有资源进行登录校验
- @WebFilter(urlPatterns = {"/*"})
- public class LoginFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {}
- // 在该方法内部完成登录校验
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- HttpServletRequest req = (HttpServletRequest) servletRequest;
- HttpServletResponse resp = (HttpServletResponse) servletResponse;
- // 获取请求地址,如:@WebServlet("/test.do") == /test.do
- String requestURI = req.getRequestURI();
- if (requestURI.endsWith("login.jsp")
- || requestURI.endsWith("register.jsp")
- || requestURI.endsWith("login.do")
- || requestURI.endsWith("register.do")
- ) {
- //请求特定资源放行
- filterChain.doFilter(req,resp);
- //其它所有的请求和页面都必须进行登录校验
- }else{
- Object loginUser = req.getSession().getAttribute("User");
- //没有登录:打回
- if (null == loginUser) {
- resp.sendRedirect("/html/login.html");
- //登录过了:放行
- }else{
- filterChain.doFilter(req,resp);
- }
- }
- }
- @Override
- public void destroy() {}
- }