2017-10-01 1 views
0

Ich verwende Spring Boot, Spring JPA, Federdaten REST, Spring HATEOAS, Hibernate Validator. Ich habe meinen eigenen Constraint-Validator erstellt.Aktivieren Sie die Internationalisierung für Integritätsüberprüfungen auf Klassenebene mit Spring

Die Anmerkung:

Target({ java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.ANNOTATION_TYPE }) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = { TicketBundleValidator.class }) 
@Documented 
public @interface ValidTicketBundle { 

    String message() default "{server.validators.annotations.ValidTicketBundle.message}"; 

    Class<?>[] groups() default {}; 

    Class<? extends Payload>[] payload() default {}; 
} 

Der Validator:

public class TicketBundleValidator implements ConstraintValidator<ValidTicketBundle, TicketBundle> { 

    @Override 
    public void initialize(ValidTicketBundle constraintAnnotation) { 
    } 

    @Override 
    public boolean isValid(TicketBundle value, ConstraintValidatorContext context) { 
     if (value == null) 
      return true; 

     // Must be at least 1 row for each ticket bundle 
     if (value.getRows().size() == 0) 
      return false; 

     // The start/end date must be valid 
     if (value.getStartDate().isAfter(value.getEndDate())) 
      return false; 

     // The sum of payments can't be greater than the total price of the ticket 
     // bundle 
     if (value.getTotalPaymentsAmount().compareTo(value.getTotalPrice()) == 1) 
      return false; 

     // if (!isValid) { 
     // constraintContext.disableDefaultConstraintViolation(); 
     // constraintContext.buildConstraintViolationWithTemplate(
     // "{org.hibernate.validator.referenceguide.chapter06." + 
     // "constraintvalidatorcontext.CheckCase.message}" 
     //) 
     // .addConstraintViolation(); 
     // } 
     return true; 
    } 

} 

Ich habe meinen Schlüssel und Text sowohl in Ressourcen/i18n/messages.properties und Ressourcen/i18n/validation.properties:

server.validators.annotations.ValidTicketBundle.message = I dati inseriti non sono validi. Verificare nuovamente e ripetere l'operazione. 

Ich habe meinen Testfall erstellt, um zu überprüfen, ob alles funktioniert:

@Test 
    @WithMockUser(roles = "ADMIN") 
    public void saveTicketBundleWithWrongDateThrowsException() { 
     TicketBundle ticketBundle = new TicketBundle(); 
     ticketBundle.setCustomer(customer); 
     ticketBundle.setStartDate(Instant.now().plus(30, ChronoUnit.DAYS)); 
     ticketBundle.setEndDate(Instant.now()); 

     Set<ConstraintViolation<TicketBundle>> constraintViolations = validator.validate(ticketBundle); 
     assertEquals(1, constraintViolations.size()); 
     ConstraintViolation<TicketBundle> constraintViolation = constraintViolations.iterator().next(); 
     assertEquals("I dati inseriti non sono validi. Verificare nuovamente e ripetere l'operazione.", 
       constraintViolation.getMessage()); 
    } 

aber ich habe eine fehlschlagen, weil die Nachricht Validierung Schlüssel scheint nicht behoben:

org.junit.ComparisonFailure: expected:<[I dati inseriti non sono validi. Verificare nuovamente e ripetere l'operazione.]> but was:<[{server.validators.annotations.ValidTicketBundle.message}]> 
    at org.junit.Assert.assertEquals(Assert.java:115) 

Ich bin sicher, dass ich etwas verpasst, aber es ist nicht ganz klar, was. Dies ist eine MVC-Anwendung, aber ich möchte nicht nur die REST-Endopoint-Antworten mit lokalisierten Nachricht: Ich erwarte auch der Testfall erhalten die richtige Nachricht.

Um das Bild abzurunden, ich habe diese Konfiguration Klasse in meinem Projekt:

@Configuration 
@EnableHypermediaSupport(type = { HypermediaType.HAL }) 
public class WebMvcConfiguration extends WebMvcConfigurerAdapter { 
@Bean 
public LocaleResolver localeResolver() { 
    return new SmartLocaleResolver(); 
} 

public class SmartLocaleResolver extends CookieLocaleResolver { 
    @Override 
    public Locale resolveLocale(HttpServletRequest request) { 
     String acceptLanguage = request.getHeader("Accept-Language"); 
     if (acceptLanguage == null || acceptLanguage.trim().isEmpty()) { 
      return super.determineDefaultLocale(request); 
     } 
     return request.getLocale(); 
    } 
} 

@Bean 
public MessageSource messageSource() { 
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); 
    messageSource.setBasenames("classpath:/i18n/messages"); 
    // messageSource.setDefaultEncoding("UTF-8"); 
    messageSource.setUseCodeAsDefaultMessage(true); 
    messageSource.setCacheSeconds((int) TimeUnit.HOURS.toSeconds(1)); 
    messageSource.setFallbackToSystemLocale(false); 
    return messageSource; 
} 
+0

Wie wird in diesem Zusammenhang auf die Nachrichtenquelle verwiesen? –

+0

@RomanC Ich dachte, dass von Spring Boot automatisch verwiesen wurde. – drenda

+0

Hey @drenda Ich habe dir eine Frage gestellt? Wenn Sie diese Frage nicht beantworten können, sollten Sie eine * klare Problembeschreibung * einschließlich des Codes zur Verfügung stellen, um das Problem reproduzieren zu können, ohne klare Aussage und qualifizierte Code-Frage ist off-topic und sollte entfernt werden, sobald es Ihnen unmöglich ist eine Lösung, ohne Details zu wissen oder einfach Ihren Beitrag zu entfernen, um Entwickler nicht zu stören, die streiten, anstatt Details zur Verfügung zu stellen. –

Antwort

Verwandte Themen