自定义 Spring MVC Controller 方法参数处理

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 【6月更文挑战第3天】在 Spring MVC Controller 的方法参数,Spring 会自动为我们注入一些特殊的参数值,比如 HttpServletRequest、HttpServletResponse 等对象,或者 HTTP 请求参数。

在 Spring MVC Controller 的方法参数,Spring 会自动为我们注入一些特殊的参数值,比如 HttpServletRequest、HttpServletResponse 等对象,或者 HTTP 请求参数。有时候,我们也可以在 Controller 中使用 @InitBinder 注解的方法,来自定义转换请求参数的逻辑。对于在整个工程的诸多地方都需要的相同的转换逻辑,我们还可以自定义一个全局的参数转换处理逻辑。

比较常见的是,很多请求方法中会需要读取当前登录的用户信息,我们以此为例,来实现一个自定义的参数处理逻辑。

最终实现的效果是,可以将保存在 Session 中的当前登录用户的 ID,注入到请求处理方法的某个参数重,这个参数使用一个注解来标记,比如这样:

@GetMapping("current")
public String right(@CurrentUserId Long userId) {
   
    return userId;
}

自定义注解的代码比较简单:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@Documented
public @interface CurrentUserId {
   
}

要使Controller 中的方法能够自动获取到当前登录用户的id,我们需要写一个参数处理的类,这个类需要继承 HandlerMethodArgumentResolver 类,并实现其中的方法:

public class CurrentUserIdArgumentResolver implements HandlerMethodArgumentResolver {
   
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
   
        return methodParameter.hasParameterAnnotation(CurrentUserId.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
   
        Object result = nativeWebRequest.getAttribute("currentUserId", NativeWebRequest.SCOPE_SESSION);
        return object;
    }
}

以上的方法当中,第一个方法,用来判断这个参数处理器支持哪些参数,方法返回 true/false 表示是否支持,这里的判断逻辑就是参数是不是有 CurrentUserId 注解。

第二个方法是具体的处理逻辑,我们这里的示例代码比较简单,直接从 Session 中读取到相应的内容,作为返回值返回。在真实的项目当中,要根据具体的业务逻辑来指定 Session key 并作必要的判断。

最后,需要将我们自定义的参数处理器配置到 Spring MVC 中。新建一个 WebMvcConfig 类,实现 WebMvcConfigurer 接口,再重写的 addArgumentResolvers 方法中添加刚刚自定义的参数处理类即可。


@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
   
...
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
   
        resolvers.add(new CurrentUserIdArgumentResolver());
    }
}

大功告成,这样,我们就可以像文章开头的那样,在 Controller 方法中使用带有自定义的注解的参数,直接获取到当前登录用户的 ID。

目录
相关文章
|
10天前
|
前端开发 Java Spring
Spring MVC 是如何对对象参数进行校验的
【6月更文挑战第4天】对象参数校验是使用 SpringMVC 时常用的功能,这篇文章尝试分析了,Spring 是如何实现这一功能的。
24 5
|
5天前
|
安全 Java Spring
spring的controller是单例还是多例,怎么保证并发的安全
spring的controller是单例还是多例,怎么保证并发的安全
7 0
|
8天前
|
JSON 前端开发 Java
Spring MVC 级联对象参数校验
【6月更文挑战第6天】在 Spring MVC 的使用过程中,我们会发现很多非常符合直觉的功能特性,但往往我们会习惯这种「被照顾得很好」的开发方式,依靠直觉去判断很多功能特性的用法。
14 1
|
8天前
|
Java Spring 容器
Spring 中一个事务方法调用另一个事务方法会怎样?
【6月更文挑战第5天】如果我们在一个包含事务的方法中,调用了另一个包含里事务的方法,那么,Spring 会创建新的事物吗?如果方法抛出异常导致事务会滚了呢?
20 0
|
13天前
|
设计模式 Java 关系型数据库
Spring的配置文件,如何配置端口号,,properties,yml获取配置项等方法,外观模式及其优缺点,日志代表的信息
Spring的配置文件,如何配置端口号,,properties,yml获取配置项等方法,外观模式及其优缺点,日志代表的信息
|
13天前
|
Java Spring
面对Spring 不支持java8的改变方法
面对Spring 不支持java8的改变方法
|
1月前
|
设计模式 前端开发 JavaScript
Spring MVC(一)【什么是Spring MVC】
Spring MVC(一)【什么是Spring MVC】
|
1月前
|
Java Apache vr&ar
springmvc报错 nested exception is org.mybatis.spring.MyBatisSystemException:
springmvc报错 nested exception is org.mybatis.spring.MyBatisSystemException:
20 0
|
8月前
|
前端开发 Java Go
Spring MVC 和 Spring Boot 的区别
Spring MVC 和 Spring Boot 的区别
139 0
|
11月前
|
Java Spring
springmvc中spring提供的中文乱码解决问题
可以解决浏览器的乱码问题
52 0