Integrated standard Spring MessageSource components for resolving error messages in validators.

This commit is contained in:
Jon Brisbin
2012-10-09 16:55:14 -05:00
committed by Jon Brisbin
parent e8be1c1ded
commit d97c14ebb2
5 changed files with 81 additions and 24 deletions

View File

@@ -22,6 +22,8 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
@@ -1579,7 +1581,46 @@ public class RepositoryRestController
Map m = new HashMap();
List<String> errors = new ArrayList<String>();
for(FieldError fe : ex.getErrors().getFieldErrors()) {
errors.add(fe.getDefaultMessage());
String msg = applicationContext.getMessage(fe.getCode(),
new Object[]{fe.getObjectName(), fe.getField(), fe.getRejectedValue()},
fe.getDefaultMessage(),
null);
errors.add(msg);
}
m.put("errors", errors);
return negotiateResponse(request, HttpStatus.BAD_REQUEST, new HttpHeaders(), m);
}
/**
* Send a 400 Bad Request in case of a validation failure.
*
* @param ex
* @param request
*
* @return
*
* @throws IOException
*/
@SuppressWarnings({"unchecked"})
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResponseEntity handleJsr303ValidationFailure(ConstraintViolationException ex,
ServletServerHttpRequest request) throws IOException {
LOG.error(ex.getMessage(), ex);
Map m = new HashMap();
List<String> errors = new ArrayList<String>();
for(ConstraintViolation cv : ex.getConstraintViolations()) {
String msg = applicationContext.getMessage(cv.getMessageTemplate(),
new Object[]{
cv.getLeafBean().getClass().getSimpleName(),
cv.getPropertyPath().toString(),
cv.getInvalidValue()
},
cv.getMessage(),
null);
errors.add(msg);
}
m.put("errors", errors);

View File

@@ -2,10 +2,13 @@ package org.springframework.data.rest.webmvc.spec
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.rest.repository.RepositoryConstraintViolationException
import org.springframework.data.rest.test.webmvc.Customer
import org.springframework.data.rest.test.webmvc.Person
import org.springframework.data.rest.test.webmvc.TestRepositoryEventListener
import org.springframework.http.HttpStatus
import javax.validation.ConstraintViolationException
/**
* @author Jon Brisbin
*/
@@ -20,13 +23,37 @@ class EventsSpec extends BaseSpec {
def request = createJsonRequest("POST", "people", null, person)
when:
controller.create(request, baseUri, "people")
try {
controller.create(request, baseUri, "people")
} catch (RepositoryConstraintViolationException e) {
controller.handleValidationFailure(e, request)
throw e
}
then:
thrown(RepositoryConstraintViolationException)
}
def "handles JSR-303 validation errors"() {
given:
def cust = new Customer()
def request = createJsonRequest("POST", "customer", null, cust)
when:
try {
controller.create(request, baseUri, "customer")
} catch (ConstraintViolationException e) {
controller.handleJsr303ValidationFailure(e, request)
throw e
}
then:
thrown(ConstraintViolationException)
}
def "captures before and after events"() {
given:

View File

@@ -1,33 +1,14 @@
package org.springframework.data.rest.test;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.Module;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.module.SimpleSerializers;
import org.codehaus.jackson.map.ser.std.SerializerBase;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.test.webmvc.Person;
import org.springframework.data.rest.test.webmvc.PersonValidator;
import org.springframework.data.rest.test.webmvc.TestRepositoryEventListener;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.ResourceProcessor;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaDialect;
@@ -48,6 +29,12 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
public class ApplicationConfig {
@Bean public MessageSource messageSource() {
ResourceBundleMessageSource ms = new ResourceBundleMessageSource();
ms.setBasename("org.springframework.data.rest.test.ValidationErrors");
return ms;
}
@Bean public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.HSQL).build();

View File

@@ -3,6 +3,7 @@ package org.springframework.data.rest.test.webmvc;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
/**
* @author Jon Brisbin
@@ -11,6 +12,7 @@ import javax.persistence.Id;
public class Customer {
@Id @GeneratedValue private Long id;
@NotNull
private String userid;
public Long getId() {

View File

@@ -21,7 +21,7 @@ public class PersonValidator implements Validator {
@Override public void validate(Object target, Errors errors) {
Person p = (Person)target;
LOG.debug(" ***** Validating Person " + p);
ValidationUtils.rejectIfEmpty(errors, "name", "field.name.required", "Field 'name' cannot be blank.");
ValidationUtils.rejectIfEmpty(errors, "name", "field.name.required");
}
}