09_Web组件

文章目录

  • Web组件
    • Listener监听器
      • ServletContextListener
      • 执行过程
    • Filter过滤器
      • Filter与Servlet的执行
    • 案例(登录案例)
  • 小结
    • Web组件

Web组件

  • JavaEE的Web组件(三大Web组件):
    1. Servlet → 处理请求对应的业务
    2. Listener → 监听器
    3. Filter → 过滤器

Listener监听器

  • 监听器在监听到主体做了XX事情,就会触发对应的事件
  • 监听的东西与命名有关系
  • 要加上注解@WebListener

ServletContextListener

监听的主体就是ServletContext,当发现ServletContext做了事情,Listener(监听器)就会执行该事件特定的方法。

  • ServletContext如果初始化,则会执行监听器的初始化方法contextInitialized
    • ServletContext应用程序启动的时候初始化,就意味着应用程序启动
  • ServletContext如果销毁,则会执行监听器的销毁方法contextDestroy
    • ServletContext应用程序关闭的时候销毁,意味着应用程序关闭
  • 应用程序启动的时候会执行ServletContextListenercontextInitialized方法;应用程序关闭的时候会执行contextDestroy

执行过程

当应用程序启动的过程中,逐步加载Web组件

  • 首先加载ServletContextListener组件
    • ServletContext伴随着应用程序初始化,它开始初始化,然后ServletContextListener监听到ServletContext初始化,会执行Listener的Initialized方法
  • 然后初始化loadOnStartup为正数的Servlet

在这里插入图片描述
eg:

@WebListener
public class PropertyInitServletContextListener implements ServletContextListener {@SneakyThrows@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {ServletContext servletContext = servletContextEvent.getServletContext();InputStream inputStream = PropertyInitServletContextListener.class.getClassLoader().getResourceAsStream("parameter.properties");Properties properties = new Properties();properties.load(inputStream);String picPath = properties.getProperty("pic.path");servletContext.setAttribute("picPath", picPath);}@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {System.out.println("应用程序关闭,可以做一些资源的释放");}
}
/*** localhost:8080/demo1/picture/fetch?name=1.jpg*/
@WebServlet("/picture/fetch")
public class PictureAccessServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// InputStream inputStream = PictureAccessServlet.class.getClassLoader()//         .getResourceAsStream("parameter.properties");// Properties properties = new Properties();// properties.load(inputStream);// String path = properties.getProperty("pic.path");String path = (String) getServletContext().getAttribute("picPath");File file = new File(path,request.getParameter("name"));FileInputStream fileInputStream = new FileInputStream(file);ServletOutputStream outputStream = response.getOutputStream();int length = 0;byte[] bytes = new byte[1024];while((length = fileInputStream.read(bytes)) != -1) {outputStream.write(bytes,0,length);}fileInputStream.close();outputStream.close();}
}

Filter过滤器

  • Filter是一个执行过滤任务的一个对象
    • 它既可以作用于Request对象,也可以作用于Response对象,或者两者均作用
  • 就是Servlet中获取请求之前,Servlet响应之后

在这里插入图片描述

Filter与Servlet的执行

  • URL-Pattern和Servlet之间存在着映射关系,URL-Pattern和Filter之间也存在着映射关系
    • 1个URL-Pattern只能对应一个Servlet,但是可以对应多个Filter
    • Servlet和URL-Pattern之间是一对多的关系,但是URL-Pattern和Servlet之间是一对一
  • 其实,一个URL-Pattern对应的请求
    • 对应1个Servlet
    • 对应多个Filter

在这里插入图片描述
eg:

@WebFilter("/user/*")
public class CharacterEncodingFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {ServletContext servletContext = filterConfig.getServletContext();}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {// 做过滤,里面写的就是通用的业务// 前半部分// 这部分是解决中文乱码问题HttpServletResponse response = (HttpServletResponse) servletResponse;HttpServletRequest request = (HttpServletRequest) servletRequest;request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");filterChain.doFilter(servletRequest, servletResponse); // 执行下一个过滤器或者Servlet// 后半部分// 但是一般业务代码都写在前半部分}@Overridepublic void destroy() {}
}

