SpringMVC Day 09 : 异常处理

这篇具有很好参考价值的文章主要介绍了SpringMVC Day 09 : 异常处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在Web应用程序开发中,我们经常会遇到各种各样的错误和异常情况。那么如何有效地捕获和处理这些异常呢?本文将介绍Spring MVC中的异常处理机制,帮助您构建更稳定、可靠的Web应用程序。

一、前期准备

1、新建项目,结构如下

SpringMVC Day 09 : 异常处理,SpringMVC,java,spring,mvc,jetty,logback

2、导入依赖
    <dependencies>
    
        <!-- springmvc 依赖,会将spring的核心包一并添加进来 -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.23</version>
        </dependency>
     
 
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
 
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.5</version>
        </dependency>
 
 
 
    </dependencies>
 3、配置 web.xml 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


</web-app>

用于配置 Servlet 的映射和加载。在 Spring MVC 中,它用于配置 DispatcherServlet 的初始化和请求映射。

具体来说,这段配置的作用如下:

  1. 定义了一个名为 "dispatcher" 的 Servlet,并指定了 org.springframework.web.servlet.DispatcherServlet 作为其处理类。
  2. 设置了 load-on-startup 属性为 1,表示在应用启动时就加载该 Servlet。
  3. 使用 <servlet-mapping> 元素将 "dispatcher" Servlet 映射到所有的请求路径上(即 <url-pattern>/</url-pattern>),意味着所有的请求都会经过该 Servlet 进行处理。

 这段配置的作用是将所有的请求交给 DispatcherServlet 处理,并让它成为应用的核心控制器。DispatcherServlet 将根据请求的 URL 和其他配置信息,将请求分发给相应的处理器方法进行处理,然后返回响应结果。
 

4、新建一个 User 类
@Data
public class User {

    private String userName;
    private String password;

}
5、新建一个 UserDao 接口
public interface UserDao {


    User getUser(String userName);

}
 6、新建一个 UserDaoImpl 实现类
@Repository
@Slf4j
public class UserDaoImpl implements UserDao {
    @Override
    public User getUser(String userName) {
        log.info("select * from user ");
        User user = new User();
        user.setUserName("qiu");
        user.setPassword("88888888");
        return user;
    }
}

 使用日志简单的输出,并封装数据到 user 实体中。

7、新建一个 LoginService
public interface LoginService {

    /**
     * 验证用户
     * @param userName
     * @param password
     * @return
     */
    User auth(String userName,String password);

}

二、传统的 try catch 处理异常

1、编写 controller 类
@RestController
@RequiredArgsConstructor
@Slf4j
public class UserController {

    private final LoginService loginService;


    @PostMapping("/login")
    public ResultVO login(String userName, String password, HttpSession session){

        try{
            User user = loginService.auth(userName, password);
            // 将 user 保存到会话中
            user.setUserName(userName);
            user.setPassword(password);
            session.setAttribute("user",user);

            return new ResultVO();
        } catch (AuthException e){
            // 验证未通过则创建提示信息
            ResultVO resultVO = new ResultVO();
            resultVO.setCode(e.getErroeCode());
            resultVO.setMessage(e.getMessage());
            return resultVO;
            // 捕获其他非业务异常(也就是服务器内部错误异常)
        } catch (RuntimeException e){
            // 记录异常日志
            log.error(e.getMessage());
            // 验证未通过则创建提示信息
            ResultVO resultVO = new ResultVO();
            resultVO.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            resultVO.setMessage("服务器内部错误,请稍候重试");
            return resultVO;
        }

    }
}

我们使用之前的方法是不是需要有很多个 catch 语句块去抛出多个异常,这还是异常少的例子,如果还有更多的异常,还要很多的 catch 语句块,这样就会显得我们的 Controler 很臃肿。我们的控制器不能有这么多的多余的代码,那么有没有办法把异常信息抽取出来呢?

三、局部异常

1、自定义一个异常类来处理业务类的异常(登录)

/**
 * @Date 2023-10-27
 * @Author qiu
 * 自定义异常
 */
public class AuthException extends RuntimeException{

    /**
     * 异常状态码
     */
    private Integer erroeCode;

    public AuthException(Integer erroeCode,String message){
        super(message);
        this.erroeCode =erroeCode;
    }

