【问题标题】:Spring Controller: Custom annotation with combined Spring annotations does not workSpring Controller:带有组合 Spring 注释的自定义注释不起作用
【发布时间】:2015-12-08 14:37:53
【问题描述】:

我有正常工作的 Spring Controller,其中我有一个按以下方式映射的方法

@RequestMapping(
    value = "/users"
    consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
    produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
    method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public UserResponse retrieveUsers() {
    return new UserResponse();
}

@RequestMapping(
    value = "/contracts"
    consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
    produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
    method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public ContractResponse retrieveContracts() {
    return new ContractResponse();
}

这很好用,GET 请求被视为已接受,例如POST 我收到正确的405 状态代码。

现在我想介绍自定义组合注解,而不是在每个方法中都有相同的注解。

我的自定义注释看起来像,

@RequestMapping(
        consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
        produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
        method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Get {}

因此,我将方法更改为

@Get
@RequestMapping(value = "/users")
public UserResponse retrieveUsers() {
    return new UserResponse();
}

在这种情况下,我可以看到我发送给/users 的任何类型的请求都得到了正确的处理。例如,即使我做POST,我也会看到响应。所以@RequestMapping 不能正常工作。

我在这里做错了什么?是否可以使用自定义组合注释使控制器正常运行?

【问题讨论】:

  • 你为什么认为你的 @Get 会这样工作?
  • 为什么不呢?实际上它正在工作,但不正确。例如,至少它会正确返回状态代码。我假设当我输入@RequestMapping(value = "/users") 时,它实际上覆盖了我的自定义注释中的映射,因为@Get 中的另一个注释实际上正在工作。
  • 您是否尝试将@RequestMapping 与一个注解结合起来,看看是否能解决问题?
  • 为什么不让您的@Get 注释接受value 并为您的value 使用@RequestMapping,这样您就不必将它们分开。

标签: java spring spring-mvc annotations


【解决方案1】:

我怀疑UserResponse#retrieveUsers 上的@RequestMapping(value = "/users") 替换了@Get 接口上的@RequestMapping。

看看这是否有效:

@RequestMapping(
        consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
        produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
        method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Get {

    @AliasFor(annotation = RequestMapping.class, attribute = "value")
    String[] value() default {};
}

@Get(value = "/users")
public UserResponse retrieveUsers() {
    return new UserResponse();
}

您可能对spring-composed 项目中的GetJson 感兴趣。

请注意,@AliasFor 仅在 Spring 4.2 中发布。它在早期版本中不可用。

【讨论】:

    【解决方案2】:

    您覆盖了您在@Get 注释中设置的@RequestMapping 注释。因此它只指定了请求映射的value 部分,而将所有其他属性保留为默认值。

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 1970-01-01
      • 2021-12-25
      • 2013-05-18
      • 2014-08-14
      • 2017-08-08
      • 2015-10-26
      • 2016-06-02
      • 1970-01-01
      相关资源
      最近更新 更多