案例(登录案例)

  • 需求
    • /user/login
    • /user/logout
    • /user/info
    • /order/list
    • 增加web组件中的filter功能
    • 增加web组件中的listener功能
    • 增加白名单功能

在这里插入图片描述

  • bean目录下
@Data
public class Order {private Integer id;private String name;private Double price;private Integer userId;
}
@Data
public class User {private Integer id;private String username;private String password;private Integer age;private Date birthday;private Date createdate;private String mobile;}
  • mapper目录下
public interface OrderMapper {List<Order> selectByUserId(Integer id);
}
public interface UserMapper {List<User> selectByUserNameAndPassword(@Param("username") String username, @Param("password") String password);User selectByPrimaryKey(Integer id);
}
  • servlet目录下
@WebServlet("/order/*")
public class OrderServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}@SneakyThrowsprivate void process(HttpServletRequest request, HttpServletResponse response) {DispatchUtil.dispatch(request,response,this);}@SneakyThrowsprivate void list(HttpServletRequest request, HttpServletResponse response){// 先判断是否是登录状态// 如果没有登录,则跳转到登录页面// 这里filter帮我们完成了// 如果已经登录,则查询orderlist信息OrderMapper orderMapper = MybatisUtil.getSqlSession().getMapper(OrderMapper.class);HttpSession session = request.getSession();User user = (User) session.getAttribute("user");List<Order> orders = orderMapper.selectByUserId(user.getId());response.getWriter().println(orders);}
}
@WebServlet("/user/*")
public class UserServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}@SneakyThrowsprivate void process(HttpServletRequest request, HttpServletResponse response) {DispatchUtil.dispatch(request, response, this);}@SneakyThrowsprivate void login(HttpServletRequest request, HttpServletResponse response){// 获取username和password,查询user记录String username = request.getParameter("username");String password = request.getParameter("password");UserMapper userMapper = MybatisUtil.getSqlSession().getMapper(UserMapper.class);List<User> users = userMapper.selectByUserNameAndPassword(username, password);// 有可能用户名和密码相同,则取第一条数据if (users != null && users.size() > 0) {User user = users.get(0);HttpSession session = request.getSession();session.setAttribute("user",user);response.getWriter().println("登录成功");} else {response.getWriter().println("用户名或密码错误,即将跳转到登录页面...");response.setHeader("refresh","2;url=/demo3/login.html");}}@SneakyThrowsprivate void logout(HttpServletRequest request, HttpServletResponse response){HttpSession session = request.getSession();session.invalidate();response.getWriter().println("注销用户");}@SneakyThrowsprivate void info(HttpServletRequest request, HttpServletResponse response){// 先判断是否是登录状态// 如果没有登录,则跳转到登录页面// 这里filter帮我们做了// 如果已经登录,可以从session中获取信息 -> 响应信息HttpSession session = request.getSession();User user = (User) session.getAttribute("user");response.getWriter().println(user);}
}
  • listener目录下
@WebListener
public class PropertyServletContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {ServletContext servletContext = servletContextEvent.getServletContext();Properties properties = new Properties();InputStream inputStream = PropertyServletContextListener.class.getClassLoader().getResourceAsStream("application.properties");try {properties.load(inputStream);} catch (IOException e) {e.printStackTrace();}String whiteList = properties.getProperty("whiteList");String[] whiteListStr = whiteList.split(",");List<String> list = Arrays.asList(whiteListStr);servletContext.setAttribute("whiteList", list);}@Overridepublic void contextDestroyed(ServletContextEvent sce) {}
}
  • filter目录下
