令人非常恼火的是,Spring并不接受defaultValue
@RequestParam
中的非常数值。我想为集合返回一个空的不可变集合。有没有漂亮的解决方法?
答案 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);
}
}