1

嗨,我到处寻找,但找不到解决方案。我在 Jquery 函数中进行 ajax 调用并从 spring 输入表单提交数据:输入到控制器。控制器正在通过 JSR 303 Hibernate Validation 验证日期,并通过 JSON 将错误返回到相同的 Jquery 函数(通过 Json 接收数据)并在 jsp 中显示错误。一切正常,但显示的错误消息只是默认的或来自验证注释的消息参数。我想从 ValidationMessages.properties 文件中获取错误消息,并且该文件包含准备好的消息,但显示消息是默认的,而不是来自 ValidationMessages.properties。我没有使用 form:error 标签,因为我想显示 Json 收到的错误。问题是错误消息不是来自文件而是默认显示。

我将补充一点,在进行正常的 JSR 303 验证(没有 Ajax 和 Json)时,通过 form:error 标签显示错误消息,一切正常,消息来自 ValidationMessages.properties 文件。

我的 .jsp 页面

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
     <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Add Users using ajax</title>
         <script src="<%=request.getContextPath() %>/js/jquery.js"></script>
         <script type="text/javascript">
           var contexPath = "<%=request.getContextPath() %>";
         </script>
         <script src="<%=request.getContextPath() %>/js/user.js"></script>
          <link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/style/app.css">
     </head>

       <body>
          <h1>Add Users using Ajax ........</h1>
           <form:form method="post"  modelAttribute="user">
           <table>
                <tr><td colspan="2"><div id="error" class="error"></div></td></tr> 
                   <tr><td>Name:</td> <td><form:input path="name" /></td> 
                <tr><td>Education</td> <td><form:input path="education" /></td> 

                <tr><td colspan="2"><input type="button" value="Add Users" onclick="doAjaxPost()"><br/></td></tr>

                <tr><td colspan="2"><div id="info" class="success"></div></td></tr>
          </table>

  </form:form>

</body>
</html>

我在 user.js 中的 doAjaxPost 函数

      function doAjaxPost() {  
  // get the form values  
  var name = $('#name').val();
  var education = $('#education').val();

  $.ajax({  
    type: "POST",  
    url: contexPath + "/AddUser.htm",  
    data: "name=" + name + "&education=" + education,  
    success: function(response){
      // we have the response 
      if(response.status == "SUCCESS"){
          userInfo = "<ol>";
          for(i =0 ; i < response.result.length ; i++){
              userInfo += "<br><li><b>Name</b> : " + response.result[i].name + 
              ";<b> Education</b> : " + response.result[i].education;
          }
          userInfo += "</ol>";
          $('#info').html("User has been added to the list successfully. " + userInfo);
          $('#name').val('');
          $('#education').val('');
          $('#error').hide('slow');
          $('#info').show('slow');
      }else{

          errorInfo = "";
          for(i =0 ; i < response.result.length ; i++){

              errorInfo += "<br>" + (i + 1) +". " + response.result[i].defaultMessage;

          }
          $('#error').html("Please correct following errors: " + errorInfo);

          $('#info').hide('slow');
          $('#error').show('slow');

      }       
    },  
    error: function(e){  
      alert('Error: ' + e);  
    }  
  });  
}  

这是一个控制器

  package com.raistudies.controllers;

  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;

   import javax.validation.Valid;
   import org.springframework.stereotype.Controller;
   import org.springframework.validation.BindingResult;
   import org.springframework.web.bind.annotation.ModelAttribute;
   import org.springframework.web.bind.annotation.RequestMapping;
   import org.springframework.web.bind.annotation.RequestMethod;
   import org.springframework.web.bind.annotation.ResponseBody;

   import com.raistudies.domain.JsonResponse;
   import com.raistudies.domain.User;

  @Controller
  public class UserController {
private List<User> userList = new ArrayList<User>(); 

@RequestMapping(value="/AddUser.htm",method=RequestMethod.GET)
public String showForm(Map model){
    User user = new User();
    model.put("user", user);
    return "AddUser";
}


@RequestMapping(value="/AddUser.htm",method=RequestMethod.POST)
public @ResponseBody JsonResponse addUser(@ModelAttribute(value="user") @Valid User user, BindingResult result ){
    JsonResponse res = new JsonResponse();

    if(!result.hasErrors()){
        userList.add(user);
        res.setStatus("SUCCESS");
        res.setResult(userList);

    }else{
        res.setStatus("FAIL");
        res.setResult(result.getAllErrors());

    }

    return res;
}

  }