@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {List<String> whiteList = null;@SneakyThrows@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 方法1:
//        Properties properties = new Properties();
//        InputStream inputStream = CharacterEncodingFilter.class.getClassLoader()
//                .getResourceAsStream("application.properties");
//        properties.load(inputStream);
//        String whiteListStr = properties.getProperty("whiteList");
//        String[] whiteArray = whiteListStr.split(",");
//        whiteList = Arrays.asList(whiteArray);// 方法2:// 可以先把配置文件在Listener的时候放入whiteList = (List<String>) filterConfig.getServletContext().getAttribute("whiteList");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {// List<String> list = Arrays.asList("/user/login", "/user/logout", "/login.html");// 强转HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String uriSuffix = UriUtil.getUriSuffix(request);if (whiteList.contains(uriSuffix)) {if (!uriSuffix.endsWith("html")) {// 1. 解决字符集request.setCharacterEncoding("utf-8");// 响应的字符集问题response.setContentType("text/html;charset=utf-8");}filterChain.doFilter(request, response);}// 1. 解决字符集request.setCharacterEncoding("utf-8");// 响应的字符集问题response.setContentType("text/html;charset=utf-8");// 2. 解决登录状态的判断HttpSession session = request.getSession();Object user = session.getAttribute("user");// 2.1 如果已经登录(或者登录/注销请求)就放行if (user != null) {filterChain.doFilter(request, response);} else {// 2.2 如果没有登录就提示,跳转到登录页面response.getWriter().println("没有登录,请先登录,即将跳转到登录页面...");response.setHeader("refresh", "2;url=/demo3/login.html");}//        String requestURI = request.getRequestURI();//        if (requestURI.endsWith("html")) {
//            filterChain.doFilter(request, response);
//        }// 2.1 如果已经登录(或者登录/注销请求)就放行
//        if (user != null || requestURI.endsWith("login")
//                || requestURI.endsWith("logout")){
//            filterChain.doFilter(request, response);
//        } else {
//            // 2.2 如果没有登录就提示,跳转到登录页面
//            response.getWriter().println("没有登录,请先登录,即将跳转到登录页面...");
//            response.setHeader("refresh","2;url=/demo3/login.html");
//        }}@Overridepublic void destroy() {}
}
  • util目录下
public class DispatchUtil {public static void dispatch(String operation, HttpServletRequest request, HttpServletResponse response, HttpServlet instance)throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {Method method = instance.getClass().getDeclaredMethod(operation, HttpServletRequest.class, HttpServletResponse.class);method.setAccessible(true);method.invoke(instance, new Object[]{request, response});}public static void dispatch(HttpServletRequest request, HttpServletResponse response, HttpServlet userServlet)throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {String requestURI = request.getRequestURI();String operation = requestURI.substring(requestURI.lastIndexOf("/") + 1);dispatch(operation, request, response, userServlet);}
}
public class MybatisUtil {private static SqlSession sqlSession;static{try {sqlSession = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml")).openSession(true);} catch (IOException e) {e.printStackTrace();}}public static SqlSession getSqlSession() {return sqlSession;}
}
public class UriUtil {// Suffix的意思是后缀public static String getUriSuffix(HttpServletRequest request) {// uri - contextPathString uriSuffix = null;// eg: /demo3/user/nameString requestURI = request.getRequestURI();// eg: /demo3String contextPath = request.getContextPath();if (contextPath == null || contextPath.length() == 0) {// 这是一个root应用uriSuffix = requestURI;} else {uriSuffix = requestURI.replaceAll(contextPath, "");// 或者:uriSuffix = requestURI.substring();}return uriSuffix;}
}
  • UserMapperxml目录
<mapper namespace="com.coo1heisenberg.demo3.mapper.OrderMapper"><select id="selectByUserId" resultType="com.coo1heisenberg.demo3.bean.Order">select id, name, price, user_id as userId from test_product<where>user_id = #{user_id}</where></select>
</mapper>
<mapper namespace="com.coo1heisenberg.demo3.mapper.UserMapper"><select id="selectByUserNameAndPassword" resultType="com.coo1heisenberg.demo3.bean.User">select id, username, password, age, birthday, createDate, mobile from test_user<where>username = #{username} and password = #{password}</where></select><select id="selectByPrimaryKey" resultType="com.coo1heisenberg.demo3.bean.User">select id, username, password, age, birthday, createDate, mobile from test_user<where>id = #{id}</where></select>
</mapper>

小结

Web组件

