private ModelAndView getModelAndViewSettingsPage(
      Map<String, String> parameters, SettingsForm settingsForm, MockHttpServletRequest request) {
    if (settingsForm == null) {
      settingsForm = new SettingsForm();
    }

    WebDataBinder binder = new WebDataBinder(settingsForm, "settingsform");

    if (parameters != null) {
      request.setParameters(parameters);
      binder.bind(new MutablePropertyValues(request.getParameterMap()));
    }

    SessionStatus status = new SimpleSessionStatus();
    return controller.submitSettingsPage(settingsForm, binder.getBindingResult(), status, request);
  }
 /**
  * {@inheritDoc}
  *
  * <p>Downcast {@link org.springframework.web.bind.WebDataBinder} to {@link
  * org.springframework.web.bind.ServletRequestDataBinder} before binding.
  *
  * @throws Exception
  * @see org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory
  */
 protected void bindRequestParameters(
     ModelAndViewContainer mavContainer,
     WebDataBinderFactory binderFactory,
     WebDataBinder binder,
     NativeWebRequest request,
     MethodParameter parameter)
     throws Exception {
   Map<String, Boolean> hasProcessedPrefixMap = new HashMap<String, Boolean>();
   Class<?> targetType = binder.getTarget().getClass();
   ServletRequest servletRequest = prepareServletRequest(binder.getTarget(), request, parameter);
   WebDataBinder simpleBinder = binderFactory.createBinder(request, null, null);
   if (Collection.class.isAssignableFrom(targetType)) { // bind collection or array
     Type type = parameter.getGenericParameterType();
     Class<?> componentType = Object.class;
     Collection target = (Collection) binder.getTarget();
     List targetList = new ArrayList(target);
     if (type instanceof ParameterizedType) {
       componentType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
     }
     if (parameter.getParameterType().isArray()) {
       componentType = parameter.getParameterType().getComponentType();
     }
     for (Object key : servletRequest.getParameterMap().keySet()) {
       String prefixName = getPrefixName((String) key);
       // 每个prefix 只处理一次
       if (hasProcessedPrefixMap.containsKey(prefixName)) {
         continue;
       } else {
         hasProcessedPrefixMap.put(prefixName, Boolean.TRUE);
       }
       if (isSimpleComponent(prefixName)) { // bind simple type
         Map<String, Object> paramValues =
             WebUtils.getParametersStartingWith(servletRequest, prefixName);
         Matcher matcher = INDEX_PATTERN.matcher(prefixName);
         if (!matcher.matches()) { // 处理如 array=1&array=2的情况
           for (Object value : paramValues.values()) {
             targetList.add(simpleBinder.convertIfNecessary(value, componentType));
           }
         } else { // 处理如 array[0]=1&array[1]=2的情况
           int index = Integer.valueOf(matcher.group(1));
           if (targetList.size() <= index) {
             growCollectionIfNecessary(targetList, index);
           }
           targetList.set(
               index, simpleBinder.convertIfNecessary(paramValues.values(), componentType));
         }
       } else { // 处理如
         // votes[1].title=votes[1].title&votes[0].title=votes[0].title&votes[0].id=0&votes[1].id=1
         Object component = null;
         // 先查找老的 即已经在集合中的数据(而不是新添加一个)
         Matcher matcher = INDEX_PATTERN.matcher(prefixName);
         if (!matcher.matches()) {
           throw new IllegalArgumentException(
               "bind collection error, need integer index, key:" + key);
         }
         int index = Integer.valueOf(matcher.group(1));
         if (targetList.size() <= index) {
           growCollectionIfNecessary(targetList, index);
         }
         Iterator iterator = targetList.iterator();
         for (int i = 0; i < index; i++) {
           iterator.next();
         }
         component = iterator.next();
         if (component == null) {
           component = BeanUtils.instantiate(componentType);
         }
         WebDataBinder componentBinder = binderFactory.createBinder(request, component, null);
         component = componentBinder.getTarget();
         if (component != null) {
           ServletRequestParameterPropertyValues pvs =
               new ServletRequestParameterPropertyValues(servletRequest, prefixName, "");
           componentBinder.bind(pvs);
           validateIfApplicable(componentBinder, parameter);
           if (componentBinder.getBindingResult().hasErrors()) {
             if (isBindExceptionRequired(componentBinder, parameter)) {
               throw new BindException(componentBinder.getBindingResult());
             }
           }
           targetList.set(index, component);
         }
       }
       target.clear();
       target.addAll(targetList);
     }
   } else if (MapWapper.class.isAssignableFrom(targetType)) {
     Type type = parameter.getGenericParameterType();
     Class<?> keyType = Object.class;
     Class<?> valueType = Object.class;
     if (type instanceof ParameterizedType) {
       keyType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
       valueType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[1];
     }
     MapWapper mapWapper = ((MapWapper) binder.getTarget());
     Map target = mapWapper.getInnerMap();
     if (target == null) {
       target = new HashMap();
       mapWapper.setInnerMap(target);
     }
     for (Object key : servletRequest.getParameterMap().keySet()) {
       String prefixName = getPrefixName((String) key);
       // 每个prefix 只处理一次
       if (hasProcessedPrefixMap.containsKey(prefixName)) {
         continue;
       } else {
         hasProcessedPrefixMap.put(prefixName, Boolean.TRUE);
       }
       Object keyValue = simpleBinder.convertIfNecessary(getMapKey(prefixName), keyType);
       if (isSimpleComponent(prefixName)) { // bind simple type
         Map<String, Object> paramValues =
             WebUtils.getParametersStartingWith(servletRequest, prefixName);
         for (Object value : paramValues.values()) {
           target.put(keyValue, simpleBinder.convertIfNecessary(value, valueType));
         }
       } else {
         Object component = target.get(keyValue);
         if (component == null) {
           component = BeanUtils.instantiate(valueType);
         }
         WebDataBinder componentBinder = binderFactory.createBinder(request, component, null);
         component = componentBinder.getTarget();
         if (component != null) {
           ServletRequestParameterPropertyValues pvs =
               new ServletRequestParameterPropertyValues(servletRequest, prefixName, "");
           componentBinder.bind(pvs);
           validateComponent(componentBinder, parameter);
           target.put(keyValue, component);
         }
       }
     }
   } else { // bind model
     ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
     servletBinder.bind(servletRequest);
   }
 }