Html 不使用spring taglib对以下划线“开头的变量进行数据绑定_&引用;

Html 不使用spring taglib对以下划线“开头的变量进行数据绑定_&引用;,html,spring,data-binding,spring-mvc,Html,Spring,Data Binding,Spring Mvc,我的html是在不使用spring标记库的情况下构建的,现在我想将表单的参数绑定到控制器中的一个对象。 我在绑定以下划线“\u1”开头的属性时遇到问题 目前我的表单如下所示 <form method="post" action="${pageContext.request.contextPath}/test.form"> <input type="text" name="_NumeroPage" /> <input type="tex

我的html是在不使用spring标记库的情况下构建的,现在我想将表单的参数绑定到控制器中的一个对象。 我在绑定以下划线“\u1”开头的属性时遇到问题

目前我的表单如下所示

<form method="post" action="${pageContext.request.contextPath}/test.form">
          <input type="text" name="_NumeroPage" />
      <input type="text" name="_Tri" />
      <input type="text" name="_SensTri" />
      <input type="text" name="codePays" />
</form>
我的控制器是

@RequestMapping(value={"/test","/test.form"})
public String paginerSequencesSuiviMulticanal(TestForm formulaire, Model model, HttpSession session){

        model.addAttribute("_NumeroPage", formulaire.get_NumeroPage());
        model.addAttribute("_Tri", formulaire.get_Tri());
        model.addAttribute("_SensTri", formulaire.get_SensTri());
        model.addAttribute("codePays", formulaire.getCodePays());

    return "/result";
}
我该怎么装订呢。目前NumeroPage,Tri,SensTri没有绑定,但它绑定了codePays。
是否有办法绑定以下划线字符“”开头的属性?

您可能可以在Spring中深入研究bean属性访问器代码,并找出原因(在粗略检查代码或文档时找不到任何东西),但一个简单得多的解决方案似乎是,在数据绑定涉及的类和字段中,不使用带前导下划线的名称。

您可以尝试创建一个自定义子类,将以下划线开头的请求参数映射到不带下划线的字段。然后您必须创建一个定制的来创建的子类。接下来,您需要创建的自定义子类并向SpringMVC注册它。这将允许您继续在HTML中使用下划线,而无需在POJO字段名中使用下划线

自定义ServletRequestDataBinder:

public class MyCustomServletRequestDataBinder extends
  ExtendedServletRequestDataBinder {
  public MyCustomServletRequestDataBinder(Object target) {
    super(target);
  }

  public MyCustomServletRequestDataBinder(Object target, String objectName) {
    super(target, objectName);
  }

  @Override
  protected void addBindValues(MutablePropertyValues mpvs,
      ServletRequest request) {
    super.addBindValues(mpvs, request);

    addUnderscoreBindValues(mpvs, request);
  }

  protected void addUnderscoreBindValues(MutablePropertyValues mpvs,
      ServletRequest request) {
    // go through each parameter and check if it starts with an underscore (_)
    // if it starts with an underscore, add it to mpvs under the name without
    // the underscore
    @SuppressWarnings("unchecked")
    Map<String, Object> parameterMap = request.getParameterMap();
    for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
      if (StringUtils.startsWith(entry.getKey(), "_")) {
        mpvs.add(StringUtils.removeStart(entry.getKey(), "_"), entry.getValue());
      }
    }
  }
}

我很确定,在默认请求参数绑定期间,可能有一种更简单的方法来修改/添加附加值,但我记不起另一个钩子在哪里。

我想我知道答案。这是因为spring使用下划线绑定chekbox”复选框标记遵循现有的spring约定,即为每个复选框包含一个以下划线(“389;”)为前缀的隐藏参数。问题是我正在处理一个已迁移到spring的旧项目。并且有太多带有“”的变量“改变。在一个完美的世界里,我永远不会用“”来命名java中某个属性的开头^ ^ ^ ^我必须为此找到一个解决方法……您可能会花费更多的时间来尝试解决这个问题,而不仅仅是更改所有字段并获取/设置方法名称以符合约定,所以我会这么做。当然,这可能是一项枯燥的工作,但所有体面的IDE:s都有重构支持,因此您可以轻松地重命名方法和字段,IDE将自动重命名所有引用。最终,您将花费更少的时间,获得更好的代码。当你可以重构的时候,不要做丑陋的黑客。
public class MyCustomServletRequestDataBinder extends
  ExtendedServletRequestDataBinder {
  public MyCustomServletRequestDataBinder(Object target) {
    super(target);
  }

  public MyCustomServletRequestDataBinder(Object target, String objectName) {
    super(target, objectName);
  }

  @Override
  protected void addBindValues(MutablePropertyValues mpvs,
      ServletRequest request) {
    super.addBindValues(mpvs, request);

    addUnderscoreBindValues(mpvs, request);
  }

  protected void addUnderscoreBindValues(MutablePropertyValues mpvs,
      ServletRequest request) {
    // go through each parameter and check if it starts with an underscore (_)
    // if it starts with an underscore, add it to mpvs under the name without
    // the underscore
    @SuppressWarnings("unchecked")
    Map<String, Object> parameterMap = request.getParameterMap();
    for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
      if (StringUtils.startsWith(entry.getKey(), "_")) {
        mpvs.add(StringUtils.removeStart(entry.getKey(), "_"), entry.getValue());
      }
    }
  }
}
public class MyCustomServletRequestDataBinderFactory extends
    ServletRequestDataBinderFactory {
  /**
   * Create a new instance.
   * @param binderMethods one or more {@code @InitBinder} methods
   * @param initializer provides global data binder initialization
   */
  public MyCustomServletRequestDataBinderFactory(
      List<InvocableHandlerMethod> binderMethods,
      WebBindingInitializer initializer) {
    super(binderMethods, initializer);
  }

  /**
   * Returns an instance of {@link MyCustomServletRequestDataBinder}.
   */
  @Override
  protected ServletRequestDataBinder createBinderInstance(Object target,
      String objectName, NativeWebRequest request) {
    return new MyCustomServletRequestDataBinder(target, objectName);
  }
}
public class MyCustomRequestMappingHandlerAdapter extends
    RequestMappingHandlerAdapter {
  public MyCustomRequestMappingHandlerAdapter() {
    super();
  }

  /**
   * {@inheritDoc} Creates an instance of
   * {@link MyCustomServletRequestDataBinderFactory}.
   */
  @Override
  protected ServletRequestDataBinderFactory createDataBinderFactory(
      List<InvocableHandlerMethod> binderMethods) throws Exception {
    return new MyCustomServletRequestDataBinderFactory(binderMethods,
        getWebBindingInitializer());
  }
}
@Configuration
@Import(ValidationConfiguration.class)
@ComponentScan(basePackageClasses = ControllerScanMarker.class)
public class MyCustomHandlerConfig extends WebMvcConfigurationSupport {
  /**
   * {@inheritDoc} Returns the subclass
   * {@link MyCustomRequestMappingHandlerAdapter} in place of the default
   * {@link RequestMappingHandlerAdapter}.
   */
  @Override
  @Bean
  public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
    ...
    RequestMappingHandlerAdapter adapter = new MyCustomRequestMappingHandlerAdapter();

    // set additional adapter fields here...
    ...
    return adapter;
  }
}