JSP入门教程

  1. JSP全称是Java Server Pages,Java的服务器页面,就是服务器端渲染技术
  2. JSP这门技术的最大的特点在于,写JSP就像在写HTML
    • 相比html而言,html只能为用户提供静态数据,而JSP技术允许在页面中嵌套java代码,为用户提供动态数
    • 相比Servlet而言,Servlet很难对数据进行排版,而JSP除了可以用java代码产生动态数据的同时,也很容
      易对数据进行排版。
  3. jsp技术基于Servlet,你可以理解成JSP就是对Servlet的包装.
  4. 会使用JSP的程序员,再使用thymeleaf是非常容易的事情,几乎是无缝接轨.
  5. jsp页面不能像HTML页面,直接用浏览器运行。只能通过浏览器访问Tomcat来访问jsp页面
  6. 每一个JSP文件就是一个java类,里面嵌套的java代码就是该类内部的代码
  7. 每一个JSP文件对应的类都继承了HttpJspBase,类图如下

  • JSP的简单演示

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>一个简单的求和JSP页面</title>
        <%--我的第一个jsp文件,注释一下--%>
    </head>
    <body>
    <h1>JSP简单的演示</h1>
    <%
        //在JSP中,该标签不能嵌套
        //JSP内置了一些Servlet对象,JSP本质还是一个Servlet
        int i = 10;
        int j = 20;
        int result = i + j;
        //输出
        out.print(i + " + " + j + "=" + result);
    %>
    </body>
    </html>
    
  • JSP的注释

    • <%--注释--%>
  • page指令

    <%@ page language="java" contentType="text/html;charset="utf-8 pageEncoding="utf-8"%>

    1. language表示jsp翻译后是什么语言文件,只支持java
    2. contentType表示jsp返回的数据类型,对应源码中response.setContentType()参数值
    3. pageEncoding属性表示当前jsp页面文件本身的字符集
    4. import属性跟java源代码中一样。用于导包,导类
  • 代码脚本

    1. 代码脚本的语法是:<%java代码%>

    2. 代码脚本的作用是:可以在jsp页面中,编写我们需要的功能(使用java)

    3. 可以由多个代码脚本块组合完成一个完整的java语句。

    4. 代码脚本还可以和表达式脚本一起组合使用,在jsp页面上输出数据

      <%@ page import="com.hspedu.jsp.Monster" %>
      <%@ page import="java.util.ArrayList" %><%--
        Created by IntelliJ IDEA.
        User: 杨逸
        Date: 2023/4/9     
        Time: 10:22
        Version: 1.0
      --%>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>演示代码脚本的使用</title>
      </head>
      <body>
      <h1>演示代码脚本的使用</h1>
      <%
      //创建两个Monster对象
          Monster monster = new Monster("1", "孙悟空", "金箍棒横扫");
          Monster monster1 = new Monster("2", "牛魔王", "冲锋");
          //加入到List集合中
          ArrayList<Monster> monsters = new ArrayList<>();
          monsters.add(monster);
          monsters.add(monster1);
      %>
      <%--创建一个表格展示信息--%>
      <table border="1" bgcolor="#faebd7" cellpadding="0">
          <tr>
              <th>id</th>
              <th>姓名</th>
              <th>技能</th>
          </tr>
          <%
              for (Monster m :monsters) {
      //这里使用代码脚本实现循环从集合中取出元素
          %>
          <tr>
              <td><%=m.getId()%></td>
              <td><%=m.getName()%></td>
              <td><%=m.getSkill()%></td>
          </tr>
          <%
              }
          %>
      </table>
      </body>
      </html>
      
  • 声明脚本

    1. 声明脚本的格式是:<%!声明java代码%>,在代码脚本标签内加一个感叹号(!)
    2. 作用:定义JSP文件对应类需要的属性、方法、静态代码块和内部类等
  • 表达式脚本

    1. 表达式脚本的格式是:<%=表达式%>,在代码脚本标签内加一个等于号(=)
    2. 表达式脚本的作用是:在jsp页面上输出数据
    3. 表达式脚本中的表达式不能以分号结束。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP声明脚本和表达式脚本演示</title>
</head>
<body>
<%!
    //声明脚本,用于设置该jsp文件生成的对应java类的属性