用户类

 package com.raistudies.domain;

 import org.hibernate.validator.constraints.NotEmpty;

 import javax.validation.constraints.Size;

 public class User {

@NotEmpty
private String name = null;

@NotEmpty
@Size(min=6, max=20)
private String education = null;


public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getEducation() {
    return education;
}
public void setEducation(String education) {
    this.education = education;
}

  }

这是 ValidationMessage.properties 文件

  NotEmpty.user.name=Name of user cant be empty
  NotEmpty.user.education = User education cant be empty
  Size.education=education must hava between 6 and 20 digits

这是 app-config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<!-- Application Message Bundle -->
   <bean id="messageSource"    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="/WEB-INF/ValidationMessages" />
</bean>


<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="com.raistudies" />

<!-- Configures the @Controller programming model -->
<mvc:annotation-driven/>



<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>



   </beans>

这是一个截图 https://www.dropbox.com/s/1xsmupm1cgtv4x7/image.png?v=0mcns

如您所见,显示的默认错误消息不是来自 ValidationMessages.properties 文件。如何解决?

4

2 回答 2

1

我知道这是一个非常古老的问题,但我一直在尝试解决这个问题。由于我刚刚找到了解决此问题的工作,因此我想分享它以帮助其他可能坚持同一件事的人。

请注意,我正在使用java config执行此操作,因此我使用注释。

首先,在控制器上,向环境添加一个自动连接的链接。这是为了能够读取属性文件:

@Autowired
private Environment environment;

OP 已经通过 XML 定义了 messageSource,但在 java config 中它将位于扩展的配置类上WebMvcConfigurerAdapter。就我而言,它适用于:

@Bean
public MessageSource messageSource() {
   ResourceBundleMessageSource msg= new ResourceBundleMessageSource();
   msg.setUseCodeAsDefaultMessage(true);
   msg.setBasename("PATH_TO_YOUR_MESSAGE_FILE");
   msg.setDefaultEncoding("UTF-8");
   return msg;
}

确保将该部分替换为文件的路径。无论如何,现在要解决这个问题。回到控制器上,替换这一行:

res.setResult(result.getAllErrors());

为此,并调用一个新函数:

createErrorMessages(result.getFieldErrors());

现在,这是转换消息的新方法:

private LinkedList<CustomErrorMsg> createErrorMessages(List<FieldError> originalErrors) {
    // Create a new list of error message to be returned
    LinkedList<CustomErrorMsg> newErrors = new LinkedList<>();

    // Iterate through the original errors
    for(FieldError fe: originalErrors) {
        // If the codes are null, then put the default message,
        // if not, then get the first code from the property file.
        String msg = (fe.getCodes() == null) ? fe.getDefaultMessage()
                : environment.getProperty(fe.getCodes()[0]);

        // Create the new error and add it to the list
        newErrors.add(new CustomErrorMsg(fe.getField(), msg));
    }

    // Return the message
    return newErrors;
}

if 部分使其适用于没有代码的情况,也适用于在控制器上执行业务逻辑验证检查并手动添加新字段错误的情况。

此解决方法不适用于海关消息中的参数。另一方面,如果您碰巧有其他页面使用休眠验证但不需要 AJAX 回调,则不需要使用此策略。那些只是默认工作。

我很清楚这根本不优雅,它可能会添加比预期更多的代码,但正如我之前所说,这是一种“解决方法”。

于 2016-10-18T14:14:15.210 回答
0

你可以试试这个:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="messageInterpolator" ref="messageSource"/>
</bean>

<mvc:annotation-driven validator="validator"/> 

这个想法是明确告诉验证器使用哪个消息源。我自己没有尝试过,但可能值得一试。

于 2013-05-21T09:31:35.543 回答