SpringBoot-全局处理异常,时间格式,跨域,拦截器,监听器

目录

  1. 引言
  2. 全局处理异常
  3. 时间格式处理
  4. 跨域处理
  5. 拦截器
  6. 监听器
  7. 总结

引言

随着微服务架构的流行,Spring Boot 已经成为了开发 RESTful API 的热门选择。在实际的开发过程中,我们经常会遇到一些通用的需求,比如全局异常处理、时间格式化、跨域请求处理、请求拦截以及事件监听等。本文将详细介绍这些功能的实现方式,并通过实例来阐述每个部分的应用场景。

全局处理异常

在 Spring Boot 应用中,异常处理是非常重要的一部分。我们希望能够统一处理所有的异常情况,以便向用户提供一致的错误信息。

1.1 使用 @ControllerAdvice 处理异常

@ControllerAdvice 是一个用于全局处理控制器异常的注解。它能够捕获所有控制器抛出的异常。

javaCopy Code
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<String> handleAllExceptions(Exception ex) { return new ResponseEntity<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } }

场景:当系统出现未被捕获的异常时,可以使用此方法返回一个统一的错误响应。

1.2 自定义异常类

我们可以定义自定义异常类,以便更精确地控制异常信息。

javaCopy Code
public class CustomException extends RuntimeException { public CustomException(String message) { super(message); } }

GlobalExceptionHandler 中添加对 CustomException 的处理:

javaCopy Code
@ExceptionHandler(CustomException.class) public ResponseEntity<String> handleCustomException(CustomException ex) { return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); }

1.3 返回统一格式

为了统一返回格式,我们可以定义一个响应体类。

javaCopy Code
public class ErrorResponse { private String message; private int status; public ErrorResponse(String message, int status) { this.message = message; this.status = status; } // getters and setters }

然后在异常处理器中返回这个对象:

javaCopy Code
@ExceptionHandler(CustomException.class) public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex) { ErrorResponse errorResponse = new ErrorResponse(ex.getMessage(), HttpStatus.BAD_REQUEST.value()); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); }

时间格式处理

在处理日期和时间时,常常需要将其格式化为特定的字符串形式。

2.1 使用 Jackson 配置时间格式

Spring Boot 默认使用 Jackson 进行 JSON 序列化,我们可以通过配置属性来指定时间格式。

application.properties 文件中添加:

propertiesCopy Code
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

2.2 自定义时间格式化

如果我们需要在代码中动态控制时间格式,可以使用 @JsonFormat 注解。

javaCopy Code
import com.fasterxml.jackson.annotation.JsonFormat; public class User { private String name; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") private Date createdAt; // getters and setters }

跨域处理

跨域请求是指在不同域之间发送请求。为了支持跨域,我们需要进行相应的配置。

3.1 使用 @CrossOrigin 注解

在 Controller 类上使用 @CrossOrigin 注解可以允许跨域请求。

javaCopy Code
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @CrossOrigin(origins = "http://localhost:8080") public class MyController { @GetMapping("/api/data") public String getData() { return "Hello World"; } }

3.2 全局跨域配置

如果希望全局处理跨域请求,可以在配置类中进行设置。

javaCopy Code
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("http://localhost:8080"); } }

拦截器

拦截器可以用于对请求进行预处理和后处理。

4.1 创建拦截器

我们可以创建一个实现 HandlerInterceptor 接口的拦截器。

javaCopy Code
import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 请求前处理 System.out.println("Request URL: " + request.getRequestURL()); return true; // 返回 true 继续执行,返回 false 将终止请求 } }

4.2 注册拦截器

在配置类中注册拦截器。

javaCopy Code
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("/api/**"); } }

4.3 拦截器中的逻辑

preHandle 方法中,我们可以添加逻辑,比如验证用户身份、记录日志等。

监听器

监听器用于监听特定的事件并作出响应。

5.1 事件发布与监听

Spring 提供了事件发布和监听的机制。我们可以自定义事件。

javaCopy Code
import org.springframework.context.ApplicationEvent; public class CustomEvent extends ApplicationEvent { private final String message; public CustomEvent(Object source, String message) { super(source); this.message = message; } public String getMessage() { return message; } }

发布事件:

javaCopy Code
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; @Service public class EventService { @Autowired private ApplicationEventPublisher publisher; public void publishEvent(String message) { CustomEvent event = new CustomEvent(this, message); publisher.publishEvent(event); } }

5.2 使用 ApplicationListener

我们可以创建一个监听器来处理发布的事件。

javaCopy Code
import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class CustomEventListener implements ApplicationListener<CustomEvent> { @Override public void onApplicationEvent(CustomEvent event) { System.out.println("Received event: " + event.getMessage()); } }

总结

本文详细介绍了 Spring Boot 中全局处理异常、时间格式化、跨域处理、拦截器和监听器的实现方法。通过示例代码和场景描述,相信读者能够对这些概念有更深入的理解。在实际开发中,根据业务需求灵活运用这些特性,将有助于提升应用的可维护性和用户体验。