2016-02-27 2 views
1

Я разрабатываю пример интеграции Spring MVC + Hibernate Validator, беря ссылку от https://spring.io/guides/gs/validating-form-input/. Я добавил некоторые сообщения, которые будут решены из файла messages.properties, но ни одно из сообщений не будет устранено и не будет рассмотрено ниже. Пожалуйста, объясните, почему приложение не распознает файл messages.properties. Я ожидал получить фактическое сообщение из файла .properties, но почему это происходит [{length.validation.country}]?Невозможно разрешить пользовательские сообщения проверки в Hibernate + Spring

org.springframework.validation.BeanPropertyBindingResult: 1 errors 
Field error in object 'person' on field 'country': rejected value [U]; 
codes [Length.person.country,Length.country,Length.java.lang.String,Length]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes 
[person.country,country]; arguments []; default message [country],50,2]; default message [{length.validation.country}] 

Person.java

@Entity 
@Table(name="PERSON") 
public class Person { 

    @Id 
    @Column(name="id") 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    @SafeHtml(whitelistType=WhiteListType.NONE, message="{html.validation.firstname}") 
    @Length(max=Constant.MAX_FIRSTNAME,min=Constant.MIN_FIRSTNAME,message="{length.validation.firstname}") 
    @Column(name="FIRST_NAME") 
    private String firstname; 

    @SafeHtml(whitelistType=WhiteListType.NONE, message="{html.validation.lastname}") 
    @Length(max=Constant.MAX_LASTNAME,min=Constant.MIN_LASTTNAME,message="{length.validation.lastname}") 
    @Column(name="LAST_NAME") 
    private String lastname; 

    @SafeHtml(whitelistType=WhiteListType.NONE, message="{html.validation.country}") 
    @Length(max=Constant.MAX_COUNTRY,min=Constant.MIN_COUNTRY,message="{length.validation.country}") 
    @Column(name="COUNTRY") 
    private String country; 

    @SafeHtml(whitelistType = SafeHtml.WhiteListType.NONE, message = "{html.validation.emailId}") 
    @Length(max=Constant.MAX_EMAILID,min=Constant.MIN_EMAILID, message = "{length.validation.emailId}") 
    @Pattern(regexp = "^(.+)@(.+)$") 
    @Column(name="EMAIL_ID") 
    private String emailId; 
     // setters and getters 
} 

PersonController.java

@Controller 
public class PersonController { 

    private PersonService personService; 

    public PersonController(){} 

    public PersonController(PersonService personService){ 
     this.personService = personService; 
    } 

    @Autowired(required=true) 
    @Qualifier(value="personService") 
    public void setPersonService(PersonService ps){ 
     this.personService = ps; 
    } 

    @RequestMapping(value = "/persons", method = RequestMethod.GET) 
    public String listPersons(Model model) { 
     model.addAttribute("person", new Person()); 
     model.addAttribute("listPersons", this.personService.listPersons()); 
     return "person"; 
    } 

    //For add and update person both 
    @RequestMapping(value= "/person/add", method = RequestMethod.POST) 
    public String addPerson(@Valid @ModelAttribute("person") Person p, BindingResult bindingResult){ 

     if(bindingResult.hasErrors()){ 
      System.out.println(bindingResult); 
      return "redirect:/persons"; 
     } 

     if(p.getId() == 0){ 
      //new person, add it 
      this.personService.addPerson(p); 
     }else{ 
      //existing person, call update 
      this.personService.updatePerson(p); 
     } 

     return "redirect:/persons"; 

    } 

    @RequestMapping("/remove/{id}") 
    public String removePerson(@PathVariable("id") int id){ 
     this.personService.removePerson(id); 
     return "redirect:/persons"; 
    } 

    @RequestMapping("/edit/{id}") 
    public String editPerson(@PathVariable("id") int id, Model model){ 
     model.addAttribute("person", this.personService.getPersonById(id)); 
     model.addAttribute("listPersons", this.personService.listPersons()); 
     return "person"; 
    } 
} 

messages.properties

html.validation.firstName=Invalid First Name 
length.validation.firstName=First Name should be 2 to 50 lenght in characters 
html.validation.lastName=Invalid Last Name 
length.validation.lastName=Last Name should be 2 to 50 lenght in characters 
html.validation.country=Invalid Country Name 
length.validation.country=Country Name should be 2 to 50 lenght in characters 
html.validation.emailId=Invalid Email ID 
length.validation.emailId=Email ID length should not be more than 11 characters 

