我有一个带有基本请求映射的Spring 3.2控制器,如
@RequestMapping("/action")
public String action(@RequestParam("param") String param) {
//do stuff...
return "view";
}
此控制器处理由非技术业务用户创建的链接。有时用户会搞砸它并创建具有重复参数的链接,例如
www.example.com/action?param=value¶m=value
参数完全相同,可能是复制/粘贴错误。
我的问题是Spring将这些欺骗连接在一起,所以当我只需要"value,value"
时,上面的url会为param
提供"value"
。
检测和处理这些重复项的好方法是什么?我知道我可以将@RequestParam
的所有内容更改为List<String>
并从那里开始,但是&# 39;在几十个请求映射上有很多样板。
理想情况下,有一种方法可以在Spring尝试绑定它们之前拦截和修改url参数 - 但仅限于此控制器。
答案 0 :(得分:1)
一个好主意是用您自己的策略扩展AbstractNamedValueMethodArgumentResolver
。然后可以在您认为必要的地方使用该策略。
此策略仅适用于Spring 3.1+,因为您使用的是Spring 3.2
,这对您来说不是问题答案 1 :(得分:1)
我发现我可以注册一个自定义字符串属性编辑器来执行此操作。
class DuplicateParameterReducingPropertyEditor extends PropertyEditorSupport {
Object value;
@Override
public void setValue(Object value) {
if (value instanceof String[]) {
String[] strings = (String[])value;
Set<String> unique = Sets.newHashSet(strings);
this.value = unique.toArray();
} else {
this.value = value;
}
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
this.value = text;
}
@Override
public String getAsText() {
return value.toString();
}
@Override
public Object getValue() {
return value;
}
};
我把它添加到我的控制器:
@InitBinder
public void initBinder(WebDataBinder binder) {
PropertyEditor stringEditor = new DuplicateParameterReducingPropertyEditor();
binder.registerCustomEditor(String.class, stringEditor);
}
因此,只要Spring遇到@RequestParam
- 带注释的String方法参数,就会调用PropertyEditor
来转换传入的数据(如果需要)。在重复参数的情况下,Spring将String[]
值传递给属性编辑器setValue
,然后我可以对其进行操作。
这确实有我想要的结果。不过,我不确定这一点的影响,所以我不能认为它是一个很好的解决方案。不必更改任何处理程序方法签名是一个很大的优点。
答案 2 :(得分:0)
我在Spring Boot中遇到了同样的问题。最终,我想出了使用转换器的这种解决方案,以防它对任何人都有帮助。
此方法应作为WebMvcConfigurer类的一部分添加。
@Override
public void addFormatters(FormatterRegistry registry) {
// Duplicate query parameters converter
registry.addConverter(new Converter<String[], String>() {
public String convert(String[] arr) {
return arr[arr.length - 1]; // Return the last value
}
});
}