Web核心中一共涉及的三大技术
Servlet : server applet 服务器端的小程序(主要处理请求响应的部分)
Filter: 过滤器 , 过滤: 将自己所需要的内容留下 不需要的内容剔除
Listener : 监听器
filter创建步骤
/**
* 1. 创建类
* 2. 实现javax.servlet.Filter的规范(接口)
* 3. 通知tomcat我们配置了过滤器 (web.xml进行配置)
* 4. 正常编写过滤器的代码即可
*/
public class HelloFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 执行过滤的方法 , 每次执行到过滤器都会执行此方法 相当于servlet的service方法
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
System.out.println("HelloFilter 被执行了 A");
//放行代码
filterChain.doFilter(request, response);
System.out.println("HelloFilter 放行后的代码 B");
}
@Override
public void destroy() {
}
}
3.通知tomcat我们配置了过滤器 (配置web.xml)
<filter>
<filter-name>HelloFilterfilter-name>
<filter-class>com.llz.web.a_filter.HelloFilterfilter-class>
filter>
<filter-mapping>
<filter-name>HelloFilterfilter-name>
<url-pattern>/DemoServleturl-pattern>
filter-mapping>
4.正常编写过滤器代码即可
a.配置web.xml
b.@WebFilter注解
/**
* 1.创建类
* 2.实现javax.servlet.Filter 接口
* 3.配置web.xml
*
* XmlFilter
* com.llz.web.b_filter.XmlFilter
*
*
* XmlFilter
* /DemoServlet
*
* 给Filter一个拦截路径
* 4.编写放行代码
*/
@WebFilter(urlPatterns = "/DemoServlet")
public class AnnoFilter implements Filter {
含义:类什么时候创建 什么时候销毁
init :在项目启动就执行(只执行一次) : servlet默认情况下是第一次访问servlet才初始化
doFilter:每次访问只要被拦截 必然执行该方法 每一次都执行
destroy :项目停止时 执行销毁 只执行一次
servlet的url-pattern设置 , 访问到servlet入口 (四种)
完全匹配: /a/b/c/Servlet
不完全匹配(目录匹配): /a/b/c/*
后缀名匹配: *.jsp *.html *.do *.abc
缺省匹配: / 以上三种都没有匹配成功 执行默认的缺省匹配(tomcat里面有默认设置 404 )
filter的拦截路径设置 只有三种(匹配到 就进行拦截)
完全匹配: /a/b/c/Servlet
不完全匹配(目录匹配): /a/b/c/*
后缀名匹配: *.jsp *.html *.do *.abc
filter没有缺省匹配
//放行后如果能找到访问的资源 显示
//放行后如果没有找到能够访问的资源 404
//不放行 : 不管后面资源是否能访问成功 响应是filter构成 , 白板页面
过滤器执行时机
REQUEST: 默认值 , 表示请求开始就进行拦截
FORWARD: 请求转发进行拦截
<filter>
<filter-name>MyDispatcherFilterfilter-name>
<filter-class>com.llz.web.d_dispatcher.MyDispatcherFilterfilter-class>
filter>
<filter-mapping>
<filter-name>MyDispatcherFilterfilter-name>
<url-pattern>/DemoServleturl-pattern>
<dispatcher>FORWARDdispatcher>
filter-mapping>
服务器中允许存在多个过滤器 , 这一组过滤器 称之为叫过滤器链
过滤器链xml , 执行的顺序问题 ,xml方式中 是 web.xml自上而下 filter的配置顺序就是执行顺序
过滤器链注解Filter执行顺序问题 : 类名决定顺序
xml :
优点: 配置清晰 解耦(解除耦合,代码关联度) 利于修改(所有的内容都在一起)
缺点: 配置麻烦 , 要编写大量的内容 表示一段配置
注解:
优点: 简单使用 不需要大量的配置
缺点: 不利于修改 每个类中嵌入的注解(耦合度太高) 建议使用注解的类不应该经常修改
/**
* 注意事项:
* 1.urlPatterns = "/*" 对服务器中所有的资源都进行处理
* 2.必须有放行 不能够影响原来的业务逻辑
* chain.doFilter(req, resp);
*/
@WebFilter(filterName = "EncodingFilter" , urlPatterns = "/*")
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("过滤器执行了");
//处理请求响应编码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//必须有放行 不能够影响原来的业务逻辑
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
@WebFilter(filterName = "IllEgalFilter",urlPatterns = "/*")
public class IllEgalFilter implements Filter {
//存储脏字字符 -- 提升作用于 让多个方法都可以使用
List<String> list = new ArrayList<String>();
/**
* 初始化方法: 将脏字的集合 在此处初始化 一次即可
*/
public void init(FilterConfig config) throws ServletException {
//存储脏字字符
//List list = new ArrayList();
list.add("大爷");
list.add("曰");
list.add("你 女未");
}
/**
* 1.准备处理脏字的List集合 - 在init初始化的 因为只初始化一次
* 2.在doFilter 先获得 字符
* @param req
* @param resp
* @param chain
* @throws ServletException
* @throws IOException
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//强转对象 : 使用熟悉的对象
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
//设置编码
request.setCharacterEncoding("utf-8");
response.setContentType("textml;charset=utf-8");
//1.拿到请求字符
String username = request.getParameter("username");
System.out.println("filter中未被处理的username:" + username);
//2.遍历脏字的字符集
for (String word : list) {
//3.判断 请求的字符是否含有脏字 , 必须是每一种脏字都判断
if(username.contains(word)){//contains 包含 大爷去跳广场舞 大爷 曰 你妹
username = username.replaceAll(word , "*");
}
}
System.out.println("filter中已经处理的username:" + username);
//传入的对象是我们转换以后的对象
chain.doFilter(request, response );//放行
}
public void destroy() {
}
}
问题的产生 : request.getParameter(“key”) 获得的是原始的数据,执行chain.doFilter(request, response )放行时还是会将脏字带过去。(即未起到我们想让它起到的效果)
解决方法:只要复写request.getParameter 方法即可 (修改代码逻辑)
解决方案:tomcat已经考虑到这个问题了 所以已经提供了一个 HttpServletRequest对象的实现类。
要求 :我们创建类 必须继承 , 但是必须提供有参构造。重写我们需要执行我们自己逻辑的方法,其他方法直接调用父类方法 (这就是包装思想)
public class MyHttpServletRequest extends HttpServletRequestWrapper{
//非法字符准备的数据
List<String> list = new ArrayList<String>();
HttpServletRequest request2 ; //在自己本类中可以使用request对象
public MyHttpServletRequest(HttpServletRequest request) {
super(request); //传入到父类 所有的代码 全部实现(这里不需要复写的代码 父类全部已经完成)
this.request2 = request;
}
//不需要复写的代码 父类全部已经完成
//考虑需要被复写的代码
@Override
public String getParameter(String name) {
//准备数据
list.add("大爷");
list.add("曰");
list.add("你 女未");
//System.out.println("MyHttpServletRequest-->getParameter被执行了");
if(name==null || "".equals(name)){//防止代码错误 参数传递错误
return null; //后续代码不再执行
}
//获得原来的数据
String oldParameter = request2.getParameter(name);
if(oldParameter==null || "".equals(oldParameter)){//防止代码错误 参数传递错误
return null; //后续代码不再执行
}
//逻辑代码 -> 一定是有参数 并且 已经获得请求的数据
for (String word : list) {
//if(oldParameter.contains(word)){
oldParameter = oldParameter.replaceAll(word , "*");
//}
}
//只要最后返回的值是处理过后的字符串 效果达到
return oldParameter;
}
}
WebFilter(filterName = "IllEgalFilter",urlPatterns = "/*")
public class IllEgalFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
/**
* 1.准备处理脏字的List集合 - 在init初始化的 因为只初始化一次
* 2.在doFilter 先获得 字符
* @param req
* @param resp
* @param chain
* @throws ServletException
* @throws IOException
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//强转对象 : 使用熟悉的对象
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
//设置编码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//自己定义的request 对方法进行修改了
MyHttpServletRequest myHttpServletRequest = new MyHttpServletRequest(request);
//传入的对象是我们转换以后的对象
chain.doFilter(myHttpServletRequest, response );//放行
}
public void destroy() {
}
}
监听: 监控 , web中的监听器, 监听三个域对象(Request,Session ,ServletContext)的一些操作
三组监听器:
第一组:监听域对象的创建和销毁的
第二组:监听域对象操作域的api ( 往域中存数据 , 删除域中数据… )
第三组: 监听域对象session的特殊数据
第一组:监听域对象的创建和销毁的
Request(结论)
创建: 请求开始就创建
销毁: 响应结束就销毁
请求转发可以共享数据 , 重定向两个请求的情况下 不能携带数据
Session:
创建:浏览器第一次访问服务器 并调用request.getSession() 创建session对象
销毁: 默认tomcat超时三十分钟销毁, 手动调用invalidate方法 ,服务器非正常关闭销毁
ServletContext(结论)
创建: 服务器启动就创建 , 初始化数据操作(只初始化一遍数据内容) , 加载一些配置文件 , 模拟数据库
销毁: 服务器关闭就销毁 , 释放资源
监听器的目标: 证明以前的结论 , 给框架做铺垫
监听的单词:Listener
1.创建一个类
2.实现一个接口 ServletContextListener( 表示当前的java就是一个监听器 )
3.通知tomcat我们有监听 配置web.xml
监听器代码
public class MyServletContextListener implements ServletContextListener {
/**
* context Init 初始化 : servletContext创建 立马执行该方法
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 初始化");
}
/**
* context Destroy : 监听ServletContext 销毁方法
* @param servletContextEvent
*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 销毁");
}
}
web.xml配置
<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_3_1.xsd"
version="3.1">
<listener>
<listener-class>com.llz.web.listener.MyServletContextListenerlistener-class>
listener>
web-app>
作用: 利用ServletContextListener监听器在创建ServletContext域对象时完成一些想要初始化的工作或者执行自定义任务调度。
/**
*
* com.llz.web.listener.MyServletRequestListener
*
*
*/
public class MyServletRequestListener implements ServletRequestListener {
/**
* 监听request对象创建的方法
* @param servletRequestEvent
*/
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("request对象创建");
}
/**
* 监听request对象销毁的方法
* @param servletRequestEvent
*/
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("request对象销毁");
}
}
//@WebServlet
//@WebFilter
/**
*
* com.llz.web.listener.MyServletRequestListener
*
*/
@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
/**
* sessionCreated : 监听session的创建
*/
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session的创建");
}
/**
* sessionDestroyed : 监听session的销毁
*/
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session的销毁");
}
}