Day40

Day40

监听器

概念:
监听器用于监听web应用中某些对象信息的创建、销毁、增加,修改,删除等动作的
发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用
监听器对象中的方法。
常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等。

类别:

第一大类:监听请求域、会话域、全局域对象的创建和销毁。

第二大类:监听请求域、会话域、全局域对象的属性的创建、替换、销毁。

第三大类:监听会话域(String key - Object value)里value的绑定和解绑、钝化和活化。

第一大类

监听请求域:

servlet:

package com.qf.servlet;

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("/Servlet01")
public class Servlet01 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("执行Servlet");
    }
}

web.xml:

<listener>
        <listener-class>com.qf.listen.MyServletRequestListener</listener-class>
    </listener>

listener:

package com.qf.listen;

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class MyServletRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        ServletRequest request = servletRequestEvent.getServletRequest();
        System.out.println("请求对象被销毁了"+request);
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        ServletRequest request = servletRequestEvent.getServletRequest();
        System.out.println("请求对象被创建了"+request);
    }
}

注:请求对象的生命周期为,创建:客户端发送请求,服务器会创建请求对象。销毁:服务器返回响应后,会把请求对象、响应对象一并销毁。

监听会话域

注意:查看生命周期要把index.jsp改名或者删除,因为项目启动会默认进入index.jsp,会创建会话对象。

web.xml:(手动调整session销毁时间)

<listener>
        <listener-class>com.qf.listen.MyHttpSessionListener</listener-class>
    </listener>
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

创建一个page01.jsp。

MyHttpSessionListener:

package com.qf.listen;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MyHttpSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("会话对象被创建了"+session.getId());

    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("会话对象被销毁了");
    }
}

注:会话对象的什么周期,创建:服务器使用到了session->request.getSession();销毁:session对象设置的过期时间到后就会被销毁。

思考1:客户端访问html资源是否会创建会话对象?答:不会

思考2:客户端访问jsp资源会创建会话对象?为什么?答:会,因为jsp里9大内置对象中有session对象。

思考3:session对象创建后,客户端发送下一次请求是为什么能找到之前的session对象?答:因为客户端在cookie中存储了session的id->JSESSIONID

思考4:session对象是存活在服务器中的,默认为30分钟的生命周期,可客户端存储的cookie里的JSESSIONID为会话结束时,也就意味着关闭浏览器后,再也找不到之前存储在服务器中的session对象,那怎么解决?

答:设置cookie中JSESSION的过期时间。

package com.qf.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/Servlet01")
public class Servlet01 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Servlet收到请求");
        HttpSession session = request.getSession();
        Cookie cookie = new Cookie("JSESSION",session.getId());
        cookie.setMaxAge(60*30);
        response.addCookie(cookie);
        response.getWriter().println("abc");
    }
}
监听全局域

web.xml:

<context-param>
        <param-name>info</param-name>
        <param-value>abc</param-value>
    </context-param>

<listener>
        <listener-class>com.qf.listen.MyServletContextListener</listener-class>
    </listener>

MyServletContextListener:

package com.qf.listen;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();
        String info = servletContext.getInitParameter("info");
        System.out.println("全局对象被创建了"+"--"+info);
        
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("全局对象被销毁了");

    }
}

注:1.生命周期为项目启动时创建,服务器正常关闭时销毁。

经验:应用场景:

监听全局域对象的创建和销毁,而全局域对象在项目启动时创建,就意味着监听器里的初始化方法在项目启动时就会被调用,所以我们可以把项目初始化的工作放在该方法里。在配置文件中context-param里设置初始数据(建议放在最上面),在监听器的初始化方法中可以用getInitParameter()方法获取数据。

第一大类使用案例-统计在线人数

在全局域监听器中创建:

        servletContext.setAttribute("count",0);

在会话域监听器中统计:

package com.qf.listen;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MyHttpSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("会话对象被创建了"+session.getId());
        ServletContext servletContext = session.getServletContext();
        int count = (int) servletContext.getAttribute("count");
        count++;
        servletContext.setAttribute("count",count);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("会话对象被销毁了");
        HttpSession session = httpSessionEvent.getSession();
        ServletContext servletContext = session.getServletContext();
        int count = (int) servletContext.getAttribute("count");
        count--;
        servletContext.setAttribute("count",count);
    }
}

