(5.4)、异常处理步骤流程
1、执行目标方法,目标方法运行期间有任何异常都会被catch、而且标志当前请求结束;并且用 dispatchException
2、进入视图解析流程(页面渲染?)
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
3、mv = processHandlerException;处理handler发生的异常,处理完成返回ModelAndView;
- 1、遍历所有的 handlerExceptionResolvers,看谁能处理当前异常【HandlerExceptionResolver处理器异常解析器】
- 系统默认的 异常解析器;
- 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实列对象 } }