[英]Can't resolve custom validation messages in Hibernate + Spring
I am developing Spring MVC + Hibernate Validator
integration example by taking reference from https://spring.io/guides/gs/validating-form-input/ . 我正在开发Spring MVC + Hibernate Validator
集成示例,参考https://spring.io/guides/gs/validating-form-input/ 。 I added some messages to be gets resolved from messages.properties
file, but none of the messages getting resolved and facing below issue. 我添加了一些要从messages.properties
文件中解析的messages.properties
,但没有消息得到解决并面临下面的问题。 Please guide why application not recognizing the messages.properties
file. 请指导应用程序无法识别messages.properties
文件的原因。 I was expecting to get actual message from .properties file, but why this is coming [{length.validation.country}]
? 我期待从.properties文件中获取实际消息,但是为什么会出现[{length.validation.country}]
?
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 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 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 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
servlet-context.xml servlet的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 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>
<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>
Define your MessageSource bean id as 'messageSource' and reference it from you validator as 'messageSource' as well. 将MessageSource bean id定义为'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>
Also for Hibernate Validation you will need ValidationMessages.properties and make sure the correct key names were used. 此外,对于Hibernate验证,您将需要ValidationMessages.properties并确保使用了正确的密钥名称。 Keep in mind that external message properties need to override the defaults of the validation framework to provide custom messages. 请记住,外部消息属性需要覆盖验证框架的默认值以提供自定义消息。 see below 见下文
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.