JavaEE精选-Web组件

本文涉及的产品
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: JavaEE精选-Web组件

Web组件

最开始,ee规范中只有servlet一个组件。

后来,又出现了两个组件,listener、filter

listener:监听器()

filter:过滤器(拦截)

Listener

web访问过程中的监听器

被监听者:ServletContext对象

监听者:自己编写了一个监听器

监听事件:对象的创建和销毁

触发行为:调用自己写的监听器对应的方法

作用:主要负责监听ServletContext对象的创建和销毁,一般存放全局性的代码

使用

1.编写一个类实现ServletContextListener接口

2.注册当前监听器(web.xml 注解)

@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
    System.out.println("init");
    ServletContext servletContext = servletContextEvent.getServletContext();
   
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
    System.out.println("destroy");
}

原理

底层维护了一个接口,通过不同的子实现来调用不同的方法

class ServletContext {
  List<ServletContextListener> listeners;
  
  //注册该listener,tomcat会调用
  add(ServletContextListener listener){
    listeners.add(listener);
  }
  
  init(){
    listeners.for{listener.contextInitialized()}
  }
  
  destroy(){
    listeners.for{listener.contextDestroyed()}
  }
}

Filter

介绍

过滤器,主要的作业是对请求和响应对象进行检查和修改。—>ServletContext

设置编码格式

可以实现对页面的拦截和放行

与过滤器关联的Servlet

使用

1.编写一个类实现Filter接口

2.注册该Filter

filter如何和servlet关联

最简单的方式就是通过url-pattern进行关联,即把servlet的url-pattern直接赋值给filter即可

filter默认情况下执行的是拦截操作,如果需要放行,必须要加如下代码:

filterChain.doFilter(servletRequest, servletResponse);//底层使用递归调用

filter url-pattern的不同于servlet之处

1.filter可以设置和servlet相同的url-pattern