String name = "杨逸";
int age = 12;
%>
<h1>个人信息</h1><br>
名字=<%=name%><br>
年龄=<%=age%><br>
工作=<%="程序员"%>
</body>
</html>
  • JSP的内置对象

    1. JSP内置对象,是指Tomcat在翻译jsp页面成为Servlet后,内部提供的九大对象,叫内置对象
    2. 内置对象,可以直接使用,不需要手动定义
  • JSP九大内置对象

    1. out对象:向客户端输出数据,out.println(""):
    2. request对象:客户端的http请求
    3. response响应对象
    4. session会话对象
    5. application对象:对应ServletContext
    6. pageContext对象:jsp页面的上下文,是一个域对象,可以setAttribue(),作用范围只是本页面
    7. exception异常对象,getMessage()
    8. page对象:代表jsp这个实例本身
    9. config对象:对应ServletConfig
  • JSP四大域对象

    1. pageContext(域对象,存放的数据只能在当前页面使用)

    2. request(域对象,存放的数据在一次request请求有效)

    3. session(域对象,存放的数据在一次会话有效)

    4. application(域对象,存放的数据在整个web应用运行期间有效处

    • JSP四大域对的总结
      1. 域对象是可以像Map一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存储范围
      2. 从存储范围(作用域范围看)pageContext<request<session<application
  • JSP的请求转发标签:<jsp:forward page="转发的目标地址"></jsp:forward>

    <jsp:forward page="bb.jsp"></jsp:forward>
    

EL表达式

  • EL表达式一般获得的都是域对象中的数据fg

  • 本质就是调用对象的getxx()方法

  • EL表达式可以用来获得HttpRequestServlet对象的属性值,比JSP的表达式脚本(<%=%>)更简洁

    ${表达式}等价于JSP的<%=表达式%>

  • EL的emty运算

    1. empty运算可以判断一个数据是否为空,如果为空,返回true,否则返回false
    2. 以下几种情况为空
      • 值为nul川
      • 值为空串的时
      • 值是Object类型数组,长度为零
      • list集合,元素个数为零
      • map集合,元素个数为零
  • EL表达式的三元运算符,与Java的三元表达式类似,只是写法不同

    表达式?返回值1:返回值2

  • 如果${requestScope.score}.那么就明确的指定从request域对象取出数据

  • 如果${score},这是就按照从小到大的域范围去获取,pageContext-->request-->session

  • EL的11个隐藏(内置)对象

JSTL表达式

  • JSTL的核心库

    • <c:if test="逻辑值"><C:if>:类似java的if分支,test属性的值是逻辑表达式,当表达式为真时,就输出<c:if>表达式里数据,可以嵌套EL表达式(${表达式})使用

      • test属性:用于接受逻辑值
      • scope属性:表示从哪个域对象取值
      • var属性:表示从域对象中取出哪个属性
      <%--
        Created by IntelliJ IDEA.
        User: 杨逸
        Date: 2023/4/9     
        Time: 17:24
        Version: 1.0
      --%>
      <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>\<c\:if\>的使用</title>
      </head>
      <body>
      <h1>c:if的使用</h1>
      <%--类似java的if分支,test属性的值是逻辑表达式
      当表达式为真时,就输出<c:if>表达式里数据
      --%>
      <c:if test="${20 > 10}">
          <h1>20 > 10</h1>
      </c:if>
      </body>
      </html>
      
    • <c:set><c:set>:用于设置域对象的属性

      1. 等价于,域对象.setAttribute(key,value)
      2. scope属性设置保存到哪个域
        • page表示PageContext域(默认值)
        • request表示Request域
        • session表示Session域
        • application表示ServletContext域
      3. var属性设置key是什么
      4. value属性设置值
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <%--
        Created by IntelliJ IDEA.
        User: 杨逸
        Date: 2023/4/9     
        Time: 18:09
        Version: 1.0
      --%>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>c:set标签的使用</title>
      </head>
      <body>
      <c:set scope="page" var="name" value="c:set标签的使用"></c:set>
      使用c:set设置的值${name}
      </body>
      </html>
      
    • <c:choose><c:when><c:when><c:otherwise><c:otherwise><c:choose>:类似java的多分支结构

      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <%--
        Created by IntelliJ IDEA.
        User: 杨逸
        Date: 2023/4/9     
        Time: 18:21
        Version: 1.0
      --%>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>c:choose标签的使用</title>
      </head>
      <body>
      <%
          pageContext.setAttribute("score","60");
      %>
      <c:choose>
          <c:when test="${score}>90">
              <h1>成绩=${score}>90</h1>
          </c:when>
          <c:when test="${score} >60">
              <h1>成绩=${score}>60</h1>
          </c:when>
          <c:otherwise>
              <h1>成绩=${score}<=60</h1>
          </c:otherwise>
      </c:choose>
      
      </body>
      </html>
      
      
    • <c:forEach><c:forEach>:用于遍历,只能边域对象的属性

      • begin属性:表示循环开始的数值
      • end属性:表示循环结束的数值
      • step属性:步长,每次增长的长度,默认为1
      • var属性:记录取出的变量或记录循环的标记
      • varStatus属性:获得元素的类信息,相当于调用了getClass()方法
      • items属性:表示要从哪个域对象(数组,集合)中取出数据
    <%@ page import="java.util.ArrayList" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%--
      Created by IntelliJ IDEA.
      User: 杨逸
      Date: 2023/4/9     
      Time: 17:48
      Version: 1.0
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>c:forEach标签的使用</title>
        <%
            ArrayList<String> list = new ArrayList<>();
            list.add("kk");
            list.add("jj");
            list.add("ll");
            pageContext.setAttribute("list",list);
            String name[] = {"杨逸","看看","清奇"};
            pageContext.setAttribute("name",name);
        %>
    </head>
    <body>
    <c:forEach begin="1" end="5" step="1" var="i" >
        <h1>第${i}</h1>
    </c:forEach>
    <%--只能遍历域的属性--%>
    <c:forEach items="${name}" var="v">
        <h1>名字${v}</h1>
    </c:forEach>
    <c:forEach items="${list}" var="v">
        <h1>名字${v}</h1>
    </c:forEach>
    
    </body>
    </html>
    

Listener监听器

  1. Listener监听器它是JavaWeb的三大组件之一。JavaWeb的三大组件分别是:Servlet程序、Listener监听器、Filter过滤器
  2. Listener是JavaEE的规范,就是接口
  3. 监听器的作用是,监听某种变化(一般就是对象创建/销毁,属性变化),触发对应方法完成相应的任务
  4. JavaWeb中的监听器(共八个),目前最常用的是ServletContextListener
    1. ServletContextListener
    2. ServletContextAttributeListener
    3. HttpSessionListener
    4. HttpSessionAttributeListener
    5. ServletRequestListener
    6. ServletRequestAttributeListener
    7. HttpSessionBindingListener感知监听器
    8. HttpSessionActivationListener感知监听器
  • ServletContextListener(ServletContext对象监听器)
    1. 作用:监听Servletcontext创建或销毁(当我们Web应用启动时,就会创建ServletContext),即生命周期监听,应用场景(1)加载初始化的配置文件;比如spring的配置文件(2)任务调度(配合定时器Timer/TimerTask)
package com.hspedu.listener;

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

/**
 * @Projectname: servlet
 * @Filename: HspServletContextListener
 * @Author: 杨逸
 * @Data:2023/4/10 11:04
 * @Description: TODO
 */
//使用监听器也需要配置web.xml

/**
 * 1.当一个类实现了ServletContextListener
 * 2.该类就是一个监听器
 * 3.该类可以监听的事件由该类实现的监听接口决定,比如实现ServletContextListener
 * ,则该类就可以监听ServletContext.对象的创建和销毁,以此类推
 * 4.HspServletContextListener就是一个监听者
 * 5.web应用启动时,就会产生ServletContextEvent事件,会调用监听器的对应事件处理方法
 * contextInitialized,同时会传递事件对象
 * 6.程序员可以通过ServletContextEvent事件对象,来获取需要的信息,然后再进行业务处
 */
//监听ServletContext对象创建和销毁的监听器
public class HspServletContextListener implements ServletContextListener {
    //当有ServletContext对象创建时,会被调用
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContextEvent对象被创建");
        System.out.println(servletContextEvent.getServletContext() + "被创建");
    }

    //当有ServletContext对象被销毁时,会被调用
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContextEvent对象被销毁");
        System.out.println(servletContextEvent.getServletContext() + "被销毁");

    }
}
  • ServletContextAttributeListener(ServletContext对象属性监听器)