    public Integer getErroeCode() {
        return erroeCode;
    }
}

这是一个自定义异常类AuthException的示例代码。

该异常类继承自RuntimeException,因此是一个运行时异常。它的目的是在程序中处理身份验证相关的异常情况。

在该类中,有两个成员变量:

  • erroeCode:表示异常状态码,用于标识不同的异常情况。
  • message:异常的详细信息。

构造方法AuthException(Integer erroeCode, String message)用于创建AuthException对象,并接受一个异常状态码和异常信息作为参数。它调用父类的构造方法super(message)来设置异常信息,并将异常状态码赋值给成员变量erroeCode

同时,类中提供了getErroeCode()方法用于获取异常状态码。

通过自定义异常类,可以在程序中抛出和捕获AuthException对象,以便对身份验证过程中的异常进行更细粒度的处理和控制。

2、完成 LoginImpl 实现类

@Service
@Slf4j
@RequiredArgsConstructor
public class LoginServiceImpl implements LoginService {

    private final UserDao userDao;

    @Override
    public User auth(String userName, String password) {

        User user = userDao.getUser(userName);
        // 用户不为 Null 则校验密码
        if ( user != null ){
            if ( password.equals(user.getPassword())){
                return user;
            }
        }
        // 抛出业务异常
        throw new AuthException(10001,"账号密码错误");
    }

}

在类中,定义了一个userDao成员变量,并通过构造方法注入UserDao对象。

实现了LoginService接口中的auth()方法,用于进行用户名和密码的校验。首先通过userDao.getUser(userName)方法获取对应用户名的用户对象,然后判断用户是否存在以及密码是否匹配。如果匹配成功,则返回用户对象;否则,抛出一个业务异常AuthException,并设置异常状态码为10001,异常信息为"账号密码错误"。

通过LoginServiceImpl类,可以实现用户登录认证的功能,并且在校验失败时抛出自定义的业务异常,以便后续处理和提供详细的错误提示。

3、使用 @ExceptionHandler 注解
    /**
     * 局部异常处理,处理登录业务异常
     * @ExceptionHandler:注解标注的方法专门用于处理请求方式产生的异常。
     * value:属性指定要处理的异常类型
     * 注意:这个局部异常的范围只在当前的 Controller 中有效,也就是说
     * 每个 controller 都有自己专门的 handlerException
     * @param e
     * @return
     */
    @ExceptionHandler(AuthException.class)
    public ResultVO handlerAuthException(AuthException e){
        // 验证未通过则创建提示信息
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(e.getErroeCode());
        resultVO.setMessage(e.getMessage());
        return resultVO;
    }

这是一个局部异常处理的示例代码,用于处理登录业务异常。

在该代码中,使用@ExceptionHandler注解标记了一个方法,该方法专门用于处理AuthException类型的异常。value属性指定要处理的异常类型,即AuthException.class

当控制器(Controller)中的请求处理方法抛出AuthException异常时,Spring框架会自动调用该方法进行异常处理。在该方法中,首先创建一个ResultVO对象作为返回结果,并将异常状态码和异常信息设置到ResultVO对象中。然后将ResultVO对象作为方法的返回值返回。最终,将返回结果以JSON格式返回给客户端。

通过局部异常处理,可以提高代码的可读性和可维护性,将异常处理逻辑从业务逻辑中分离出来,并且能够对不同类型的异常做出不同的响应。

 四、全局异常

1、新建 ExceptionAdvice 类

/**
 * @Date 2023-10-27
 * @Author qiu
 * 定义一个全局异常处理类(类似一个切面)
 * 这个类中定义所有的异常处理方法,也可以
 * 理解为全局异常通知
 */
//@ControllerAdvice (对应 @Controller 注解的类)

// (对应 @RestController 注解的类)
// value 屬性 controller 包下所有类都需要捕获异常
@RestControllerAdvice("edu.nf.ch09.controller")

@Slf4j
public class ExceptionAdvice {