第二大类

请求属性监听器

MyServletRequestAttributeListener(用注解配置):

package com.qf.listen02;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println("请求域对象添加了属性:"+name+"---"+value);
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println("请求域对象删除了属性:"+name+"---"+value);
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();//获取被替换的值
        System.out.println("请求域对象替换了属性:"+name+"---"+value);
    }
}

page.jsp:

<%
    //操作请求域的属性
    request.setAttribute("msg","aaabbbccc");//添加属性
    request.setAttribute("msg","bbbcccddd");//替换属性
    request.removeAttribute("msg");//删除属性
%>

会话属性监听器

MyHttpSessionAttributeListener:

package com.qf.listen02;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println("会话域对象添加了属性");
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println("会话域对象删除了属性");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println("会话域对象替换了属性");
    }
}

page02.jsp:

<%
    //操作会话域的属性
    session.setAttribute("msg","aaabbbccc");//添加属性
    session.setAttribute("msg","bbbcccddd");//替换属性
    session.removeAttribute("msg");//删除属性
%>

全局属性监听器

MyServletContextAttributeListener:

package com.qf.listen02;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        String name = servletContextAttributeEvent.getName();
        Object value = servletContextAttributeEvent.getValue();
        System.out.println("全局对象创建了属性:"+"--"+name+"--"+value);
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        String name = servletContextAttributeEvent.getName();
        Object value = servletContextAttributeEvent.getValue();
        System.out.println("全局对象创建了属性:"+"--"+name+"--"+value);
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        String name = servletContextAttributeEvent.getName();
        Object value = servletContextAttributeEvent.getValue();
        System.out.println("全局对象创建了属性:"+"--"+name+"--"+value);
    }
}

page03.jsp:

<%
  //操作全局域的属性
  application.setAttribute("msg","aaabbbccc");//添加属性
  application.setAttribute("msg","bbbcccddd");//替换属性
  application.removeAttribute("msg");//删除属性
%>

第三大类

HttpSessionBindingListener:监听JavaBean对象在session中的绑定(添加)和解绑(删除),即监听某一个具体的类对象,第二大类是监听所有的类对象。

HttpSessionActivationListener:监听JavaBean对象在session中的钝化(序列化)和活化(反序列化)

User:(实现HttpSessionBindingListener,HttpSessionActivationListener,Serializable)

package com.qf.listen03;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;

public class User implements HttpSessionBindingListener, HttpSessionActivationListener, Serializable {
    private String username;
    private String password;
    private String name;
    private String nickName;

    public User(String username, String password, String name, String nickName) {
        this.username = username;
        this.password = password;
        this.name = name;
        this.nickName = nickName;
    }

    public User() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        System.out.println(this+"被session钝化了");
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        System.out.println(this+"被session活化了");
    }

    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println(this+"绑定到session中了");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println(this+"从session中解绑了");
    }
}

在web里面创建META-INF文件夹,写一个context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
            <Store className="org.apache.catalina.session.FileStore" directory="C:\\text"/>
    </Manager>
</Context>

Servlet02:

package com.qf.servlet;

import com.qf.listen03.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/Servlet02")
public class Servlet02 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("Servlet02接收到请求了...");
        HttpSession session = request.getSession();
        //注意:将user对象添加到session中,可以叫做User对象绑定到session中 --- 绑定
        session.setAttribute("user",new User("1233211234567","123132","zs","fwkt"));
        //注意:将user对象从session中删除,可以叫做User对象从session中解绑了 --- 解绑
        session.removeAttribute("user");
    }
}

Servlet03:

package com.qf.servlet;

import com.qf.listen03.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/Servlet03")
public class Servlet03 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Servlet03接收到请求了...");
        HttpSession session = request.getSession();
        session.setAttribute("user",new User("1233211234567","123132","zs","fwkt"));
    }
}

注意:将User对象添加到session中,可以叫做User对象绑定到session中 — 绑定

将User对象从session中删除,可以叫做User对象从session中解绑 — 解绑

面试题:session的钝化与活化:

在这里插入图片描述

过滤器

简介

Filter:过滤器,拦截访问web资源的请求与响应操作

Servlet API中提供了Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个Java类称之为过滤器。

创建与使用

在这里插入图片描述

场景:welcome.html向Servlet01发送请求:

