BaseServlet 使用流程,过滤器
1. 案例
// http://localhost:8080/Day45/student?method=addStudent
@WebServlet("/student")
public class StudentControllerServlet extends BaseServlet {
public String addStudent(HttpServletRequest req, HttpServletResponse resp) {
}
}
public abstract class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 请求编码集和响应编码集统一为 UTF-8
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
// 获取用户请求参数中的方法名称,明确方法执行目标
String methodName = req.getParameter("method");
try {
// 指定对应目标方法,得到目标转发路径
String path = (String) this.getClass()
.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class)
.invoke(this, req, resp);
// 如果有返回 path 内容需要完成转发操作,如果没有不执行任务
if (path != null) {
req.getRequestDispatcher(path).forward(req, resp);
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
}
}
2. 过滤器
2.1 过滤器作用
在 Web 项目中,很多资源需要对用户信息进行校验之后,才可以给予用户访问,例如:
用户的订单详情,订单列表,地址信息,购物车...
都是需要用户登陆之后才可以得到对应的数据响应,或者说访问权限。
目前咱们的小项目所有的资源都是完全敞开,只要知道路径,资源都可以直接访问。
该功能需要 Java WEB 三大组件之一的 Filter 来完成对应功能 ==> 过滤器
tips:
Java WEB 三大组件
Servlet, Filter, Listener
2.2 过滤器 必要方法
过滤器需要遵从接口
javax.servlet.Filter
必须实现的方法:
doFilter(ServletRequest request, ServletResponse response, FilterChain chain);
过滤器核心方法,request和response 是Tomcat服务器对应用户请求 和 给予对应响应
FilterChain 过滤器放行方法执行对象 ==> doFilter(ServletRequest request, ServletResponse response)
非必要方法 默认方法
init(FilterConfig filterConfig);
对当前过滤器对象进行初始化操作,可以用于增强当前过滤器能力,一定的参考参数
【功能】
敏感词汇过滤器
王乾 ==> **
国粹 ==> **
*************************************
init方法来读取敏感词汇限制信息类初始化过滤参数
同时利用【代理机制】来处理用户提交数据
void destroy()
销毁过滤器对象。
2.3 过滤使用流程
1. 明确限制资源路径,资源名称
哪些需要限制操作,哪些不限制操作
例如
用户详情,用户订单,购买操作 需要过滤,用户未登录不能操作
搜索信息,主页访问,商品详情 可以不用于过滤,用户未登录也可以操作
@WebFilter();
String[] value
String[] urlPatterns
用于配置当前 过滤器限制的资源路径,数据形式为 数组
/* 整个 Web Application 所有资源全部过滤
2. 需要按照自定义过滤器规则,完整放行操作。
在 doFilter 中完成规则限制,一般情况下,可以根据用户请求资源路径,以及其他辅助数据来判断是否放行。
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("AFilter in");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
System.out.println("用户请求资源: " + req.getRequestURL());
// 放行当前用户请求
String requestURI = req.getRequestURI();
// 有且只放行资源带有 aServlet 内容
if (requestURI.contains("aServlet")) {
chain.doFilter(req, resp);
} else {
resp.getWriter().append("<h1>Forbidden Resources</h1>");
}
System.out.println("AFilter out");
}
3. 可以限制过滤器过滤资源路,完成不同的过滤器限制范围
资源:
/user
/user/orderList
@WebFilter("/user")
/user 过滤器工作
/user/orderList 过滤器不工作,当前过滤器不限制
@WebFilter(value = {"/user", "/user/orderList"})
/user 过滤器工作
/user/orderList 过滤器工作
@WebFilter("/user/*")
/user 过滤器工作
/user/orderList 过滤器工作
2.4 过滤器链
同一个资源需要多重过滤限制,采用 @WebFilter 注解方式配置,按照过滤器的类名字段字典排序。如果采用 @WebFilter 方式限制过滤资源内容,可以考虑利用首字母限制过滤器优先级问题
案例:
完成需要在登陆之后才可以访问其他资源
1. 登陆判断过滤器
2. 编码集过滤器
3. 敏感词汇过滤器
购物网站,搜索功能
1. 编码集过滤器
2. 敏感词汇过滤器
仅限制需要登陆的资源通过过滤器限制。
2.5 过滤器案例
2.5.1 编码集过滤器
package com.qfedu.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Anonymous 2022/4/22 16:49
*/
// 限制所有资源都需要通过编码集过滤器处理
@WebFilter("/*")
public class AEncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 1. 强转数据类型
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
/*
2. 仅修用户请求编码集,最终给予用户的响应数据内容和编码形式具体业务逻辑,具体分析
该过滤器是一个简配版过滤,有且只能处理 Tomcat 8 Tomcat 9 请求编码
如果是 Tomcat 7 需要其他方式处理编码集
*/
req.setCharacterEncoding("UTF-8");
// 3. 放行用户请求
chain.doFilter(req, resp);
}
}