通用化的处理, 比如说登录的功能,统一的编码问题可以放在过滤器中进行拦截
定义一个类,实现Filter接口
`@WebFilter("/*")
public class FilterDemo1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("servletDFilterDemo执行了");
// 放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}`
2. web.xml 方式的配置
`
demo1
com.liangxin.web.Filter.FilterDemo1
demo1
/*
`
3. 过滤器的执行流程
`WebFilter("/*")
public class FilterDemo2 implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("我是用来执行request请求的 ,我是在放行方法doFilter方法之前执行的");
// 放行
chain.doFilter(req, resp);
System.out.println("在放行之后 ,执行请求资源文件或者路径之后, 再回来执行执行放行之后的方法");
}
public void init(FilterConfig config) throws ServletException {
}
`
4. 过滤器的生命周期
`@WebFilter( "/*")
public class FilterDemo3 implements Filter {
public void destroy() {
System.out.println("我是destroy方法,在服务器关闭的时候我就会被执行, 只会执行一次,常用来释放资源");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("我是doFilter方法, 每次拦截的时候我都会执行一次, 相当于servlet中的service方法, 每次访问我就会执行一次");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
System.out.println("我是init方法,我在服务器启动的时候 就会被执行, 只会执行一次,用来加载资源");
}`
5. 过滤器的配置
1. 拦截路径的配置
1. 具体的资源路径---"/index.jsp"---@WebFilter("/index.jsp")
2. 目录拦截:/user/*--- 在访问/user路径下的所有资源的时候,过滤器就会执行---@WebFilter("/user/findAllServlet")
3. 后缀名拦截:*.jsp --- 再访问后缀名为*.jsp的资源的时候,过滤器就会执行--- @WebFilter("*.jsp")
4. 拦截所有--- "/*"---@WebFilter("/*")
2. 拦截方式的配置:资源被访问的方式
1. 注解配置 设置dispatcherTypes属性
@WebFilter(value = "/index.jsp" ,dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.ASYNC,DispatcherType.ERROR,DispatcherType.FORWARD, DispatcherType.INCLUDE})
1. REQUEST(默认的方式, 浏览器请求)
2. FORWARD 转发
3. INCLUDE 包含
4. ERROR 错误
5. ASYNC 异步
2. web.xml
1. 设置 上面的五个取值
6. 过滤器的配置链
1. 多个过滤器的执行顺序
1. FilterDemo5执行了
FilterDemo6执行了
index.jsp执行了
FilterDemo6回来了执行了
FilterDemo5回来了执行了
2.过滤器的执行先后问题
1. 注解的方式:是根据过滤器的类名字符串的比较,小的先执行(FilterDemo1 < FilterDemo2) demo1先执行
2.web.xml的方式:配置在上面的先执行
`WebFilter( "/*")
public class LoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
// 获取URI 类型强制转换
HttpServletRequest request = (HttpServletRequest) req;
String requestURI = request.getRequestURI();
//判断 是够路径中包含本身就是登录的内容和cssjs数据 有则放行
if (requestURI.contains("/login.jsp") || requestURI.contains("/loginServlet")
|| requestURI.contains("/css") || requestURI.contains("/fonts") || requestURI.contains("/js") || requestURI.contains("/checkCodeServlet")) {
chain.doFilter(request, resp);
} else {
// 判断session中是否有user有的话就放行 没有则转到登录页面
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if (user != null) {
//放行
chain.doFilter(request, resp);
} else {
request.setAttribute("login_msg", "尚未登录,请您登录");
request.getRequestDispatcher("/login.jsp").forward(request, resp);
}
}
// chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}`
` /**
*@描述
*@参数 代理对象动态代理代理对象和真实的对象必须要实现同一个接口
* Proxy.newProxyInstance()参数类型: 真实对象的类加载器, 真实对象实现的所有接口的数组, 和一个执行器
*@返回值
*/
SaleComputer o = (SaleComputer) Proxy.newProxyInstance(dell.getClass().getClassLoader(), dell.getClass().getInterfaces(), new InvocationHandler() {
/**
*@描述 对于代理对象的执行方法都会执行invoke方法,
*@参数 proxy:就是我们的代理对象
* method:在反射中调用的方法会封装成Method对象,
* args:方法的参数数组 --invoke = method.invoke(dell, args);
* 调用方法的时候,
*@返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用方法
if (method.getName().equals("sale")) {
//增强参数
Double money = (Double) args[0];
money *= 0.8;
//在方法之前增强方法
System.out.println("专车接送");
String invoke = (String) method.invoke(dell, money);
//在方法之后增强方法
System.out.println("送货上门");
//增强方法的方返回值
return invoke+"键盘套装";
}else{
Object invoke = method.invoke(dell, args);
return invoke;
}
}
});
// 动态代理增强方法
String sale1 = o.sale(9999.0);
System.out.println(sale1);
}
}`
@WebFilter("/*")
public class SensitiveWordFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//1.创建代理对象,增强getParameter方法
ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增强getParameter方法
//判断是否是getParameter方法
if(method.getName().equals("getParameter")){
//增强返回值
//获取返回值
String value = (String) method.invoke(req,args);
if(value != null){
for (String str : list) {
if(value.contains(str)){
value = value.replaceAll(str,"***");
}
}
}
return value;
}
//判断方法名是否是 getParameterMap
//判断方法名是否是 getParameterValue
return method.invoke(req,args);
}
});
//2.放行
chain.doFilter(proxy_req, resp);
}
private List list = new ArrayList();//敏感词汇集合
public void init(FilterConfig config) throws ServletException {
try{
//1.获取文件真实路径
ServletContext servletContext = config.getServletContext();
String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
//2.读取文件
BufferedReader br = new BufferedReader(new FileReader(realPath));
//3.将文件的每一行数据添加到list中
String line = null;
while((line = br.readLine())!=null){
list.add(line);
}
br.close();
System.out.println(list);
}catch (Exception e){
e.printStackTrace();
}
}
public void destroy() {
}
}`
1. 事件监听机制(事件 事件源, 监听器 )
2. 注册监听:将事件事件源监听器绑定在一起,当事件源发生某事件的时候,执行监听器代码
3. ServletContextListenter(对象)
1. 使用注解的方式配置
1. `@WebListener("/servletContextListenerDemo")
public class ServletContextListenterDemo implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//在服务器启动会自动调用
//通常用来加载资源文件
ServletContext servletContext = servletContextEvent.getServletContext();
String realPath = servletContext.getRealPath("获取在web.xml中配置的资源路径 t通常用来加载全局的资源文件");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//在服务器正常关闭后 ,被执行,销毁
}
}`
3.使用Web.xml配置
com.liangxin.web.Filter.FilterDemo1