package com.qf.servlet;

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("/Servlet01.action")
public class Servlet01 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        System.out.println("Servlet收到请求了");
    }
}

过滤器:

package com.qf.filter;

import javax.servlet.*;
import java.io.IOException;

public class Filter01 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter01 --- init()");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter01 --- doFilter() -- 放行前");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("Filter01 --- doFilter() -- 放行后");


    }

    @Override
    public void destroy() {
        System.out.println("Filter01 --- destroy()");
    }
}

配置文件:

<welcome-file-list>
        <welcome-file>welcome.html</welcome-file>
    </welcome-file-list>
    <filter>
        <filter-name>Filter01</filter-name>
        <filter-class>com.qf.filter.Filter01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Filter01</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>

生命周期

创建:项目启动时创建 – 构造方法、init()

销毁:项目正常关闭时销毁 – destroy()

注意:Filter对象是单例的。

当有多个过滤器时,

配置文件:

<filter>
        <filter-name>Filter01</filter-name>
        <filter-class>com.qf.filter.Filter01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Filter01</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>Filter02</filter-name>
        <filter-class>com.qf.filter.Filter01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Filter02</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>Filter03</filter-name>
        <filter-class>com.qf.filter.Filter01</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Filter03</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>

思考:多个Filter的创建顺序?多个Filter调用顺序?

创建顺序:无序,底层是多线程抢资源。调用顺序为web.xml里的配置顺序(推荐)。如果是使用注解配置,是按照类名字典排序。

案例1 编码过滤器

WEB-学生管理系统中写一个Encoderfilter类进行编码过滤(就不必在servlet中设置了)

