将请求参数转换为泛型类

时间:2013-11-22 16:26:03

标签: java spring generics spring-mvc

我正在寻找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<String, String[]> params转换为IRequestParams。我可以通过Spring解析泛型类型。

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

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

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

注册很简单:

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

另一种方法是实现自定义Converter。主要问题是,转换器只能转换一个String / Request属性。但是,如果您的IRequestParams在具有多个值的http请求中,则无效。 - 另一方面,如果您的转换器旨在通过其ID加载实体,则可以使用Converter

如果你想建立一种自动注册转换器的方法,那么看看这个答案 https://stackoverflow.com/a/13778502/280244

答案 1 :(得分:1)

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

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

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

@PostConstruct无效(不是为什么不起作用),因此我修改了@Configuration课程来实施ApplicationListener<ContextRefreshedEvent>。这是代码:

@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提供快速帮助!