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

SpringMVC全局异常处理+拦截器使用+参数校验

SpringMVC全局异常处理+拦截器使用+参数校验

SpringMVC 是 Spring 框架中用于构建 Web 应用程序的模块。为了提高应用程序的稳定性和用户体验,全局异常处理、拦截器的使用和参数校验是必须掌握的技术。以下将详细介绍这些内容。

全局异常处理

全局异常处理能够有效捕获并处理应用程序中的异常,防止异常信息直接暴露给用户,从而提高应用的安全性和用户体验。

1. 使用 @ControllerAdvice 注解

@ControllerAdvice 是 Spring 提供的一个用于全局处理控制器里异常的注解。它可以捕获所有控制器中的异常,并进行统一处理。

示例代码:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> handleException(Exception e) {
        return new ResponseEntity<>("服务器内部错误:" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) {
        return new ResponseEntity<>("无效参数:" + e.getMessage(), HttpStatus.BAD_REQUEST);
    }
}
​

在上述代码中,@ExceptionHandler 注解指定了不同的异常处理方法,@ResponseStatus 注解用于设置返回的 HTTP 状态码。

2. 使用 @ExceptionHandler 注解

@ExceptionHandler 注解可以直接在控制器中使用,用于处理特定方法的异常。

示例代码:

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.http.HttpStatus;

@Controller
public class MyController {

    @RequestMapping("/example")
    public String exampleMethod() {
        // 代码可能抛出异常
        throw new IllegalArgumentException("Invalid argument");
    }

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleIllegalArgumentException(IllegalArgumentException e) {
        return "error/400"; // 返回视图名
    }
}
​

拦截器的使用

拦截器(Interceptor)是 AOP(面向切面编程)在 Spring 中的应用之一,可以在请求到达控制器之前和之后执行逻辑,用于处理身份验证、日志记录等任务。

1. 实现 HandlerInterceptor 接口

要创建一个拦截器,需要实现 HandlerInterceptor 接口,并重写其方法。

示例代码:

import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 请求处理之前执行
        System.out.println("拦截器:请求处理之前");
        return true; // 返回 true 表示继续处理请求,返回 false 表示中断请求
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 请求处理之后,视图渲染之前执行
        System.out.println("拦截器:请求处理之后,视图渲染之前");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 完全处理完请求之后执行
        System.out.println("拦截器:请求完全处理之后");
    }
}
​
2. 注册拦截器

拦截器需要在配置类中注册才能生效。

示例代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/**"); // 拦截所有请求
    }
}
​

参数校验

参数校验是确保传入的请求参数符合预期的一种手段,可以有效防止无效数据导致的异常和错误。

1. 使用 JSR-303/JSR-380 注解

Spring MVC 支持 JSR-303/JSR-380(Bean Validation),可以使用注解对请求参数进行校验。

示例代码:

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

public class User {

    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 20, message = "用户名长度必须在3到20之间")
    private String username;

    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 20, message = "密码长度必须在6到20之间")
    private String password;

    // Getter 和 Setter
}
​
2. 在控制器中使用 @Valid 注解

在控制器方法参数中使用 @Valid 注解进行参数校验,并使用 BindingResult 对象捕获校验结果。

示例代码:

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/register")
    public ResponseEntity<String> register(@Valid @RequestBody User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return new ResponseEntity<>(bindingResult.getFieldError().getDefaultMessage(), HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>("注册成功", HttpStatus.OK);
    }
}

http://www.kler.cn/a/531481.html

相关文章:

  • 在线知识库的构建策略提升组织信息管理效率与决策能力
  • 本地快速部署DeepSeek-R1模型——2025新年贺岁
  • 深度学习之“缺失数据处理”
  • CSS Fonts(字体)
  • 【自然语言处理(NLP)】深度学习架构:Transformer 原理及代码实现
  • 前端进阶:深度剖析预解析机制
  • C语言的物联网
  • 基于SpringBoot的信息技术知识赛系统的设计与实现(源码+SQL脚本+LW+部署讲解等)
  • bagging框架
  • 什么是 Shell?常见的 Unix Shell有哪些?(中英双语)
  • 【数据结构】_链表经典算法OJ:复杂链表的复制
  • C++基础day1
  • 5分钟在本地PC上使用VLLM快速启动Mistral-Small-24B-Instruct-2501
  • 【思维导图】redis
  • 深入理解开放寻址法中的三种探测序列
  • Java程序设计:掌握核心语法与经典案例
  • 笔试-业务逻辑4
  • 在线销售数据集分析:基于Python的RFM数据分析方法实操训练
  • java_String类
  • DeepSeek大模型系列
  • Visual Studio Code应用本地部署的deepseek
  • 高并发、高可用的消息队列(MQ)设计与实战
  • 前端架构师的职责之我见
  • 计算图 Compute Graph 和自动求导 Autograd | PyTorch 深度学习实战
  • 基于STM32的智能安防监控系统
  • Kubernetes常见问答(一)