124.【SpringBoot 源码刨析C】(五)

简介: 124.【SpringBoot 源码刨析C】

(5.4)、异常处理步骤流程

1、执行目标方法,目标方法运行期间有任何异常都会被catch、而且标志当前请求结束;并且用 dispatchException

2、进入视图解析流程(页面渲染?)

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

3、mv = processHandlerException;处理handler发生的异常,处理完成返回ModelAndView;

  • 1、遍历所有的 handlerExceptionResolvers,看谁能处理当前异常【HandlerExceptionResolver处理器异常解析器

  1. 系统默认的 异常解析器;
  • 1、DefaultErrorAttributes先来处理异常。把异常信息保存到rrequest域,并且返回null;
  • 2、默认没有任何人能处理异常,所以异常会被抛出
  • 1、如果没有任何人能处理最终底层就会发送 /error 请求。会被底层的BasicErrorController处理
  • 2、解析错误视图;遍历所有的 ErrorViewResolver 看谁能解析。
  • 3、默认的 DefaultErrorViewResolver ,作用是把响应状态码作为错误页的地址,error/500.html
  • 4、模板引擎最终响应这个页面 error/500.html
7.Web原生组件注入(Servlet、Filter、Listener)
(1).使用Servlet API (第一种方式)
首先要在主类中设置需要扫描的servlet包在哪。
1. @ServletComponentScan(basePackages = "com.atguigu.admin") :指定原生Servlet组件都放在那里,默认是扫描主类所在包的子包
然后我们在servlet包中配置我们的原生servlet
2. @WebServlet(urlPatterns = "/my"):效果:直接响应,没有经过Spring的拦截器?
3. @WebFilter(urlPatterns={"/css/*","/images/*"})
4. @WebListener

扩展:DispatchServlet 如何注册进来

  • 容器中自动配置了 DispatcherServlet 属性绑定到 WebMvcProperties;对应的配置文件配置项是 spring.mvc

  • 实质上通过 ServletRegistrationBean<DispatcherServlet> 把 DispatcherServlet 配置进来。

  • 默认映射的是 / 路径。

Tomcat-Servlet

多个Servlet都能处理到同一层路径,精确优选原则

A: /my/ ->(假如说这个路径可以处理my/下的所有路径)

B: /my/1 -> (假如说这个路径可以处理my/1这个准确路径)

主类

package com.jsxs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan
public class SpringBootLs02Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootLs02Application.class, args);
    }
}

servlet

package com.jsxs.servlet;
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 java.io.IOException;
/**
 * @Author Jsxs
 * @Date 2023/7/8 17:24
 * @PackageName:com.jsxs.servlet
 * @ClassName: MyServlet
 * @Description: TODO  1.添加上注解.   2.重写get和post方法
 * @Version 1.0
 */
@WebServlet(urlPatterns = "/my")  //标注是原生的API,并指定拦截路径
public class MyServlet extends HttpServlet {
    //  请求后的真实业务
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("666666");  //拦截后展示666
    }
    //  请求后的真实业务
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

Filter

package com.jsxs.servlet;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
 * @Author Jsxs
 * @Date 2023/7/8 17:58
 * @PackageName:com.jsxs.servlet
 * @ClassName: MyFilter
 * @Description: TODO   配置过滤器
 * @Version 1.0
 */
@Slf4j
@WebFilter(urlPatterns = {"/css/*","/imag/*"})   //设置拦截我们CSS和imag的所有文件
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
       log.info("MyFilter初始化完成.....");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("MyFilter工作中.....");
        chain.doFilter(request,response);
    }
    @Override
    public void destroy() {
        log.info("MyFilter初始化销毁.....");
    }
}

Listener

package com.jsxs.servlet;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
 * @Author Jsxs
 * @Date 2023/7/8 18:05
 * @PackageName:com.jsxs.servlet
 * @ClassName: MyServletContextListener
 * @Description: TODO
 * @Version 1.0
 */
@Slf4j
@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("MyServletContextListener监听器初始化完成.....");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("MyServletContextListener监听器销毁完成.....");
    }
}

(2).使用RegistrationBean (第二种方式)

去掉以上方法的各个注解(但保留类),并添加一个配置类实现三个原生API。

主类

package com.jsxs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan
public class SpringBootLs02Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootLs02Application.class, args);
    }
}

servlet: 将注册的组件删除

package com.jsxs.servlet;
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 java.io.IOException;
/**
 * @Author Jsxs
 * @Date 2023/7/8 17:24
 * @PackageName:com.jsxs.servlet
 * @ClassName: MyServlet
 * @Description: TODO  1.添加上注解.   2.重写get和post方法
 * @Version 1.0
 */
//@WebServlet(urlPatterns = "/my")  //标注是原生的API,并指定拦截的路径(就是不放行)
public class MyServlet extends HttpServlet {
    //  请求后的真实业务
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("666666");  //拦截后展示666
    }
    //  请求后的真实业务
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

Filter:将注册的组件删除

package com.jsxs.servlet;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
 * @Author Jsxs
 * @Date 2023/7/8 17:58
 * @PackageName:com.jsxs.servlet
 * @ClassName: MyFilter
 * @Description: TODO   配置过滤器
 * @Version 1.0
 */