package com.hspedu.listener;

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

/**
 * @Projectname: servlet
 * @Filename: HspServletContextAttrbute
 * @Author: 杨逸
 * @Data:2023/4/10 11:19
 * @Description: TODO
 */
//监听ServletContextAttribute的监听器
public class HspServletContextAttribute implements ServletContextAttributeListener {
    //有属性被添加时,会被调用
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("ServletContext添加新属性" + servletContextAttributeEvent.getName() +"=" +servletContextAttributeEvent.getValue());
    }

    //有属性被删除时,会被调用
    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("ServletContext删除属性" + servletContextAttributeEvent.getName() +"=" +servletContextAttributeEvent.getValue());

    }

    //有属性被修改时,会被调用
    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("ServletContext修改属性" + servletContextAttributeEvent.getName() +"=" +servletContextAttributeEvent.getValue());

    }
}
  • HttpSessionListener(Session对象监听器),可以用于监听用户的上线和下线
package com.hspedu.listener;

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

/**
 * @Projectname: servlet
 * @Filename: HspSessionListener
 * @Author: 杨逸
 * @Data:2023/4/10 14:00
 * @Description: TODO
 */
public class HspHttpSessionListener implements HttpSessionListener {
    //创建Session对象时,被调用
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("创建了一个Session对象");
        System.out.println("用户id" + httpSessionEvent.getSession().getId() + "已上线");
    }

    //销毁Session对象时,被调用
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("销毁了一个Session对象");
        System.out.println("用户id" + httpSessionEvent.getSession().getId() + "已下线");
    }
}
  • HttpSessionAttributeListener(Session对象属性监听器)
