Spring接口常用自定义功能
前言
在我们接口开发过程中,往往会遇到不少问题,如:身份校验,登录拦截,数据过滤,参数处理,限流等。这时候Spring预留的一些接口类就派上用场了,本文记录了一些常用的实现代码,如下文所示:
接口拦截器
创建自定义拦截器主要有两种方式
实现
org.springframework.web.servlet.HandlerInterceptor接口继承已经实现了
org.springframework.web.servlet.HandlerInterceptor接口的类,如:org.springframework.web.servlet.handler.HandlerInterceptorAdapter
主要方法介绍
在具体的业务处理器(接口)之前调用,常做用于
身份校验,登录拦截等功能
/**
* @param request current HTTP request
* @param response current HTTP response
* @param handler 选择要执行的处理程序
* @return 是否继续执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// do something
return true;
}在具体的业务处理器(接口)之后调用,但在视图解析(接口返回)之前调用,常做用于修改
ModelAndView
/**
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler
* @param modelAndView 处理程序(接口)返回值
* @throws Exception e
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// do something
}在视图解析(接口返回)成功之后调用,常做用于
资源释放等
/**
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler
* @param ex 处理程序执行抛出的异常(不包括异常处理器已处理的)
* @throws Exception e
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// do something
}接口参数解析器
在我们进行接口开发的时候,不知道大家有没有发现一个问题:javax.servlet.http.HttpServletRequest对象,请求也没有传给我这个对象啊,它是怎么能够做到我在接口方法上声明了就能够拿到的?
没错,这就是由Spring内置的一个参数解析器帮我们自动注入的:org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver ,它实现了org.springframework.web.method.support.HandlerMethodArgumentResolver 接口。
创建自定义参数解析器
实现上述的
HandlerMethodArgumentResolver接口
主要方法介绍
判断当前参数解析器是否支持处理此类型的参数
/**
* @param methodParameter 方法参数的包装对象
* @return 是否支持处理
*/
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
// do something
return true;
}判断当前参数解析器是否支持处理此类型的参数
/**
* @param methodParameter 方法参数的包装对象
* @param modelAndViewContainer 视图模型容器
* @param nativeWebRequest the current request
* @param webDataBinderFactory 用于创建 DataBinder 对象工厂
* @return 参数解析器注入到接口的具体对象
*/
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
// do something
return new Object();
}接口异常处理器
众所周知,不存在没有Bug的软件,总有一些难以发现的问题会埋在软件中,不知道哪天会爆炸,从而影响用户使用。
此时,增加一个接口异常处理机制就显得非常有必要了,它有如下优点:
异常处理器可以帮助程序在遇到意外情况时不会崩溃,而是优雅地处理错误,继续执行或安全地退出。
当程序遇到问题时,通过友好的错误消息告知用户,可以提升用户体验。
异常处理器可以用来记录错误发生的上下文信息,这对于调试和后续的日志分析非常有用。
异常处理器可以使代码更加模块化,具体业务代码中只需要关注自己的业务代码即可,而错误处理则由专门的异常处理器来完成。
它不仅提高了程序的健壮性和可用性,还使得代码更加清晰和易于维护。
主要注解介绍
org.springframework.web.bind.annotation.ControllerAdvice :此注解作用与类上,声明一个类为全局异常处理器
org.springframework.web.bind.annotation.RestControllerAdvice :同上,相当于@ControllerAdvice 额外加上@ResponseBody 注解
org.springframework.web.bind.annotation.ExceptionHandler :此注解作用与方法上,其内部有一个Class<? extends Throwable>[]类型的属性,意思为声明一个方法为捕获此些异常类型的异常处理方法
org.springframework.web.bind.annotation.ControllerAdvice局部异常处理
@RestController
@RequestMapping("/test")
public class TestController {
@ExceptionHandler(RuntimeException.class)
public Object notFountRuntimeException(RuntimeException e) {
// do something
return new Object();
}
}全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public Object notFountRuntimeException(RuntimeException e) {
// do something
return new Object();
}
}注意:当产生一个符合多个异常处理器的异常时,会根据就近原则执行对应的异常处理方法,优先级如下:
局部>全局,子类>父类
静态资源映射
静态资源映射是指在 Web 应用程序中,服务器如何处理对静态文件(如 HTML 页面、CSS 样式表、JavaScript 脚本、图像文件等)的 HTTP 请求。在 Web 开发中,静态资源通常不会被应用程序逻辑直接修改或生成,而是直接由 Web 服务器提供给客户端。
在项目中默认的静态资源存放目录可能会不满足我们的要求,这个时候就需要额外的配置了:
配置文件方式
Spring.xml配置
<mvc:resources mapping="/resources/**" location="/data/resources/"/>SpringBoot
spring:
resources:
static-locations: classpath:/custom-static/, file:/var/www/static/spring.resources.static-locations=classpath:/custom-static/, file:/var/www/static/配置类
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 开放一个/static/**的路径
registry.addResourceHandler("/custom-static/**")
// 访问上方路径时去这两个目录下寻找对应的文件,其中[file:/**]表示文件系统中的绝对路径
.addResourceLocations("classpath:/custom-static/", "file:/var/www/static/");
}
}