0
点赞
收藏
分享

微信扫一扫

webpack 与 grunt、gulp 的不同?

祈澈菇凉 2023-11-02 阅读 49

前言

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

一、前期准备

1、新建项目,结构如下

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>
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;
    }
}
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;
        }

    }
}

三、局部异常

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;
    }
}
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,"账号密码错误");
    }

}
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;
    }

 四、全局异常

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;
    }

}
 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 后就要使用全局的处理异常。比起原始的 try catch 语句块处理异常是不是简洁很多了,我们把同样的事情单独放在一个类中去完成,就不会像刚刚那样把所有代码都写在控制器中那么臃肿了。

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

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

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

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

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

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

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

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

七、gitee 案例 

地址:ch09 · qiuqiu/SpringMVC - 码云 - 开源中国 (gitee.com)

举报

相关推荐

0 条评论