сервлет-context.xml

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


    <!-- Enables the Spring MVC @Controller programming model --> 
    <annotation-driven /> 
    <context:component-scan base-package="com.journaldev.spring.controller" /> 

    <!-- Load database.properties file --> 
    <context:property-placeholder location="classpath:database.properties" /> 

    <!-- Enable JPA Repositories --> 
    <jpa:repositories base-package="com.journaldev.spring.repository" /> 

    <!-- Enable Transaction Manager --> 
    <tx:annotation-driven transaction-manager="transactionManager" /> 

    <!-- Necessary to get the entity manager injected into the factory bean --> 
    <beans:bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 


    <!-- ====== MYSQL DataSource ====== --> 
    <beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
     <beans:property name="driverClassName" value="${mysql.jdbc.driverClassName}" /> 
     <beans:property name="url" value="${mysql.jdbc.url}" /> 
     <beans:property name="username" value="${mysql.jdbc.userName}" /> 
     <beans:property name="password" value="${mysql.jdbc.password}" /> 
    </beans:bean> 

    <!-- ====== Hibernate JPA Vendor Adaptor ======= --> 
    <beans:bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
     <beans:property name="showSql" value="true"/> 
     <beans:property name="generateDdl" value="true"/> 
     <beans:property name="database" value="MYSQL"/> 
    </beans:bean> 


    <!-- Beans --> 
    <beans:bean id="personService" class="com.journaldev.spring.service.PersonServiceImpl" /> 
    <beans:bean id="visitService" class="com.journaldev.spring.service.VisitServiceImpl" /> 


    <beans:bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <beans:property name="dataSource" ref="dataSource"/> 
     <beans:property name="jpaVendorAdapter" ref="jpaVendorAdapter"/> 
     <beans:property name="packagesToScan" value="com.journaldev.spring.*" /> 
     <beans:property name="jpaProperties"> 
      <beans:props> 
       <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop> <!-- validate | update | create | create-drop --> 
       <beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</beans:prop> 
       <!-- <beans:prop key="hibernate.cache.use_query_cache">true</beans:prop> --> 
      </beans:props> 
     </beans:property> 
    </beans:bean> 

    <beans:bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <beans:property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </beans:bean> 

    <beans:bean id="validationMessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
     <beans:property name="basename" value="classpath:messages" /> 
     <beans:property name="defaultEncoding" value="UTF-8" /> 
    </beans:bean> 

    <beans:bean name="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 
     <beans:property name="validationMessageSource"> 
      <beans:ref bean="validationMessageSource"/> 
     </beans:property> 
    </beans:bean> 
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <beans:property name="prefix" value="/WEB-INF/views/" /> 
     <beans:property name="suffix" value=".jsp" /> 
    </beans:bean> 
</beans:beans> 