  • 核心Servlet处理核心业务
  • Listener,用来做资源的初始化
  • Filter,在Servlet处理前后增加通用的处理

11

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/782178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux利用Jenkins部署SpringBoot项目保姆级教程

在当今快速发展的软件开发领域&#xff0c;持续集成和持续部署&#xff08;CI/CD&#xff09;已经成为提升开发效率、缩短产品上市时间的关键实践。Linux系统以其稳定性和开源友好性&#xff0c;成为众多开发者和企业的首选平台。而Spring Boot&#xff0c;作为一个轻量级的Jav…

飞天使-k8s知识点28-kubernetes散装知识点5-helm安装ingress

文章目录 安装helm添加仓库下载包配置创建命名空间安装 安装helm https://get.helm.sh/helm-v3.2.3-linux-amd64.tar.gztar -xf helm-v3.2.3-linux-amd64.tar.gzcd linux-amd64mv helm /usr/local/bin修改/etc/profile 文件&#xff0c;修改里面内容,然后重新启用export PATH$P…

深入理解 Hadoop 上的 Hive 查询执行流程

在 Hadoop 生态系统中&#xff0c;Hive 是一个重要的分支&#xff0c;它构建在 Hadoop 之上&#xff0c;提供了一个开源的数据仓库系统。它的主要功能是查询和分析存储在 Hadoop 文件中的大型数据集&#xff0c;包括结构化和半结构化数据。Hive 在数据查询、分析和汇总方面发挥…

如何使用 Python 本地客户端操作读写云服务器 Redis 缓存数据库详细教程(更新中)

Redis 基本概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的使用 ANSI C 语言编写的、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库&#xff0c;并提供多种语言的 API。它通常被称为数据结构服务器&#xff0c;因为值&#xff08;value…

本地虚拟机服务器修改站点根目录并使用域名访问的简单示例

说明&#xff1a;本文提及效果是使用vmware虚拟机&#xff0c;镜像文件是Rocky8.6 一、配置文件路径 1. /etc/httpd/conf/httpd.conf #主配置文件 2. /etc/httpd/conf.d/*.conf #调用配置文件 调用配置文件的使用&#xff1a; vim /etc/httpd/conf.d/webpage.conf 因为在主配…

5个免费的3D钣金CAD软件

如果你正在设计简单的折叠钣金零件&#xff0c;则只需设计一些具有圆角半径的法兰&#xff1a;一个简单的钣金模块。 首先&#xff0c;你可以采用老式方式绘图并以 2D 方式完成所有操作。 许多传统制造商仍在使用 2D DWG 和 DXF 图纸。 因此&#xff0c;你很有可能只需快速起草…

【MySQL】DQL-聚合函数介绍&常见聚合函数&语法&注意事项&可cv例题语句

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

java Web 疫苗预约管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 疫苗预约管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使…

使用1panel部署Ollama WebUI(dcoekr版)浅谈

文章目录 说明配置镜像加速Ollama WebUI容器部署Ollama WebUI使用问题解决&#xff1a;访问页面空白 说明 1Panel简化了docker的部署&#xff0c;提供了可视化的操作&#xff0c;但是我在尝试创建Ollama WebUI容器时&#xff0c;遇到了从github拉取镜像网速很慢的问题&#xf…

公司官网怎么才会被百度收录

在互联网时代&#xff0c;公司官网是企业展示自身形象、产品与服务的重要窗口。然而&#xff0c;即使拥有精美的官网&#xff0c;如果不被搜索引擎收录&#xff0c;就无法被用户发现。本文将介绍公司官网如何被百度收录的一些方法和步骤。 1. 创建和提交网站地图 创建网站地图…

Matlab|孤岛划分|弹性配网故障划分模型

目录 1 主要内容 1.1 DistFlow 模型 1.2 虚拟潮流 1.3 目标函数 2 部分代码 3 程序结果 4 下载链接 1 主要内容 程序主要复现《A New Model for Resilient Distribution Systems by Microgrids Formation》&#xff0c;建立灾害情况下配网优化孤岛划分方案&#xff0c;通…

【Linux】POSIX信号量{基于环形队列的PC模型/理解信号量的出现/参考代码}

文章目录 1.POSIX信号量1.1介绍1.2接口 2.基于环形队列的PC模型2.1环形队列常用计算2.2如何设计&#xff1f;2.3如何实现&#xff1f; 3.细节处理3.1空间资源和数据资源3.2push/pop3.3理解信号量的出现1.回顾基于阻塞队列的PC模型中条件变量的使用2.如何理解信号量的投入使用&a…

P8681 [蓝桥杯 2019 省 AB] 完全二叉树的权值

题目描述 给定一棵包含 &#xfffd;N 个节点的完全二叉树&#xff0c;树上每个节点都有一个权值&#xff0c;按从上到下、从左到右的顺序依次是 &#xfffd;1,&#xfffd;2,⋯&#xfffd;&#xfffd;A1​,A2​,⋯AN​&#xff0c;如下图所示&#xff1a; 现在小明要把相同…

9.动态规划——1.从递归到动态规划

例题——N阶楼梯上楼问题 分析 大事化小&#xff1a;爬N层有F(N)种可能&#xff0c;有 F ( N ) F ( N − 1 ) F ( N − 2 ) F(N)F(N-1)F(N-2) F(N)F(N−1)F(N−2)小事化了&#xff1a; F ( 1 ) 1 &#xff0c; F ( 2 ) 2 F(1)1&#xff0c;F(2)2 F(1)1&#xff0c;F(2)2 …

IDE/VS2015和VS2017帮助文档MSDN安装和使用

文章目录 概述VS2015MSDN离线安装离线MSDN的下载离线MSDN安装 MSDN使用方法从VS内F1启动直接启动帮助程序跳转到了Qt的帮助网页 VS2017在线安装MSDN有些函数在本地MSDN没有帮助&#xff1f;切换中英文在线帮助文档 概述 本文主要介绍了VS集成开发环境中&#xff0c;帮助文档MS…

R语言颜色细分

1.如何对R语言中两种颜色之间进行细分 2.代码&#xff1a; x <- colorRampPalette(c("#FC8D62","#FDEAE6"))(12) #打印向量值 # 按字典顺序排序颜色值 x_sorted <- sort(x,decreasing TRUE)# 打印排序后的颜色值 print(x_sorted)#展示颜色 scales:…

Linux系统---如何理解Linux中的文件系统

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、理解文件系统 1.ls与stat 我们使用ls -l的时候看到的除了看到文件名&#xff0c;还看到了文件元数据。 每行包含7列…

神经网络与深度学习(一)

线性回归 定义 利用数理统计中回归分析&#xff0c;来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法 要素 训练集&#xff08;训练数据&#xff09;输出数据拟合函数数据条目数 场景 预测价格&#xff08;房屋、股票等&#xff09;、预测住院时间&#…

TASKPROMPTER

baseline模型的预训练权重就有1.6G! 多吓人呐&#xff0c;当时我就暂停下载了&#xff0c;不建议复现

python opencv 直线检测

直线检测 前期准备 import cv2 import numpy as np# 读取图片 img cv2.imread(r"C:\Users\HONOR\Desktop\12.png") # 灰度转换 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化 # reg, img cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 显示二值化…