JSP入门教程
- JSP全称是Java Server Pages,Java的服务器页面,就是服务器端渲染技术
- JSP这门技术的最大的特点在于,写JSP就像在写HTML
- 相比html而言,html只能为用户提供静态数据,而JSP技术允许在页面中嵌套java代码,为用户提供动态数
据 - 相比Servlet而言,Servlet很难对数据进行排版,而JSP除了可以用java代码产生动态数据的同时,也很容
易对数据进行排版。
- 相比html而言,html只能为用户提供静态数据,而JSP技术允许在页面中嵌套java代码,为用户提供动态数
- jsp技术基于Servlet,你可以理解成JSP就是对Servlet的包装.
- 会使用JSP的程序员,再使用thymeleaf是非常容易的事情,几乎是无缝接轨.
- jsp页面不能像HTML页面,直接用浏览器运行。只能通过浏览器访问Tomcat来访问jsp页面
- 每一个JSP文件就是一个java类,里面嵌套的java代码就是该类内部的代码
- 每一个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"%>
- language表示jsp翻译后是什么语言文件,只支持java
- contentType表示jsp返回的数据类型,对应源码中response.setContentType()参数值
- pageEncoding属性表示当前jsp页面文件本身的字符集
- import属性跟java源代码中一样。用于导包,导类
-
代码脚本
-
代码脚本的语法是:<%java代码%>
-
代码脚本的作用是:可以在jsp页面中,编写我们需要的功能(使用java)
-
可以由多个代码脚本块组合完成一个完整的java语句。
-
代码脚本还可以和表达式脚本一起组合使用,在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>
-
-
声明脚本
- 声明脚本的格式是:<%!声明java代码%>,在代码脚本标签内加一个感叹号(!)
- 作用:定义JSP文件对应类需要的属性、方法、静态代码块和内部类等
-
表达式脚本
- 表达式脚本的格式是:<%=表达式%>,在代码脚本标签内加一个等于号(=)
- 表达式脚本的作用是:在jsp页面上输出数据
- 表达式脚本中的表达式不能以分号结束。
<%@ 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的内置对象
- JSP内置对象,是指Tomcat在翻译jsp页面成为Servlet后,内部提供的九大对象,叫内置对象
- 内置对象,可以直接使用,不需要手动定义
-
JSP九大内置对象
- out对象:向客户端输出数据,out.println(""):
- request对象:客户端的http请求
- response响应对象
- session会话对象
- application对象:对应ServletContext
- pageContext对象:jsp页面的上下文,是一个域对象,可以setAttribue(),作用范围只是本页面
- exception异常对象,getMessage()
- page对象:代表jsp这个实例本身
- config对象:对应ServletConfig
-
JSP四大域对象
-
pageContext(域对象,存放的数据只能在当前页面使用)
-
request(域对象,存放的数据在一次request请求有效)
-
session(域对象,存放的数据在一次会话有效)
-
application(域对象,存放的数据在整个web应用运行期间有效处
- JSP四大域对的总结
- 域对象是可以像Map一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存储范围
- 从存储范围(作用域范围看)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运算
- empty运算可以判断一个数据是否为空,如果为空,返回true,否则返回false
- 以下几种情况为空
- 值为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>:用于设置域对象的属性
- 等价于,域对象.setAttribute(key,value)
- scope属性设置保存到哪个域
- page表示PageContext域(默认值)
- request表示Request域
- session表示Session域
- application表示ServletContext域
- var属性设置key是什么
- 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监听器
- Listener监听器它是JavaWeb的三大组件之一。JavaWeb的三大组件分别是:Servlet程序、Listener监听器、Filter过滤器
- Listener是JavaEE的规范,就是接口
- 监听器的作用是,监听某种变化(一般就是对象创建/销毁,属性变化),触发对应方法完成相应的任务
- JavaWeb中的监听器(共八个),目前最常用的是ServletContextListener
- ServletContextListener
- ServletContextAttributeListener
- HttpSessionListener
- HttpSessionAttributeListener
- ServletRequestListener
- ServletRequestAttributeListener
- HttpSessionBindingListener感知监听器
- HttpSessionActivationListener感知监听器
- ServletContextListener(ServletContext对象监听器)
- 作用:监听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(拦截器)
- Filter拦截器在web项目启动时,由tomcat来创建Filter实例,每一个Filter类只会创建一个实例
- 会调用Filter默认的无参构造器,同时会调用init方法,只会调用一次
- 在创建Filter实例时,同时会创建一个FilterConfig.对象,并通过init方法传入
- 通过FilterConfig对象,程序员可以获取该Filter的相关配置信息
- 当个http请求和该Filter的urL-patter匹配时,就会调用doFilter()方法
- 在调用doFilter()方法时,tomcat会同时创ServletRequest和ServletResponse和FilterChain.对象,并通过doFilter()方法传入,
- 如果后面的请求目标资源(jsp,servlet...)会使用到request,和response,那么会继续传递
- 当WEB工程停止时,会调用destroy()方法
- 请求转发不会经过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>
-
拦截路径
- url-pattern:Filter的拦截路径,即浏览器在请求什么位置的资源时,过滤器会进行拦截过滤,同一个Filter可以配置多个url-patterm
- 精确匹配<ur-pattern>/a.jsp</url-pattern>对应的请求地址http://ip[域名]port/工程路径/a.jsp会拦截
- 目录匹配<url-pattern>/manage/*</url-pattern>对应的请求地址http://ip[域名]:port/工程路径/manage/xx,即web工程manage目录下所有资源会拦截
- 后缀名匹配飞<url-pattern>*.jsp</ur-pattern>后缀名可变,比如*.action*.do等等对应的请求地址http://ip[域名]port/工程路径/Xx.jsp,后缀名为jsp请求会拦截
- Filter过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在
- 在filter-mapping的url-pattern配置要拦截/验证url
- 对于我们不去拦截urL,就不配置
- 对于要拦截的目录的某些要放行的资源,在通过init-param配置指定
-
过滤链:当一个过滤器不能够完成过滤任务时,就设计多个过滤器来完成任务,多个过滤器就共同构成过滤链
- 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>