我有一个使用表格的Spring MVC应用程序。该表格包含可以添加或删除的动态过滤器列表。我的表单对象看起来像这样:
public class RequestForm {
@Valid
List<Filter> filters = new LinkedList<>();
}
Filter
是基类,并具有其他子类,以允许自定义验证值:
public class Filter {
String type;
String value;
boolean ignoreFilter;
}
public IntFilter extends Filter {
@ValueIsInteger
String getValue() {...}
}
public DateFilter extends Filter {
@ValueIsDate
String getValue() {...}
}
在我的控制器中,我正在使用@InitBinder
根据Filter
属性将type
对象转换为正确的子类,并忽略基于另一个属性的过滤器。代码如下:
@InitBinder
public void initBinder(WebDataBinder webDataBinder, HttpServletRequest httpServletRequest) {
// Filter out all request when we have nothing to do
Object nonCastedTarget = webDataBinder.getTarget();
// TODO: Better cache this in static final field instead
Pattern pattern = Pattern.compile("filters\\[(\\d+)]\\.filterType");
Map<Integer, String> types = new HashMap<>();
Enumeration<String> parameterNames = httpServletRequest.getParameterNames();
while (parameterNames.hasMoreElements()) {
String element = parameterNames.nextElement();
Matcher matcher = pattern.matcher(element);
if (!matcher.matches()) {
continue;
}
types.put(
Integer.parseInt(matcher.group(1)),
httpServletRequest.getParameter(element)
);
}
RequestForm target = (RequestForm) nonCastedTarget;
types.keySet().stream().sorted().forEach(key -> {
//remove disabled filter if("false".equals(httpServletRequest.getParameter("filters["+key+"].ignoreFilter"))) {
switch (types.get(key)) {
case "int":
target.getFilters().add(new IntFilter(httpServletRequest.getParameter("filters["+key+"].value")));
break;
case "date":
target.getFilters().add(new DateFilter(httpServletRequest.getParameter("filters["+key+"].value")));
break;
default:
throw new IllegalStateException("Unknown type: " + types.get(key));
}
}
});
}
在控制器中:
public ModelAndView postPage(@Valid @ModelAttribute("requestForm") RequestForm requestForm, BindingResult bindingResult, Locale locale) {
ModelAndView mav;
// errors in the selection
if (bindingResult.hasErrors()) {
mav = new ModelAndView("requestmanagement/view");
addRequestFormParameters(mav, requestForm, locale);
return mav;
}
...
}
我的问题:
子过滤器的转换和验证有效。但是,仍将忽略的过滤器添加到控制器中的RequestForm中。如果我的表单包含IntFilter
,应将其忽略,则控制器中的我的RequestForm仍包含过滤器,但不会强制转换为子类型。
谁可以从RequestForm中删除过滤器?