当前位置: 首页 > news >正文

统一异常处理和拦截器

1.全局异常处理机制

   1.异常处理两种方式

开发过程中是不可避免地会出现各种异常情况的,例如网络连接异常、数据格式异常、空指针异常等等。异常的出现可能导致程序的运行出现问题,甚至直接导致程序崩溃。因此,在开发过程中,合理处理异常、避免异常产生、以及对异常进行有效的调试是非常重要的。

对于异常的处理,一般分为两种方式:

编程式异常处理:是指在代码中显式地编写处理异常的逻辑。它通常涉及到对异常类型的检测及其处理,例如使用 try-catch 块来捕获异常,然后在 catch 块中编写特定的处理代码,或者在 finally 块中执行一些清理操作。在编程式异常处理中,开发人员需要显式地进行异常处理,异常处理代码混杂在业务代码中,导致代码可读性较差。

声明式异常处理:则是将异常处理的逻辑从具体的业务逻辑中分离出来,通过配置等方式进行统一的管理和处理。在声明式异常处理中,开发人员只需要为方法或类标注相应的注解(如 `@Throws` 或 `@ExceptionHandler`),就可以处理特定类型的异常。相较于编程式异常处理,声明式异常处理可以使代码更加简洁、易于维护和扩展。

2.基于注解异常声明异常处理  Springmvc异常处理机制)

   概念:配置出现什么异常显示对应的错误页面。异常类型和错误页面映射关系

   1.声明异常处理控制器类,统一定义异常处理handler方法!

异常处理handler方法和普通的handler方法参数接收和响应都一致!

只不过异常处理handler方法要映射异常,发生对应的异常会调用!

普通的handler方法要使用@RequestMapping注解映射路径,发生对应的路径调用!

package com.bdqn.exceptionhandler;/*** 全局异常处理器,内部可以定义异常处理Handler!* @ControllerAdvice 代表当前类的异常处理controller!*/@ControllerAdvicepublic class GlobalExceptionHandler {/*** @ExceptionHandler(NullPointerException.class)* 该注解标记异常处理Handler,并且指定发生异常调用该方法!* 异常处理handler,当发生空指针异常会触发此方法!* @param e 获取异常对象!* @return 返回handler处理结果!*/@ExceptionHandler(NullPointerException.class)public Object handlerNullException(NullPointerException e){return "null_error";}/*** 所有异常都会触发此方法!但是如果有具体的异常处理Handler!* 具体异常处理Handler优先级更高!* 例如: 发生NullPointerException异常!会触发handlerNullException方法,不会触发handlerException方法!*/@ExceptionHandler(Exception.class)public Object handlerException(Exception e){return "error";}}

2.配置文件扫描控制器类配置

   确保异常处理控制类被扫描

@ComponentScan({"com.bdqn.controller","com.bdqn.exceptionhandler"})public class SpringMvcConfig implements WebMvcConfigurer {

}

3.创建错误页面error.jsp null_error.jsp

<body><h1>出现xxx异常!</h1><img src="imgs/error1.jpg" /></body>

   3.Jsp页面异常处理

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" errorPage="error.jsp" %>

<html><body><% int num=10/0;%><h2>index.jsp</h2></body></html>

4.拦截器  Interceptor

  在程序中,使用拦截器在请求到达具体 控制器handler 方法前,统一执行检测

    4.1拦截器和过滤器区别

1.过滤器:工作在 Servlet 容器中,可以过滤所有资源,包括静态和jsp

2.拦截器:工作在 SpringMVC 的基础上,只针对拦截控制器Controller

选择:功能需要如果用 SpringMVC 的拦截器能够实现,就不使用过滤器

4.2 实现步骤 

    准备控制器的类

@Controllerpublic class TestController {@RequestMapping("/demo1")public String demo1() {System.out.println("执行demo1");
return "index";}@RequestMapping("/demo2")public String demo2() {System.out.println("demo2...");return "index";}@RequestMapping("/demo3")public String demo3() {System.out.println("demo3...");return "index";}}
  1. 编写拦截器的java类,实现HandlerInterceptor接口