    /**
     * 全局异常处理,处理登录业务异常
     * @ExceptionHandler:注解标注的方法专门用于处理请求方式产生的异常。
     * value:属性指定要处理的异常类型
     * 注意:这个局部异常的范围只在当前的 Controller 中有效,也就是说
     * 每个 controller 都有自己专门的 handlerException
     * @param e
     * @return
     */
    @ExceptionHandler(AuthException.class)
    public ResultVO handlerAuthException(AuthException e){
        // 验证未通过则创建提示信息
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(e.getErroeCode());
        resultVO.setMessage(e.getMessage());
        return resultVO;
    }


    /**
     * 全局的异常处理(处理非业务异常,如:数据库异常)
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public ResultVO handlerRunTimeException(RuntimeException e ){
        // 捕获其他非业务异常(也就是服务器内部错误异常)
        // 记录异常日志
        log.error(e.getMessage());
        // 验证未通过则创建提示信息
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        resultVO.setMessage("服务器内部错误,请稍候重试");
        return resultVO;
    }

}

这是一个全局异常处理类,用于统一处理控制器中抛出的异常。

在该代码中,使用@RestControllerAdvice注解标记了一个类,该类是一个切面,用于处理全局异常。通过value属性指定了需要捕获异常的控制器层(Controller)所在的包路径。

在该类中,定义了两个异常处理方法。

  1. handlerAuthException方法用于处理AuthException类型的异常。当控制器中的请求处理方法抛出AuthException异常时,Spring框架会自动调用该方法进行异常处理。在该方法中,首先创建一个ResultVO对象作为返回结果,并将异常状态码和异常信息设置到ResultVO对象中。然后将ResultVO对象作为方法的返回值返回。

  2. handlerRunTimeException方法用于处理RuntimeException类型的异常(即非业务异常,如数据库异常等)。当控制器中的请求处理方法抛出RuntimeException异常时,Spring框架会自动调用该方法进行异常处理。在该方法中,首先记录异常日志,然后创建一个ResultVO对象作为返回结果,并设置一个服务器内部错误的提示信息和状态码。最终将ResultVO对象作为方法的返回值返回。

通过全局异常处理类,可以集中处理控制器中抛出的异常,并返回统一的响应结果,提高代码的可读性和可维护性。

我们把异常都放在这个类来处理,就不用在 controller 写那么多处理异常代码了。

 2、编写 controller 类
@RestController
@RequiredArgsConstructor
@Slf4j
public class UserController {

    private final LoginService loginService;

    @PostMapping("/login")
    public ResultVO login(String userName, String password, HttpSession session){

        User user = loginService.auth(userName, password);
        // 将 user 保存到会话中
        user.setUserName(userName);
        user.setPassword(password);
        session.setAttribute("user",user);

        return new ResultVO();

    }
}

 在控制器中只需要完成对业务类的方法调用即可,不用去考虑异常怎么处理。

3、运行效果

SpringMVC Day 09 : 异常处理,SpringMVC,java,spring,mvc,jetty,logback

五、总结

本次案例,介绍了三种处理异常的方式,我们学习了 SpringMVC 后就要使用全局的处理异常。比起原始的 try catch 语句块处理异常是不是简洁很多了,我们把同样的事情单独放在一个类中去完成,就不会像刚刚那样把所有代码都写在控制器中那么臃肿了。

六、使用 Springmvc 异常处理的好处 

使用Spring MVC异常处理的好处有以下几个方面:

  1. 统一异常处理:通过在全局配置中定义统一的异常处理类,可以集中处理应用程序中所有控制器抛出的异常。这样可以减少代码重复,提高代码的可维护性和可读性。

  2. 简化异常处理逻辑:在应用程序的控制器中,通常需要编写大量的异常处理代码来处理各种可能发生的异常情况。使用Spring MVC的异常处理功能,可以将这些异常处理逻辑从控制器中抽离出来,使得控制器代码更加简洁和清晰。

  3. 统一错误信息:通过自定义异常处理类,可以将不同类型的异常映射到统一的错误信息,并返回给客户端。这样可以提供一致的错误信息格式,便于前端进行处理和展示。

  4. 异常日志记录:在异常处理类中,可以对异常进行日志记录,包括异常的详细信息、发生异常的时间等。这样可以帮助开发人员快速定位和解决问题,提高系统的可靠性和稳定性。

  5. 提升用户体验:通过合理地处理异常,可以向用户提供更友好的错误提示信息,避免出现系统默认的错误页面或者错误信息。这样可以提升用户体验,增加系统的可用性。

总之,使用Spring MVC的异常处理功能可以简化开发过程,提高代码的可维护性和可读性,提供统一的错误信息和日志记录,并提升用户体验。这些优势使得Spring MVC成为开发Web应用程序时的首选框架之一。

七、gitee 案例 

地址:ch09 · qiuqiu/SpringMVC - 码云 - 开源中国 (gitee.com)文章来源地址https://www.toymoban.com/news/detail-738961.html

到了这里,关于SpringMVC Day 09 : 异常处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring MVC配置全局异常处理器!!!

    为什么要使用全局异常处理器:如果不加以异常处理,错误信息肯定会抛在浏览器页面上,这样很不友好,所以必须进行异常处理。 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图: 结果展示:  

    2024年01月15日
    浏览(44)
  • Spring MVC文件上传及全局异常处理器

    编写controller 在index.jsp里面定义超链接 如果不加以异常处理,错误信息肯定会抛在浏览器页面上,这样很不友好,所以必须进行异常处理。 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图: 编写c

    2024年01月18日
    浏览(48)
  • 【Java】异常处理 之 使用SLF4J 和 Logback

    前面介绍了 Commons Logging 和 Log4j 这一对好基友,它们一个负责充当日志 API,一个负责实现日志底层,搭配使用非常便于开发。 有的童鞋可能还听说过 SLF4J 和 Logback 。这两个东东看上去也像日志,它们又是啥? 其实 SLF4J 类似 于Commons Logging ,也是一个日志接口,而 Logback 类似

    2024年02月12日
    浏览(50)
  • [第二章—Spring MVC的高级技术] 2.3 处理异常

    各位小猿,程序员小猿开发笔记,希望大家共同进步。 引言 我是谁——异常处理。 来自那——所有功能正常运行,但出现错误 怎么办——如何处理异常和响应客户端 我是谁——Spring框架中的一个注解 用在哪——应用在控制器类或方法上 什么用——用于在控制器方法中指定

    2024年01月22日
    浏览(48)
  • 解密Spring MVC异常处理:从局部到全局,打造稳固系统的关键步骤

    😀前言 在现代软件开发中,异常处理是不可或缺的一部分,它能够有效地提高系统的稳定性和健壮性。在Spring MVC框架中,异常处理机制起着至关重要的作用,它允许开发者在程序运行过程中捕获、处理和报告异常,从而保障用户体验和系统可靠性。本文将带您深入探索Spr

    2024年02月10日
    浏览(42)
  • DAY09_SpringBoot—整合SpringMVC&SpringMVC参数取值用法

    Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一

    2024年01月25日
    浏览(42)
  • Spring MVC学习随笔-Ajax集成(JSON格式返回数据)、拦截器(MyInterceptor)、全局异常处理(GlobalExceptionResolver)

    学习视频:【编程不良人】继spring之后快速入门springmvc,面对SpringMVC不用慌 引入相关依赖 开发控制器 日期格式修正 可以正常响应 拦截器 :Interceptor 拦截 中断 类似于javaweb中的Filter,不过没有Filter那么强大 作用 Spring MVC的拦截器是一种用于在请求处理过程中进行预处理和后处

    2024年02月05日
    浏览(48)
  • (第十一天)初识SpringMVC SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录

    今天我们要来学习一下SSM框架的最后一个框架SpringMVC 一、初认SpringMVC 基本概念: ​ Spring MVC(Model-View-Controller)是一个用于构建Java Web应用程序的开源框架,它提供了一种基于MVC架构的方式来开发Web应用 。 ​ SpringMVC是Spring Framework的一部分,它是一种基于模型-视图-控制器(

    2024年02月07日
    浏览(67)
  • Spring Mvc:初识SpringMvc

    编译软件:IntelliJ IDEA 2019.2.4 x64 操作系统:win10 x64 位 家庭版 Maven版本:apache-maven-3.6.3 Mybatis版本:3.5.6 SpringMvc版本:5.3.1 ①SpringMVC是Spring的一种 子框架 ,它是Spring为【 展现层 | 表示层 | 表述层 | 控制层 】提供的 基于MVC设计理念 的优秀的Web框架,是目前最主流的MVC框架。

    2024年02月13日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包