【问题标题】:Convert request params to generic class将请求参数转换为泛型类
【发布时间】:2013-12-07 14:51:08
【问题描述】:

我正在寻找有关 Spring Controller 定义的帮助。我尝试了几次谷歌,但没有找到如何实现我的目标的直接解释。

我想定义通用控制器:

public abstract class AbstractController<E extends AbstractEntity, 
                                         P extends IRequestParams> {
  @RequestMapping(method = GET)
  public @ResponseBody
  abstract List<E> list(@RequestParam P params);
}

之后我会声明如下控制器:

public class CatController 
          extends AbstractController<Cat, ICatSearchParams> {
  @RequestMapping(method = GET)
  public @ResponseBody
  List<Cat> list(@RequestParam ICatSearchParams params) {
    // do something and return list of results
  }
}

我有以通用方式将@RequestParam Map&lt;String, String[]&gt; params 转换为IRequestParams 的服务。我可以通过 Spring 解析泛型类型。

但我不知道如何插入 Spring 以自动将请求参数转换为我的参数接口并在方法调用中使用它。我希望这种转换在配置后对开发人员是透明的。

提前感谢您的帮助!

【问题讨论】:

  • 我不确定完整的构造最终是否会起作用,因为我不知道spring ConverterWebArgrumentResolver 是否可以正确解析泛型类型。

标签: java spring generics spring-mvc


【解决方案1】:

您可以实现HandlerMethodArgumentResolver,但您需要自己实现完整的对象映射。

注册很简单:

<mvc:annotation-driven>
      <mvc:argument-resolvers>
           <bean class="YourMethodArgumentResolver"/>         
      </mvc:argument-resolvers>
 </mvc:annotation-driven>

另一种方法是实现自定义Converter。主要问题是,转换器只能转换一个字符串/请求属性。但是,如果您的 IRequestParams 在 http-request 中有多个值,这将不起作用。 - 另一方面,如果您的转换器旨在通过其 ID 加载实体,那么 Converter 是要走的路。

如果您想构建一种自动注册转换器的方法,请查看此答案 https://stackoverflow.com/a/13778502/280244

【讨论】:

    【解决方案2】:

    我已经完成了问题的目标。 @Ralph's 的回答非常非常很有帮助,但确切地说,我会写出更多需要的内容。

    我创建了@987654321@,将其命名为CustomHandlerMethodArgumentResolver。要将所有请求参数映射到结果对象,我必须将控制器方法的参数标记为@RequestBody

    这还不够,因为 Spring 的默认 HandlerMethodArgumentResolvers 尝试先映射它,而我的解析器没有执行。但是this 回答指出了如何为我的解析器设置优先级。

    @PostConstruct 不起作用(不知道为什么),所以我修改了我的 @Configuration 类以实现 ApplicationListener&lt;ContextRefreshedEvent&gt;。代码如下:

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
      RequestMappingHandlerAdapter adapter = 
          event.getApplicationContext().getBean(
              RequestMappingHandlerAdapter.class);
      CustomHandlerMethodArgumentResolver resolver =
          event.getApplicationContext().getBean(
              CustomHandlerMethodArgumentResolver.class);
    
      List<HandlerMethodArgumentResolver> argumentResolvers = 
          new ArrayList<>(
              adapter.getArgumentResolvers().getResolvers());
      List<HandlerMethodArgumentResolver> customResolvers = 
          adapter.getCustomArgumentResolvers();
      argumentResolvers.remove(resolver);
      argumentResolvers.add(0, resolver);
      adapter.setArgumentResolvers(argumentResolvers);
    }
    

    当然CustomHandlerMethodArgumentResolver.supportsParameter(MethodParameter)会检查实际情况是否应该以自定义或默认方式处理 - 这取决于要求。

    感谢@Ralph 闪电般的快速帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      相关资源
      最近更新 更多