package com.hspedu.listener;

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

/**
 * @Projectname: servlet
 * @Filename: HspHttpSessionAttributeListener
 * @Author: 杨逸
 * @Data:2023/4/10 14:06
 * @Description: TODO
 */
public class HspHttpSessionAttributeListener implements HttpSessionAttributeListener {
    //给Session对象添加属性时,调用
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("Session对象添加一个属性" +httpSessionBindingEvent.getValue());
    }

    //给Session对象删除属性时,调用
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("Session对象删除一个属性" +httpSessionBindingEvent.getValue());
    }

    //给Session对象修改属性时,调用
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("Session对象修改一个属性" +httpSessionBindingEvent.getValue());
    }
}

  • ServletRequestListener(ServletRequest请求对象监听器),可以用于监控ip访问的频率
package com.hspedu.listener;

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

/**
 * @Projectname: servlet
 * @Filename: HspServletRequestListener
 * @Author: 杨逸
 * @Data:2023/4/10 14:35
 * @Description: TODO
 */
public class HspServletRequestListener implements ServletRequestListener {
    //当创建一个Request对象是调用
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("Request对象被创建" + servletRequestEvent.getServletRequest());
    }

    //当销毁一个Request对象是调用
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("Request对象被销毁" + servletRequestEvent.getServletRequest());
    }
}

  • ServletRequestAttributeListener(ServletRequest属性监听器)
package com.hspedu.listener;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

/**
 * @Projectname: servlet
 * @Filename: HspServletRequestAttributeListener
 * @Author: 杨逸
 * @Data:2023/4/10 14:38
 * @Description: TODO
 */
public class HspServletRequestAttributeListener implements ServletRequestAttributeListener {
    //当给Request添加属性时调用
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("给Request添加属性" + servletRequestAttributeEvent.getValue());
    }

    //当给Request删除属性时调用
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("给Request删除属性" + servletRequestAttributeEvent.getValue());
    }

    //当给Request修改属性时调用
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("给Request修改属性" + servletRequestAttributeEvent.getValue());
    }
}

  • HttpSessionBindingListener感知监听器(感知监听器不需要配置web.xml文件),用于绑定加入到Session对象的属性的数据对象
  • HttpSessionActivationListener感知监听器,