配置文件(标准写法要求匹配所有的action,但是由于之前项目中servlet后没有加.action,故此处偷懒直接写/*):

<welcome-file-list>
        <welcome-file>welcome.html</welcome-file>
    </welcome-file-list>
    <filter>
        <filter-name>EncoderFilter</filter-name>
        <filter-class>com.qf.filter.EncoderFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>EncoderFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

过滤器:

package com.qf.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class EncoderFilter implements Filter {
    private String code;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        code = filterConfig.getInitParameter("code");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        request.setCharacterEncoding(code);
        response.setContentType("text/html;charset="+code);
        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {

    }
}

案例2 登录权限过滤器

写一个LoginFilter。

配置文件:

<filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>com.qf.filter.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

LoginFilter:

package com.qf.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

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 request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestURI = request.getRequestURI();
        System.out.println(requestURI);
//        StringBuffer requestURL = request.getRequestURL();
//        System.out.println(requestURL);
        HttpSession session = request.getSession();
        String username = (String) session.getAttribute("username");
        String role = (String) session.getAttribute("role");
        String name = (String) session.getAttribute("name");

        if(requestURI.equals("/Day37_war_exploded/register.jsp")||
                requestURI.equals("/Day37_war_exploded/login.jsp")||
                requestURI.equals("/Day37_war_exploded/CodeServlet")||
                requestURI.equals("/Day37_war_exploded/LoginServlet")||
                requestURI.equals("/Day37_war_exploded/")||
                requestURI.equals("/Day37_war_exploded/welcome.html")
        ){
            filterChain.doFilter(request,response);
        }else{
            if(username!=null&&role!=null&&name!=null){
                if("student".equals(role) && requestURI.contains("QueryAllStuServlet")) {
                    response.sendRedirect("index.jsp");
                }
                else{
                    filterChain.doFilter(request,response);
                    
                }
            }

        }


    }

    @Override
    public void destroy() {

    }
}

案例3 敏感词过滤器

场景:在学生详情页面写一个建议,跳转到proposal.jsp,里面写一个表单,提交到ProposalServlet

<%--
  Created by IntelliJ IDEA.
  User: Gu
  Date: 2024-06-17
  Time: 17:37
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>建议</h2>
    <form action="ProposalServlet" method="post">
        建议:<input type="text" name="proposal"/>
        <input type="submit" value="提交"/>
        <button type="button" οnclick="fun01()">返回</button>
    </form>
    <script type="text/javascript">
        function fun01(){
            window.location = "index.jsp";
        }
    </script>
</body>
</html>

ProposalServlet(输出建议):

package com.qf.servlet;

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("/ProposalServlet")
public class ProposalServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String proposal = (String) request.getParameter("proposal");
        response.getWriter().println(proposal);
    }
}

MyHttpServletRequestWrapper包装类,继承HttpServletRequestWrapper类(构造方法、重写getParameter方法):

package com.qf.pojo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
    public MyHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        String parameter = super.getParameter(name);
        if(parameter!=null){
        	parameter = parameter.replaceAll("<","&lt;");
       	    parameter = parameter.replaceAll(">","&gt;");
        	parameter = parameter.replaceAll("傻逼","**");
        }
        
        return parameter;
    }
}

SensitiveWordsFilter:

package com.qf.filter;

import com.qf.pojo.MyHttpServletRequestWrapper;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class SensitiveWordFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper(request);
        filterChain.doFilter(requestWrapper,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/718920.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AWS——01篇(AWS入门 以及 AWS之EC2实例及简单实用)AWS

AWS——01篇&#xff08;AWS入门 以及 AWS之EC2实例及简单实用&#xff09; 1. 前言 2. 创建AWS账户 3. EC2 3.1 启动 EC2 新实例 3.1.1 入口 3.1.2 设置名称 选择服务 3.1.3 创建密钥对 3.1.4 网络设置——安全组 3.1.4.1 初始设置 3.1.4.2 添加安全组规则&#xff08;开放新…

0X0-基于Sklearn的机器学习入门:聚类(上)

本节及后续章节将介绍深度学习中的几种聚类算法&#xff0c;所选方法都在Sklearn库中聚类模块有具体实现。本节为上篇&#xff0c;将介绍几种相对基础的聚类算法&#xff0c;包括K-均值算法和均值漂移算法。 目录 X.1 聚类概述 X.1.1 聚类的种类 X.1.2 Sklearn聚类子模块 …

【JVM结构、JVM参数、JVM垃圾回收】

JVM&#xff1a;Java Virtual Machine java虚拟机 虚拟机&#xff1a;使用软件技术模拟出与具有完整硬件系统功能、运行在一个隔离环境中的计算机系统。 JVM官方文档&#xff1a;https://docs.oracle.com/javase/specs/jvms/se8/html/index.html java 一些命令 javac 将文件编…

【C++入门(3)】函数重载、引用

一、函数重载 1、函数重载概念 函数重载是指在同一作用域中&#xff0c;具有不同形参列表&#xff08;参数的 个数 或 类型 或类型顺序 不同&#xff09;的同名函数。 C语言中不允许同名函数的存在&#xff0c;如果一个程序中有两个函数的函数名完全相同&#xff0c;就会报错…

C#(C Sharp)学习笔记_多态【十九】

前言 个人觉得多态在面向对象编程中还比较重要的&#xff0c;而且不容易理解。也是学了一个下午&#xff0c;才把笔记写得相对比较完善&#xff0c;但仍欠缺一些内容。慢慢来吧…… 什么是多态&#xff1f; 基本概念 在编程语言和类型论中&#xff0c;多态&#xff08;Poly…

2024最新版Node.js下载安装及环境配置教程(非常详细)

一、进入官网地址下载安装包 官网&#xff1a;Node.js — Run JavaScript Everywhere 其他版本下载&#xff1a;Node.js — Download Node.js (nodejs.org) 选择对应你系统的Node.js版本 二、安装程序 &#xff08;1&#xff09;下载完成后&#xff0c;双击安装包&#xf…

OpenGL Super Bible 7th-Primitives, Pipelines, and Pixels图元、渲染管线与像素

简介 本文的原版为《OpenGL Super Bible 7th》,是同事给我的,翻译是原文+译文的形势。文章不属于机器直译,原因在于语言不存在一一对应的关系,我将尽可能的按照中国人看起来舒服的方式来翻译这些段子,如果段子让你感到身心愉悦,那还劳烦点个关注,追个更。如果我没有及时…

从0进入微服务需要了解的基础知识

文章目录 系统架构演化过程为什么要了解系统架构的演化过程技术发展认知技术选型与创新 演变过程单体架构分层-分布式集群微服务 分布式\集群\微服务 微服务中的核心要素-拆分原则项目拆分与复杂度微服务的拆分维度有哪些小结 微服务中的核心要素服务化进行拆分后一定是微服务&…

MFC扩展库BCGControlBar Pro v35.0新版亮点:重新设计的工具栏编辑器等

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v35.0已全新发布了&#xff0c;这个版本改进类Visual Studio 2022的视觉主题、增强对多个…

ChatGPT付费创作系统V3.0.2独立版 WEB+H5+小程序端 (H5端界面美化+Pika视频作品广场+SunoAI 文生歌)系统部署教程

播播资源GPT付费体验系统最新版系统是一款基于ThinkPHP框架开发的AI问答小程序&#xff0c;是基于国外很火的ChatGPT进行开发的Ai智能问答小程序。当前全民热议ChatGPT&#xff0c;流量超级大&#xff0c;引流不要太简单&#xff01;一键下单即可拥有自己的GPT&#xff01;无限…

MinIO Enterprise Cache:实现超性能的分布式 DRAM 缓存

随着计算世界的发展和 DRAM 价格的暴跌&#xff0c;我们发现服务器配置通常配备 500GB 或更多的 DRAM。当您处理大型部署时&#xff0c;即使是那些具有超高密度 NVMe 驱动器的部署&#xff0c;这些服务器上的服务器数量乘以 DRAM 也会迅速增加&#xff0c;通常达到几 TB。该 DR…

【Intel CVPR 2024】通过图像扩散模型生成高质量360度场景,只需要一个语言模型

在当前人工智能取得突破性进展的时代&#xff0c;从单一输入图像生成全景场景仍是一项关键挑战。大多数现有方法都使用基于扩散的迭代或同步多视角内绘。然而&#xff0c;由于缺乏全局场景布局先验&#xff0c;导致输出结果存在重复对象&#xff08;如卧室中的多张床&#xff0…

Android网络性能监控方案 android线上性能监测

1 Handler消息机制 这里我不会完整的从Handler源码来分析Android的消息体系&#xff0c;而是从Handler自身的特性引申出线上卡顿监控的策略方案。 1.1 方案确认 首先当我们启动一个App的时候&#xff0c;是由AMS通知zygote进程fork出主进程&#xff0c;其中主进程的入口就是Ac…

.Net OpenCVSharp生成灰度图和二值图

文章目录 前言一、灰度图二、二值图 前言 使用OpenCVSharp生成图片的灰度图和二值图 .Net 8.0版本&#xff0c;依赖OpenCvSharp4和OpenCvSharp4.runtime.win组件。 原图&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、灰度图 /// &…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 内存访问热度分析(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

Proteus8.13安装及使用

Proteus安装包下载地址 具体安装方法如下&#xff1a; 退出所有杀毒软件,右键以管理员身份运行 如果缺插件安装插件然后点击安装 如果遇到这种需要勾选的都勾选 安装插件完成 安装过程: 安装完成后桌面会自动出现图标 注意这个安装包是免破解的, 安装好以后可以直接使用 打…

竞赛选题 LSTM的预测算法 - 股票预测 天气预测 房价预测

0 简介 今天学长向大家介绍LSTM基础 基于LSTM的预测算法 - 股票预测 天气预测 房价预测 这是一个较为新颖的竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/postgraduate 1 基于 Ke…

React+TS前台项目实战(十一)-- 全局常用组件提示语可复制Link组件封装

文章目录 前言HighLightLink组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇讲的这个组件&#xff0c;是一个用于高亮显示文本并添加可选的跳转链接&#xff0c;提示文本&#xff0c;复制文本的 React 组件 HighLightLink组件 1. 功能分析 &#x…

SmartEDA、Multisim、Proteus大比拼:电路设计王者之争?

在电路设计领域&#xff0c;SmartEDA、Multisim和Proteus无疑是三款备受瞩目的软件工具。它们各自拥有独特的功能和优势&#xff0c;但在这场电路设计王者的竞争中&#xff0c;谁才是真正的领跑者&#xff1f;让我们深入探究这三款软件的异同&#xff0c;揭示它们各自的魅力所在…

【ComfyUI】Stable Diffusion 3 加Controlnet

基于 instantX-research/diffusers_sd3_control: &#x1f917; Diffusers: State-of-the-art diffusion models for image and audio generation in PyTorch and FLAX. (github.com) 和 ZHO-ZHO-ZHO/ComfyUI-SD3-Medium-CN-Diffusers: ComfyUI SD3-Medium ControlNet&#…