*2.filter设置/*,并且设置/ 还是很有必要的

3.filter不可以设置/

4.如果有多个filter,设置相同的url-pattern,那么也是允许的

多个filter的执行先后顺序

1.如果是web.xml,按照filter-mapping声明的先后顺序

<filter-mapping>
    <filter-name>filter2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>filter1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2.如果是注解,那么按照类名首字母ASCII先后顺序,即英文字母的顺序

流程


请求的去程,只执行filterChain.doFilter上面的代码

返程只执行下面的代码

请求的完整执行流程

访问http://localhost/app/1.html

以访问http://localhost/app/1.html为例

1.域名解析(浏览器缓存–操作系统缓存–hosts缓存–dns服务器),TCP三次握手建立连接,浏览器生成请求报文经过tcp层拆包打上标签经过ip层打上端口号和目标ip,从链路层发出去在网上中转传输到目标主机

2.到达服务器后被一直监听80端口号的HTTP/1.1 Connector接收到,将其解析为request对象并生成一个response对象

3.Connector将两个对象下发给Engine,Engine进一步下发交给Host

4.Host的职责是挑选一个叫/app的应用,如果找到就将两个对象交给该应用,如果找不到就交给ROOT应用,如果ROOT应用中都没有,那就404

5.此时有效的路径就是/1.html,查找有没有filter可以处理该请求,如果有就将该filter加入组件执行的链表中,如果有多个按照先后顺序来排列,配置在web.xml文件中就按照文件的顺序执行,使用注解就按照首字母的ASCII码大小顺序执行

6.进一步查看有没有servlet可以处理该请求,如果没有就交给缺省的servlet,此时要看servlet有没有重写,如果重写了那就交给自己重写的处理,如果没有重写就交给默认的处理,当做静态资源访问,如果此时没有该资源,就抛出404

7.依次调用链表上的每一个组件,调用Filter的doFilter方法以及servlet的service方法,方法执行时需要传入request和response这两个参数

8.全部执行完毕后,Connector读取response里面的数据生成响应报文,再依次通过tcp,ip,链路层出去发送到客户端,客户端再进行解析

案例

登陆注销案例,加入拦截的功能,如果没有登陆则直接返回登陆页面

package com.fh.filter.login;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/user1/*")
public class UserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        String op = requestURI.replace(request.getContextPath() + "/user1/", "");
        //将前面的部分替换为空白,取出具体的详情页面的部分,根据不同的方法进行分发处理
        if ("loginxx".equals(op)){
            login(request,response);
        }
    }
    private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //具体的登陆的处理逻辑
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        HttpSession session = request.getSession();
        session.setAttribute("username",username);
        response.getWriter().println("登陆成功,进入个人主页");
        response.setHeader("refresh","2;url="+request.getContextPath()+"/user1/infoxx");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //刷新页面是get请求
        String requestURI = request.getRequestURI();
        String op = requestURI.replace(request.getContextPath() + "/user1/", "");
        if ("infoxx".equals(op)){
            info(request,response);
        }else if ("logoutxx".equals(op)){
            logout(request,response);
        }
    }
    private void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //处理注销的逻辑
        request.getSession().invalidate(); //清除session实现注销,服务器没有保存此客户端的数据了
        response.getWriter().println("注销成功,即将跳回登陆页面");
        response.setHeader("refresh","2;url="+request.getContextPath()+"/login5.html");
    }
    private void info(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //具体的详情页面的逻辑
        HttpSession session = request.getSession();
        Object username = session.getAttribute("username");
        response.getWriter().println("欢迎"+username+"<a href='"+request.getContextPath()+"/user1/logoutxx"+"'>点我注销</a>");
    }
}
package com.fh.filter.login;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter("/*")
public class AuthFilter 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;
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        if (auth(request)){
            //这里的主要逻辑就是如果是需要登陆的页面,并且用户没有登陆,那就进行拦截
            //反之如果页面不需要登陆,或者需要登陆且用户登陆了,就不拦截
            Object username = request.getSession().getAttribute("username");
            //主要看username是否为空,如果当前客户端的session对象中存放了username,那么就说明登陆了,反之则不行
            if (username==null){
                response.getWriter().println("你还没有登陆!即将跳回登陆页面");
                response.setHeader("refresh","2;url="+request.getContextPath()+"/login5.html");
                return;//一定要return,否则继续向下执行就放行了
            }
        }
        filterChain.doFilter(request,response);
    }
    private boolean auth(HttpServletRequest request) {
        //校验是否是需要验证登陆的页面
        String s = request.getContextPath() + "/user1/infoxx";
        if (s.equals(request.getRequestURI())){
            //uri是当前访问到的页面,如果与我们预设好的相等,那就说明需要登陆,返回true
            return true;
        }
        return false;
    }
    @Override
    public void destroy() {
    }
}

equest.getContextPath() + “/user1/infoxx”;

if (s.equals(request.getRequestURI())){

//uri是当前访问到的页面,如果与我们预设好的相等,那就说明需要登陆,返回true

return true;

}

return false;

}

@Override
public void destroy() {
}

}

目录
相关文章
|
2月前
|
XML 编解码 前端开发
【web组件库系列】封装自己的字体图标库
【web组件库系列】封装自己的字体图标库
80 0
|
2月前
|
消息中间件 druid Java
web后端-SpringCloud-Bus消息总线组件
web后端-SpringCloud-Bus消息总线组件
|
2月前
|
Java 应用服务中间件 容器
SpringBoot之Web原生组件注入
SpringBoot之Web原生组件注入
|
2月前
|
IDE API 开发工具
 鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Web组件
 鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Web组件
62 2
|
6天前
|
Java API 调度
Web后端Javaee企业级开发之定时任务 Springboot整合任务框架Quartz和Task详解
Web后端Javaee企业级开发之定时任务 Springboot整合任务框架Quartz和Task详解
11 0
|
2月前
|
SQL 分布式计算 资源调度
常用大数据组件的Web端口号总结
这是关于常用大数据组件Web端口号的总结。通过虚拟机名+端口号可访问各组件服务:Hadoop HDFS的9870,YARN的ResourceManager的8088和JobHistoryServer的19888,Zeppelin的8000,HBase的10610,Hive的10002。ZooKeeper的端口包括客户端连接的2181,服务器间通信的2888以及选举通信的3888。
54 2
常用大数据组件的Web端口号总结
|
27天前
|
Java 关系型数据库 MySQL
【JavaEE进阶】部署Web项目到Linux服务器
【JavaEE进阶】部署Web项目到Linux服务器
|
2月前
|
JavaScript 前端开发 API
Vue中的组件:构建现代Web应用的基石
Vue中的组件:构建现代Web应用的基石
|
2月前
|
移动开发 JavaScript 前端开发
【专栏:HTML进阶篇】HTML模板与Web组件:可复用的网页元素
【4月更文挑战第30天】HTML模板和Web组件提升网页开发效率和可维护性。HTML模板,如&lt;template&gt;元素和服务器端模板引擎,用于创建可复用的HTML结构。Web组件是自定义的HTML元素,结合影子DOM和模板,实现封装的可重用组件。两者助力构建高效、现代的网页和网站。
|
2月前
|
前端开发 Java 应用服务中间件
【JavaEE进阶】 初识Spring Web MVC
【JavaEE进阶】 初识Spring Web MVC