从弹簧形式中删除参数

时间:2019-03-25 10:21:38

标签: spring-mvc spring-form spring-mvc-initbinders

我有一个使用表格的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中删除过滤器?

0 个答案:

没有答案