还不会Servlet开发?来这里带你了解Servlet开发的基础知识
十八、Servlet规范扩展--------------监听器接口
1. 介绍
(1)一组来自于Servlet规范下接口,共有8个接口。在Tomcat存放servlet-api.jar包。
(2)监听器接口需要由开发人员亲自实现,Http服务器提供jar包并没有对应的实现类。
(3)监听器接口用于监控【作用域对象生命周期变化时刻】以及【作用域对象共享数据变化时刻】。
2. 作用域对象
(1)在Servlet规范中,认为在服务端内存中可以在某些条件下认为两个Servlet之间提供数据共享方案,被称为【作用域对象】。
(2)Servlet规范下作用域对象
ServletContext: 全局作用域对象
HttpServlet:会话作用域对象
HttpServletRequest:请求作用域对象
3. 监听器接口实现类开发步骤
(1)根据监听的实际情况,选择对应监听器接口进行实现
(2)重写监听器接口声明【监听事件处理方法】
(3)在web.xml文件将监听器接口实现类注册到Http服务区
4. ServletContextListener接口
(1)作用:通过这个接口合法的检测全局作用域对象被初始化时刻以及被销毁时刻。
(2)监听事件处理方法:
public void contextInitlized():在全局作用域对象被Http服务器初始化时被调用
public void contextDestory():在全局作用域对象被Http服务器销毁时被调用
package com.lht.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class OneListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("你好");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("再见");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--将监听器接口实现类注册到Tomcat-->
<listener>
<listener-class>com.lht.listener.OneListener</listener-class>
</listener>
</web-app>
5. ServletContextAttributeListener接口
(1)作用:通过这个接口合法的检测全局作用域对象共享数据变化时刻
(2)监听事件处理方法:
public void contextAdd():在全局作用域对象添加共享数据
public void contextReplaced():在全局作用域对象更新共享数据
public void contextRemove():在全局作用域对象删除共享数据
package com.lht.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
public class OneListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("添加共享数据");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("删除共享数据");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("更新共享数据");
}
}
6. 全局作用域对象共享数据变化时刻
ServletContext application = request.getServletContext();
application.setAttribute("key1",100); //新增共享数据
application.setAttribute("key1",200); //更新共享数据
application.removeAttribute("key1"); //删除共享数据
十九、Servlet规范扩展---------Filter接口(过滤器接口)
1. 介绍
(1)来自于Servlet规范下接口,在Tomcat中存在于servlet-api.jar包中。
(2)Filter接口实现类由开发人员负责提供,Http服务器 不负责提供。
(3)Filter接口在Http服务器调用资源文件之前,对Http服务器进行拦截。
2. 具体作用
(1)拦截Http服务器,帮助Http服务器检测当前请求合法性。
实例:对于az.jpg这个文件进行过滤,大于80岁的不能查看。
package com.lht.filter;
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
public class OneFilter implements Filter{
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//通过拦截请求对象得到请求包参数信息,从而得到来访用户的真实年龄
String age = servletRequest.getParameter("age");
//根据年龄,帮助Http服务器判断本次请求合法性
if(Integer.valueOf(age) < 80){ //合法请求
//将拦截请求对象和响应对象交还给Tomcat,由Tomcat继续调用资源文件
filterChain.doFilter(servletRequest,servletResponse); //放行
}else{
//过滤器代替Http服务器拒绝本次请求
servletResponse.setContentType("text/html;charset=utf-8");
PrintWriter out = servletResponse.getWriter();
out.print("<center><font style='color: red;font-size: 40px'>大爷还看呢?</font></center>");
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 将过滤器类文件路径交给Tomcat-->
<filter>
<filter-name>oneFilter</filter-name>
<filter-class>com.lht.filter.OneFilter</filter-class>
</filter>
<!--通过Tomcat在调用何种资源文件时需要被当前过滤器拦截-->
<filter-mapping>
<filter-name>oneFilter</filter-name>
<url-pattern>/az.jpg</url-pattern>
</filter-mapping>
</web-app>
(2)拦截Http服务器,对当前请求进行增强操作。
实例:当浏览器使用post方式访问资源时,如果不用utf-8字符集进行重新编辑使用中文就会出现乱码。而当有很多资源文件的时候如果每个都重新编辑一遍会使开发难度加大,这时可以使用filter进行完成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<form action="/myWeb/one" method="post">
参数:<input type="text" name="userName"></form>br>
<input type="submit" value="post方式访问OneServlet">
</form>
<form action="/myWeb/two" method="post">
参数:<input type="text" name="userName"></form>br>
<input type="submit" value="post方式访问TwoServlet">
</form>
</center>
</body>
</html>
package com.lht.filter;
import javax.servlet.*;
import java.io.IOException;
public class OneFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//通知拦截的请求对象,使用utf-8字符集对当前请求体信息进行一次重新编辑
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
package com.lht.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TwoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//直接从请求体读取请求参数
String userName = request.getParameter("userName");
System.out.println("TwoServlet 从请求体得到参数"+userName);
}
}
package com.lht.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class OneServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//直接从请求体读取请求参数
String userName = request.getParameter("userName");
System.out.println("OneServlet 从请求体得到参数"+userName);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>oneFilter</filter-name>
<filter-class>com.lht.filter.OneFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>oneFilter</filter-name>
<url-pattern>/*</url-pattern> <!--通知Tomcat在调用所有资源文件之前都要调用OneFilter进行拦截-->
</filter-mapping>
<servlet>
<servlet-name>TwoServlet</servlet-name>
<servlet-class>com.lht.controller.TwoServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>OneServlet</servlet-name>
<servlet-class>com.lht.controller.OneServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
</web-app>
3. Filter接口实现类开发步骤
(1)创建一个Java类实现Filter接口
(2)重写Filter接口中doFilter方法
(3)web.xml将过滤器接口实现类注册到Http服务器
参见上面的具体实例
4. Filter拦截地址格式
(1)命令格式
<filter-mapping>
<filter-name>oneFilter</filter-name>
<url-pattern>拦截地址</url-pattern>
</filter-mapping>
(2)命令作用
拦截地址通知Tomcat在调用任何资源文件之前需要调用OneFilter过滤进行拦截
(3)要求Tomcat在调用某一个具体文件之前,来调用OneFilter拦截
<url-pattern>/img/az.jpg</url-pattern>
(4)要求Tomcat在调用某一个文件夹下所有资源文件之前,来调用OneFilter拦截
<url-pattern>/img/*</url-pattern>
(5)要求Tomcat在调用任意文件夹下某种类型文件之前,来调用OneFilter拦截
<url-pattern>*.jpg</url-pattern>
(6)要求Tomcat在调用网站中任意文件时,来调用OneFilter拦截
<url-pattern>/*</url-pattern>