在@RequestParam中将不可变集合清空为defaultValue

时间:2014-06-01 14:50:17

标签: spring spring-mvc

令人非常恼火的是,Spring并不接受defaultValue @RequestParam中的非常数值。我想为集合返回一个空的不可变集合。有没有漂亮的解决方法?

1 个答案:

答案 0 :(得分:0)

我会从这样的事情开始: 在DispatcherServlet的配置文件中,您需要注册自己的ArgumentResolver,如上所述:

<annotation-driven>
        <argument-resolvers>
            <beans:bean class="com.foo.bar.CustomListWebArgumentResolver" />
        </argument-resolvers>
    </annotation-driven>

正如我在评论中提到的,我最初无法看到处理参数的相反(正常)方式的方法。在我看来,下面的解决方案看起来并不太漂亮,但我相信它可能有用:

public class CustomListWebArgumentResolver implements HandlerMethodArgumentResolver {

@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;

@Override
public Object resolveArgument(MethodParameter parameter,
        ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
        WebDataBinderFactory binderFactory) throws Exception {
    ServletWebRequest servletWebRequest = (ServletWebRequest) webRequest;
    HttpServletRequest request = servletWebRequest.getRequest();

    String value = request.getParameter(parameter.getParameterName());
    if (value == null || value.isEmpty()) {
        return Collections.EMPTY_LIST;
    }

    RequestParamMethodArgumentResolver defaultResolver = null;
    for (Iterator iterator = requestMappingHandlerAdapter.getArgumentResolvers().iterator(); iterator.hasNext();) {
        HandlerMethodArgumentResolver type = (HandlerMethodArgumentResolver) iterator.next();
        if (type instanceof RequestParamMethodArgumentResolver) {
            defaultResolver = (RequestParamMethodArgumentResolver) type;
        }
    }

    if (defaultResolver != null) {
        return defaultResolver.resolveArgument(parameter, mavContainer, servletWebRequest, binderFactory);
    }

    return null;
}

@Override
public boolean supportsParameter(MethodParameter parameter) {
    return List.class.equals(parameter.getParameterType());
}
}

基本上,在你的自定义解析器中,你得到RequestMappingHandlerAdapter,它引用了Spring定义的所有默认参数解析器。你要找的是RequestParamMethodArgumentResolver。一旦获得它,如果参数的值不为null且不为空,则将作业传递给默认参数解析器。

上面,在supportsParameter方法中,我假设通用列表正在作为RequestParam处理:

public String home(@RequestParam(defaultValue = "") List myList, ...) {
...
}

此外,我认为您需要自定义配置才能在默认解析器之前考虑自定义解析器:

@Configuration
public class MyCustomWebConfiguration {
    private @Inject RequestMappingHandlerAdapter adapter;

    @PostConstruct
    public void prioritizeCustomArgumentMethodHandlers () {
      List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList(adapter.getArgumentResolvers ());
      List<HandlerMethodArgumentResolver> customResolvers = adapter.getCustomArgumentResolvers ();

      argumentResolvers.removeAll(customResolvers);
      argumentResolvers.addAll(0, customResolvers);
      adapter.setArgumentResolvers(argumentResolvers);
    }
}
相关问题