请求参数的自定义 Spring 注解

问题描述 投票:0回答:2

我想编写自定义注释,根据注释修改Spring请求或路径参数。例如,代替此代码:

@RequestMapping(method = RequestMethod.GET)
public String test(@RequestParam("title") String text) {
   text = text.toUpperCase();
   System.out.println(text);
   return "form";
}

我可以做注释@UpperCase :

@RequestMapping(method = RequestMethod.GET)
   public String test(@RequestParam("title") @UpperCase String text) {
   System.out.println(text);
   return "form";
}

有可能吗?如果可以,我该怎么做?

java spring spring-mvc spring-annotations request-mapping
2个回答
50
投票

正如人们在评论中所说,您可以轻松编写注释驱动的自定义解析器。简单四步,

  1. 创建注释,例如

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UpperCase {
    String value();
}
  1. 编写一个解析器,例如

public class UpperCaseResolver implements HandlerMethodArgumentResolver {

    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterAnnotation(UpperCase.class) != null;
    }

    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
            WebDataBinderFactory binderFactory) throws Exception {
        UpperCase attr = parameter.getParameterAnnotation(UpperCase.class);
        return webRequest.getParameter(attr.value()).toUpperCase();
    }
}
  1. 注册解析器

<mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="your.package.UpperCaseResolver"></bean>
        </mvc:argument-resolvers>
</mvc:annotation-driven>

或者java配置

    @Configuration
    @EnableWebMvc
    public class Config extends WebMvcConfigurerAdapter {
    ...
      @Override
      public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
          argumentResolvers.add(new UpperCaseResolver());
      }
    ...
    }
  1. 在控制器方法中使用注释,例如

public String test(@UpperCase("foo") String foo) 

0
投票

下面是使用Spring AOP的实现。好处是不需要在注解中指定请求参数,可以用于任何方法。

  1. UpperCase
    注释用于标记需要转换为大写的参数。
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UpperCase {
}
  1. UpperCaseAspect
    类用于拦截方法调用并将参数转换为大写。
@Aspect
@Component
public class UpperCaseAspect {

    // Match any method has at least one argument annotated with `@UpperCase`.
    @Around("execution(* *(.., @UpperCase (*), ..))")
    public Object convertToUpperCase(ProceedingJoinPoint joinPoint) throws Throwable {
                Object[] args = joinPoint.getArgs();

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Parameter[] parameters = method.getParameters();

        // Find the argument annotated with `@UpperCase`, and replace it with the value of the current user.
        for (int i = 0; i < parameters.length; i++) {
            Parameter parameter = parameters[i];
            Me me = parameter.getAnnotation(Me.class);
            if (me != null) {
                String value = me.value();
                args[i] = userSession.get(value);
            }
        }

        return joinPoint.proceed(args);
    }
}

@Around
表达式用于匹配任何 1..N 个带注释的参数,无论它们在方法签名中的位置如何。 (归功于https://stackoverflow.com/a/52889642/2457861

  1. 在控制器方法中使用注释,例如
@RequestMapping(method = RequestMethod.GET)
public String test(@RequestParam("title") @UpperCase String text) {
   System.out.println(text);
   return "form";
}

public String upperCase(@UpperCase String text) {
    return text;
}
© www.soinside.com 2019 - 2024. All rights reserved.