Filter过滤器

  • Filter(拦截器)

    1. Filter拦截器在web项目启动时,由tomcat来创建Filter实例,每一个Filter类只会创建一个实例
    2. 会调用Filter默认的无参构造器,同时会调用init方法,只会调用一次
    3. 在创建Filter实例时,同时会创建一个FilterConfig.对象,并通过init方法传入
    4. 通过FilterConfig对象,程序员可以获取该Filter的相关配置信息
    5. 当个http请求和该Filter的urL-patter匹配时,就会调用doFilter()方法
    6. 在调用doFilter()方法时,tomcat会同时创ServletRequest和ServletResponse和FilterChain.对象,并通过doFilter()方法传入,
    7. 如果后面的请求目标资源(jsp,servlet...)会使用到request,和response,那么会继续传递
    8. 当WEB工程停止时,会调用destroy()方法
    9. 请求转发不会经过Filter过滤器
  • FilterConfig(过滤器的配置对象)

    • 通过FilterConfig对象可以获得Filter过滤器的初始化配置信息
    • Filter的初始化配置信息在web.xml文件配置
  • 使用过滤器实现用户访问控制,在拦截器中验证Session的属性实现控制访问

  • 使用拦截器控制访问,如果验证通过,需要继续访问,需要调用FilterChain对象的doFilter()方法,没有调用则会停止访问

  • 验证密码的Servlet

//验证密码的Servlet
package com.hspedu.filter;

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

/**
 * @Projectname: servlet
 * @Filename: LoginCheckServlet
 * @Author: 杨逸
 * @Data:2023/4/10 17:50
 * @Description: TODO
 */
public class LoginCheckServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //验证密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //给Session设置用户名
        HttpSession session = req.getSession();
        session.setAttribute("username",username);
        RequestDispatcher requestDispatcher;//定义一个转发器
        if ("hsp".equals(username) && "123456".equals(password)){
            //重定向到管理页面
            resp.sendRedirect("jsp/manage/manage.jsp");
//            requestDispatcher = req.getRequestDispatcher("/jsp/manage/manage.jsp");
        }else {
            //转发到登陆界面
            requestDispatcher = req.getRequestDispatcher("/login.html");
            //转发
            requestDispatcher.forward(req,resp);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

  • 访问的拦截器
//访问的拦截器
package com.hspedu.filter;

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

/**
 * @Projectname: servlet
 * @Filename: LoginFilter
 * @Author: 杨逸
 * @Data:2023/4/10 17:38
 * @Description: TODO
 */
//一个登陆拦截过滤器
    //使用过滤器需要在web.xml文件中配置
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("LoginFilter登陆过滤器初始化");
          //通过FilterConfig对象获得Filter的初始化配置参数
        String ip = filterConfig.getInitParameter("ip");
        //获得ServletContext对象
        ServletContext servletContext = filterConfig.getServletContext();
        String filterName = filterConfig.getFilterName();//获得该Filter的拦截器名称
        //获得所有的Filter拦截器的初始化参数名称
        Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
        //通过遍历存放拦截器初始化参数的枚举集合名称取出参数的值
        while (initParameterNames.hasMoreElements()){
            System.out.println(initParameterNames.nextElement());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("LoginFilter登陆过滤器被调用");
        //在过滤器中验证用户的session,判断是否登陆过
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
        HttpSession session = httpServletRequest.getSession();
        if (session.getAttribute("username") != null){
            //如果没有调用FilterChain对象的doFilter()方法,请求在这里会停止
            //调用后,才会放行请求通过,进入下一个资源
            filterChain.doFilter(servletRequest, servletResponse);
        }else {
            //转发到登陆页面
            RequestDispatcher requestDispatcher = httpServletRequest.getRequestDispatcher("/login.html");
            requestDispatcher.forward(httpServletRequest,servletResponse);
            //放行请求
            filterChain.doFilter(httpServletRequest,servletResponse);
        }

    }

    @Override
    public void destroy() {
        System.out.println("LoginFilter登陆过滤器被销毁");
    }
}

  • 拦截器的web.xml文件的配置
   <!--过滤器的配置一般放在最前面-->
    <!--配置方式与Servlet相似-->
    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>com.hspedu.filter.LoginFilter</filter-class>
        <!--Filter拦截器的初始化配置参数-->
        <init-param>
            <param-name>ip</param-name>
            <param-value>192.168.1.1</param-value>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/jsp/manage/*</url-pattern>
    </filter-mapping>

  • Filter过滤器作业,实现过滤器含禁用词的评论,使用过滤链
  • 禁用词:苹果、香蕉
  • 苹果过滤器
package com.hspedu.filter.homework;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Projectname: servlet
 * @Filename: AFilter
 * @Author: 杨逸
 * @Data:2023/4/10 20:21
 * @Description: TODO
 */