Person.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %> 
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> 
<%@ page session="false" %> 
<html> 
<head> 
    <title>Person Details Page</title> 
    <style type="text/css"> 
     .tg {border-collapse:collapse;border-spacing:0;border-color:#ccc;} 
     .tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#fff;} 
     .tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#f0f0f0;} 
     .tg .tg-4eph{background-color:#f9f9f9} 
    </style> 
</head> 
<body> 
<h1> 
    Add a Person 
</h1> 

<c:url var="addAction" value="/person/add" ></c:url> 

<form:form action="${addAction}" commandName="person"> 
<table> 
    <c:if test="${!empty person.firstname}"> 
    <tr> 
     <td> 
      <form:label path="id"> 
       <spring:message text="ID"/> 
      </form:label> 
     </td> 
     <td> 
      <form:input path="id" readonly="true" size="8" disabled="true" /> 
      <form:hidden path="id" /> 
     </td> 
    </tr> 
    </c:if> 
    <tr> 
     <td> 
      <form:label path="firstname"> 
       <spring:message text="First Name"/> 
      </form:label> 
     </td> 
     <td> 
      <form:input path="firstname" /> 
     </td> 
    </tr> 

    <tr> 
     <td> 
      <form:label path="lastname"> 
       <spring:message text="Last Name"/> 
      </form:label> 
     </td> 
     <td> 
      <form:input path="lastname" /> 
     </td> 
    </tr> 

    <tr> 
     <td> 
      <form:label path="emailId"> 
       <spring:message text="EmailId"/> 
      </form:label> 
     </td> 
     <td> 
      <form:input path="emailId" /> 
     </td> 
    </tr> 

    <tr> 
     <td> 
      <form:label path="country"> 
       <spring:message text="Country"/> 
      </form:label> 
     </td> 
     <td> 
      <form:input path="country" /> 
     </td> 
    </tr> 
    <tr> 
     <td colspan="2"> 
      <c:if test="${!empty person.firstname}"> 
       <input type="submit" 
        value="<spring:message text="Edit Person"/>" /> 
      </c:if> 
      <c:if test="${empty person.firstname}"> 
       <input type="submit" 
        value="<spring:message text="Add Person"/>" /> 
      </c:if> 
     </td> 
    </tr> 
</table>  
</form:form> 
<br> 
<h3>Persons List</h3> 
<c:if test="${!empty listPersons}"> 
    <table class="tg"> 
    <tr> 
     <th width="80"><b>PersonID</b></th> 
     <th width="120"><b>FirstName</b></th> 
     <th width="120"><b>LastName</b></th> 
     <th width="120"><b>EmailID</b></th> 
     <th width="120"><b>Country</b></th> 
     <th width="60"><b>Edit</b></th> 
     <th width="60"><b>Delete</b></th> 
    </tr> 
    <c:forEach items="${listPersons}" var="person"> 
     <tr> 
      <td>${person.id}</td> 
      <td>${person.firstname}</td> 
      <td>${person.lastname}</td> 
      <td>${person.emailId}</td> 
      <td>${person.country}</td> 
      <td><a href="<c:url value='/edit/${person.id}' />" >Edit</a></td> 
      <td><a href="<c:url value='/remove/${person.id}' />" >Delete</a></td> 
     </tr> 
    </c:forEach> 
    </table> 
</c:if> 
</body> 
</html> 

Изображение: enter image description here pom.xml

<properties> 
     <java.version>1.7</java.version> 
     <org.springframework-version>4.1.9.RELEASE</org.springframework-version> 
     <org.aspectj-version>1.7.4</org.aspectj-version> 
     <org.slf4j-version>1.7.5</org.slf4j-version> 
     <hibernate.version>5.1.0.Final</hibernate.version> 
     <validation-api.version>1.1.0.Final</validation-api.version> 
     <hibernate-validator.version>5.1.1.Final</hibernate-validator.version> 
     <jsoup-version>1.8.1</jsoup-version> 
     <spring-data-jpa-version>1.9.2.RELEASE</spring-data-jpa-version> 
    </properties> 

    <dependencies> 
     <!-- Spring --> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-webmvc</artifactId> 
      <version>${org.springframework-version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-tx</artifactId> 
      <version>${org.springframework-version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-jpa</artifactId> 
      <version>${spring-data-jpa-version}</version> 
     </dependency> 


     <!-- Hibernate Entity Manager --> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>${hibernate.version}</version> 
     </dependency> 


     <!-- Validations --> 
     <dependency> 
      <groupId>javax.validation</groupId> 
      <artifactId>validation-api</artifactId> 
      <version>${validation-api.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-validator</artifactId> 
      <version>${hibernate-validator.version}</version> 
     </dependency> 

     <!-- Apache Commons DBCP --> 
     <dependency> 
      <groupId>commons-dbcp</groupId> 
      <artifactId>commons-dbcp</artifactId> 
      <version>1.4</version> 
     </dependency> 
     <!-- Spring ORM --> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-orm</artifactId> 
      <version>${org.springframework-version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-test</artifactId> 
      <version>${org.springframework-version}</version> 
     </dependency> 

     <!-- Querydsl dependencies --> 
     <dependency> 
      <groupId>com.mysema.querydsl</groupId> 
      <artifactId>querydsl-core</artifactId> 
      <version>3.3.2</version> 
     </dependency> 
     <dependency> 
      <groupId>com.mysema.querydsl</groupId> 
      <artifactId>querydsl-apt</artifactId> 
      <version>3.3.2</version> 
     </dependency> 
     <dependency> 
      <groupId>com.mysema.querydsl</groupId> 
      <artifactId>querydsl-jpa</artifactId> 
      <version>3.3.2</version> 
     </dependency> 

     <!-- LOG4J --> 
     <dependency> 
      <groupId>log4j</groupId> 
      <artifactId>log4j</artifactId> 
      <version>1.2.17</version> 
      <scope>runtime</scope> 
     </dependency> 


     <!-- Needed for Hibernate Validation --> 
     <dependency> 
      <groupId>org.jsoup</groupId> 
      <artifactId>jsoup</artifactId> 
      <version>${jsoup-version}</version> 
     </dependency> 

     <dependency> 
      <groupId>com.google.code.findbugs</groupId> 
      <artifactId>jsr305</artifactId> 
      <version>3.0.0</version> 
     </dependency> 

     <!-- @Inject --> 
     <dependency> 
      <groupId>javax.inject</groupId> 
      <artifactId>javax.inject</artifactId> 
      <version>1</version> 
     </dependency> 

     <!-- JSP API --> 
     <dependency> 
      <groupId>javax.servlet.jsp</groupId> 
      <artifactId>jsp-api</artifactId> 
      <version>2.1</version> 
      <scope>provided</scope> 
     </dependency> 
     <!-- Servlet API --> 
     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>servlet-api</artifactId> 
      <version>2.5</version> 
      <scope>provided</scope> 
     </dependency> 

     <!-- JSTL --> 
     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>jstl</artifactId> 
      <version>1.2</version> 
     </dependency> 

     <!-- Junit Test --> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.12</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>mysql</groupId> 
      <artifactId>mysql-connector-java</artifactId> 
      <version>5.1.37</version> 
     </dependency> 
    </dependencies> 

    <!-- Project Build --> 
    <build> 
     <finalName>spring-mvc-jpa-hibernate</finalName> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.5.1</version> 
       <configuration> 
        <source>${java.version}</source> 
        <target>${java.version}</target> 
        <compilerArgument>-Xlint:all</compilerArgument> 
        <showWarnings>true</showWarnings> 
        <showDeprecation>true</showDeprecation> 
       </configuration> 
      </plugin> 


      <plugin> 
       <groupId>com.mysema.maven</groupId> 
       <artifactId>apt-maven-plugin</artifactId> 
       <version>1.1.1</version> 
       <executions> 
        <execution> 
         <phase>generate-sources</phase> 
         <goals> 
          <goal>process</goal> 
         </goals> 
         <configuration> 
          <!-- Specifies the directory in which the query types are generated --> 
          <outputDirectory>target/generated-sources</outputDirectory> 
          <!-- States that the APT code generator should look for JPA annotations --> 
          <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 
+1

[Ответ на этот вопрос] (http://stackoverflow.com/questions/9232284/use-custom-validation-messages-in-hibernate-spring), кажется, есть то, что вы ищете , – Enigo

+0

Хотя я не понимаю этого ответа. Не могли бы вы описать ответ здесь? –

ответ

1

Определите MessageSource боба идентификатор как 'messageSource' и ссылаться на него вы валидатор как 'messageSource', как Что ж.

<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
    <beans:property name="basenames"> 
     <beans:list> 
      <beans:value>classpath:messages</beans:value> 
      <beans:value>classpath:ValidationMessages</beans:value> 
     </beans:list>   
    </beans:bean> 
    <beans:property name="defaultEncoding" value="UTF-8" /> 
</beans:bean> 

Также для Hibernate Validation вам потребуется ValidationMessages.properties и убедитесь, что использовались правильные имена ключей. Имейте в виду, что внешние свойства сообщений должны переопределять значения по умолчанию для структуры проверки для предоставления настраиваемых сообщений. смотри ниже

ValidationMessages.properties 

# FirstName 
html.validation.firstName=Invalid First Name 
#length.validation.firstName=First Name should be 2 to 50 lenght in characters 
Length.person.firstname=First Name should be 2 to 50 lenght in characters 

# LastName 
html.validation.lastName=Invalid Last Name 
#length.validation.lastName=Last Name should be 2 to 50 lenght in characters 
Length.person.lastname=Last Name should be 2 to 50 lenght in characters 

# Country 
html.validation.country=Invalid Country Name 
#length.validation.country=Country Name should be 2 to 50 lenght in characters 
Length.person.country=Country Name should be 2 to 50 lenght in characters 

#EmailId 
html.validation.emailId=Invalid Email ID 
#length.validation.emailId=Email ID length should not be more than 11 characters 
Length.person.emailId=Email ID length should not be more than 11 characters 
Pattern.person.emailId=Invalid Email Format 
+0

Как насчет того, чтобы попытаться отладить пакет org.springframework.context.support и посмотреть, загружается ли * .properties? – aalmero

+0

см. Обновленный ответ относительно проверки Hibernate. Для javax.validation (JSR-303) он будет использовать сообщение * .properties. – aalmero

+0

Позвольте мне посмотреть, могу ли я опубликовать обновленный код в GitHub. – aalmero

Смежные вопросы