@Slf4j
//@WebFilter(urlPatterns = {"/css/*","/imag/*"})   //设置拦截我们CSS和imag的所有文件
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
       log.info("MyFilter初始化完成.....");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("MyFilter工作中.....");
        chain.doFilter(request,response);
    }
    @Override
    public void destroy() {
        log.info("MyFilter初始化销毁.....");
    }
}

Listener:将注册的组件删除

package com.jsxs.servlet;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
 * @Author Jsxs
 * @Date 2023/7/8 18:05
 * @PackageName:com.jsxs.servlet
 * @ClassName: MyServletContextListener
 * @Description: TODO
 * @Version 1.0
 */
@Slf4j
//@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("MyServletContextListener监听器初始化完成.....");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("MyServletContextListener监听器销毁完成.....");
    }
}

MyRegisterConfig 配置类实现

package com.jsxs.config;
import com.jsxs.servlet.MyFilter;
import com.jsxs.servlet.MyServlet;
import com.jsxs.servlet.MyServletContextListener;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
/**
 * @Author Jsxs
 * @Date 2023/7/8 18:14
 * @PackageName:com.jsxs.config
 * @ClassName: MyServlet
 * @Description: TODO
 * @Version 1.0
 */
@Configuration
public class MyRegisterConfig {
    @Bean
    public ServletRegistrationBean myServlet() {
        MyServlet myServlet = new MyServlet();  // //这个是我们写在Servlet包中的 MyServlet类
        return new ServletRegistrationBean(myServlet, "/my01", "/my02"); // 第一个参数是myServlet实列对象,第二个参数是映射的路径
    }
    @Bean
    public FilterRegistrationBean myFilter() {
        MyFilter myFilter = new MyFilter();  //这个是我们写在Servlet包中的 MyFilter类
        // 1.第一种
//      return new FilterRegistrationBean(myFilter,myServlet());  //第一个参数是MyFilter实列对象,第二个参数是ServletRegistrationBean对象 ->就是只拦截"/my01","/my02"这两个路径
        // 2.第二种
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);  // MyFilter实列对象
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my", "/css/*"));  // 拦截的路径
        return filterRegistrationBean;
    }
    @Bean
    public ServletListenerRegistrationBean myListener() {
        MyServletContextListener mySwervletContextListener = new MyServletContextListener(); //这个是我们写在Servlet包中的 MyServletContextListener类
        return new ServletListenerRegistrationBean(mySwervletContextListener); //  MyServletContextListener实列对象
    }
}

相关文章
|
1月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
2月前
|
前端开发 Java
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
文章通过一个表白墙/留言墙的初级SpringBoot项目实例,详细讲解了如何进行前后端开发,包括定义前后端交互接口、创建SpringBoot项目、编写前端页面、后端代码逻辑及实体类封装的全过程。
80 3
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
2月前
|
前端开发 Java 数据安全/隐私保护
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
文章通过一个简单的SpringBoot项目,详细介绍了前后端如何实现用户登录功能,包括前端登录页面的创建、后端登录逻辑的处理、使用session验证用户身份以及获取已登录用户信息的方法。
226 2
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
|
29天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
2月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
168 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
3月前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
本文介绍了一个基于Spring Boot和Vue.js实现的在线考试系统。随着在线教育的发展,在线考试系统的重要性日益凸显。该系统不仅能提高教学效率,减轻教师负担,还为学生提供了灵活便捷的考试方式。技术栈包括Spring Boot、Vue.js、Element-UI等,支持多种角色登录,具备考试管理、题库管理、成绩查询等功能。系统采用前后端分离架构,具备高性能和扩展性,未来可进一步优化并引入AI技术提升智能化水平。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
|
2月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
58 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
2月前
|
存储 JSON 算法
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
文章介绍了JWT令牌的基础教程,包括其应用场景、组成部分、生成和校验方法,并在Springboot中使用JWT技术体系完成拦截器的实现。
95 0
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
|
2月前
|
Java 数据库连接 mybatis
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
该文档详细介绍了如何在Springboot Web项目中整合Mybatis,包括添加依赖、使用`@MapperScan`注解配置包扫描路径等步骤。若未使用`@MapperScan`,系统会自动扫描加了`@Mapper`注解的接口;若使用了`@MapperScan`,则按指定路径扫描。文档还深入分析了相关源码,解释了不同情况下的扫描逻辑与优先级,帮助理解Mybatis在Springboot项目中的自动配置机制。
141 0
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
|
2月前
|
机器学习/深度学习 移动开发 自然语言处理
基于人工智能技术的智能导诊系统源码,SpringBoot作为后端服务的框架,提供快速开发,自动配置和生产级特性
当身体不适却不知该挂哪个科室时,智能导诊系统应运而生。患者只需选择不适部位和症状,系统即可迅速推荐正确科室,避免排错队浪费时间。该系统基于SpringBoot、Redis、MyBatis Plus等技术架构,支持多渠道接入,具备自然语言理解和多输入方式,确保高效精准的导诊体验。无论是线上医疗平台还是大型医院,智能导诊系统均能有效优化就诊流程。