public class AFilter implements Filter {
    String disable;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("苹果过滤器初始化");
        //获得禁用的词
        disable = filterConfig.getInitParameter("disable");
        System.out.println(disable);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("苹果过滤器");
        //获得表单提交的信息
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String topic = httpServletRequest.getParameter("topic");
        //使用正则表达式匹配判断是否有禁用词
        Pattern pattern = Pattern.compile(disable);
        Matcher matcher = pattern.matcher(topic);
        if (matcher.find()){
            RequestDispatcher requestDispatcher = httpServletRequest.getRequestDispatcher("/topic.jsp");
            requestDispatcher.forward(httpServletRequest,servletResponse);
            return;
        }else {
            //没有禁用词,放行

            filterChain.doFilter(httpServletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

  • 香蕉过滤器
package com.hspedu.filter.homework;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Projectname: servlet
 * @Filename: BFilter
 * @Author: 杨逸
 * @Data:2023/4/10 20:21
 * @Description: TODO
 */
public class BFilter implements Filter {
    String disable;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("香蕉过滤器初始化");
        //获得初始化禁用词
        disable = filterConfig.getInitParameter("disable");
        System.out.println(disable);

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("香蕉过滤器");
        //获得表单提交的信息
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String topic = httpServletRequest.getParameter("topic");
        //使用正则表达式匹配判断是否有禁用词
        Pattern pattern = Pattern.compile(disable);
        Matcher matcher = pattern.matcher(topic);
        if (matcher.find()){
            RequestDispatcher requestDispatcher = httpServletRequest.getRequestDispatcher("/topic.jsp");
            requestDispatcher.forward(httpServletRequest,servletResponse);
            return;
        }else {
            //没有禁用词,放行
            filterChain.doFilter(httpServletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

  • 填写评论的jsp
<%--
  Created by IntelliJ IDEA.
  User: 杨逸
  Date: 2023/4/10     
  Time: 20:15
  Version: 1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="/servlet/">
    <title>提交评论的页面</title>
</head>
<body>
<h1>评论</h1>
禁用词:苹果、香蕉
<form action="jsp/filter/showtopic.jsp">
    用户名:<input type="text" name="username"><br>
    评论:<br><textarea name="topic" rows="5" cols="30"></textarea><br>
    <input type="submit" value="提交评论">
</form>

</body>
</html>

  • 显示评论的jsp,放在目录"/jsp/filter/showtopic.jsp"
<%--
  Created by IntelliJ IDEA.
  User: 杨逸
  Date: 2023/4/10     
  Time: 20:17
  Version: 1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>显示评论的页面</title>
</head>
<body>
<%
    request.setCharacterEncoding("utf-8");
    response.setContentType("text/html;charset=utf-8");
%>
<h1>你的评论</h1>
<%=request.getParameter("username") %>:<%=request.getParameter("topic")%>

</body>
</html>

  • 过滤器的web.xml文件配置
<filter>
        <filter-name>AFilter</filter-name>
        <filter-class>com.hspedu.filter.homework.AFilter</filter-class>
        <init-param>
            <!--配置评论的禁用词-->
            <param-name>disable</param-name>
            <param-value>苹果</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>AFilter</filter-name>
        <url-pattern>/jsp/filter/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>BFilter</filter-name>
        <filter-class>com.hspedu.filter.homework.BFilter</filter-class>
        <init-param>
            <!--配置评论的禁用词-->
            <param-name>disable</param-name>
            <param-value>香蕉</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>BFilter</filter-name>
        <url-pattern>/jsp/filter/*</url-pattern>
    </filter-mapping>