package com.bdqn.interceptor;public class MyInterceptor implements HandlerInterceptor {//在控制器之前执行,并且返回是否放行。true:放行,false:不放行public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("控制器之前执行...");return true;}//在控制器执行之后,页面显示之前执行。控制器报错不执行!public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception{System.out.println("控制器之后,页面之前执行...");}//页面显示完成之后,执行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {System.out.println("页面之后执行...");}}

2.  修改SpringMvcConfig 配置类添加拦截器

@Configuration@EnableWebMvc@ComponentScan({"com.bdqn.controller"})public class SpringMvcConfig implements WebMvcConfigurer {/*** 配置拦截器*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {//将拦截器添加到Springmvc环境,默认拦截所有Springmvc分发的请求registry.addInterceptor(new MyInterceptor());}}

   3.  配置详解

       1. 默认拦截全部

 @Override
 
public void addInterceptors(InterceptorRegistry registry) {
     
//将拦截器添加到Springmvc环境,默认拦截所有Springmvc分发的请求
    
registry.addInterceptor(new MyInterceptor());
 }

   2.精准配置

@Overridepublic void addInterceptors(InterceptorRegistry registry) {    //精准匹配,设置拦截器处理指定请求 路径可以设置一个或者多个,为项目下路径即可//addPathPatterns("/path") 添加拦截路径//也支持 /*  /** 模糊路径。 * 任意一层字符串 ** 任意层 任意字符串registry.addInterceptor(new  MyInterceptor()).addPathPatterns("/demo01","/demo02");}

  3.排除配置

@Overridepublic void addInterceptors(InterceptorRegistry registry) { //排除匹配,排除应该在匹配的范围内排除//excludePathPatterns("/path"); 排除路径,排除应该在拦截的范围内registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/demo01");}

4.多个拦截器执行顺序

1. preHandle() 方法:SpringMVC 会把所有拦截器收集到一起,然后按照配置顺序调用各个 preHandle() 方法。

2. postHandle() 方法:SpringMVC 会把所有拦截器收集到一起,然后按照配置相反的顺序调用各个 postHandle() 方法。

3. afterCompletion() 方法:SpringMVC 会把所有拦截器收集到一起,然后按照配置相反的顺序调用各个 afterCompletion() 方法。

后台管理系统搭建:

1.MVC三层架构层

Pojo

Dao

Service

Controllor

interceptor

Jsp

2.jsp页面要求

1. 除了login.jsp以外的所有页面都不能直接访问。必须放到/WEB-INF/pages/文件夹下。

           /WEB-INF/文件下内容都不能直接访问。

2. 要想访问/WEB-INF/下的页面必须通过控制器才能访问。

控制器编写访问页面的控制器方法

@Controller

public class PageController {

    /*根据控制方法,显示指定页面*/

    @RequestMapping("{page}")

    public String page(@PathVariable String page) {

        return page;

    }

}

   3. 配置视图解析器

/*** 配置视图解析器*/@Overridepublic void configureViewResolvers(ViewResolverRegistry registry) {//加上前缀和后缀registry.jsp("/WEB-INF/pages/",".jsp");}

3.登录拦截器  LoginInterceptor

/*进行登录验证*/

public class LoginInterceptor implements HandlerInterceptor {/*** 进入控制器之前执行,先验证用户是否登录*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session=request.getSession();User user=(User)session.getAttribute("user");//判断用户是否登录,如果没有登录,跳转登录页面,不放行if(user==null){response.sendRedirect("login.jsp");return false;}return true;}}

4. SpringMvc中配置登录的拦截器

/*** 配置拦截器*/public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/user/login");}

注意:会出现资源访问的路径问题

  1. Jsp中静态资源从项目名开始写路径

Jsp获取当前项目名称

${pageContext.request.contextPath}

      2.Controller中的跳转到控制器请加上/,代表项目名称

return "redirect:/getAll";


http://www.mrgr.cn/news/58893.html

相关文章:

  • 格姗知识圈博客网站开源了!
  • TLS协议基本原理与Wireshark分析
  • go 内存分配管理
  • 代码随想录:二叉树层序遍历系列
  • 如何评估Mechanize和Poltergeist爬虫的效率和可靠性?
  • vue富文本使用editor
  • 了解Oracle表结构查询:获取列信息与注释
  • Mac打开环境变量配置文件,source ~/.zshrc无法打开问题解决
  • 分享一款录屏、直播软件
  • 计算机组成原理之指令系统的基本概念、指令格式
  • 数学之三角函数
  • 太香了,用AI做育儿账号带货,卖出2.1万件赚佣金10W+
  • Spring Boot框架下的厨艺社交网络构建
  • IP协议详解:报头格式、主机定位、转发流程、网段划分与路由机制
  • 算法刷题-小猫爬山
  • 《打造 C++团队知识库:提升团队实力,开启高效编程之旅》
  • 函数递归
  • 嵌入式软开——八股文——学习引导和资料网址
  • 【微服务】Java 对接飞书多维表格使用详解
  • C++的IO流(文件部分在这里)
  • 软考高级架构-7.2-基于架构的软件开发方法-超详细讲解+精简总结
  • Redis混合持久化原理
  • android——渐变色
  • Spring Boot技术在厨艺社交平台中的应用
  • django游戏门户系统
  • springboot体重管理与健康饮食推荐小程序计算机设计毕业源码15351