2013-11-22 171 views
1

我正在寻找Spring控制器定义的帮助。我试图谷歌几次,但没有找到直接的解释如何实现我的目标。将请求转换为泛型类

我想定义通用控制器:

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[]> paramsIRequestParams一个通用的方法。我能够通过Spring来解析泛型类型。

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

非常感谢您的帮助!

+0

我不确定完整的构造是否会在最后工作,因为我不知道Spring的'Converter'或'WebArgrumentResolver'是否可以正确解析泛型类型。 – Ralph

回答

1

你可以实现一个HandlerMethodArgumentResolver但你需要通过你自己实现完整的对象映射。

注册非常容易:

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

另一种方式将实现自定义Converter。主要的问题是,一个Converter只能转换一个String/Request属性。但是,如果您的IRequestParams在具有多个值的http请求中,则不起作用。 - 另一方面,如果您的Converter设计为通过其ID来加载实体,那么Converter就是要走的路。

如果你想自动建立的方式注册,然后转换来看看这个答案 https://stackoverflow.com/a/13778502/280244

1

我acomplished问题的目标。 @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闪电般的帮助!