2016-04-09 21 views
6

Ich bin neu in Spring Boot. In meinem Controller verwende ich UUID s als @PathVariable. In der Standardeinstellung gibt der Frühling MethodArgumentTypeMismatchException zurück, wenn eine ungültige UUID übergeben wird.benutzerdefinierte Konverter nicht im Spring Boot registriert

Wenn der Client einen ungültigen UUID übergibt, möchte ich einen benutzerdefinierten InvalidUUIDException, so dass ich in der Lage, eine benutzerdefinierte ErrorDto mithilfe dieser Ausnahme zurückgegeben werden kann.

Um zu erreichen, dass ich versuche, eine benutzerdefinierte UUIDConverter (Implementierung org.springframework.core.convert.converter.Converter) zu registrieren.

@Component 
public class UUIDConverter implements Converter<String, UUID> 
{ 
    private static final Pattern pattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"); 

    @Override 
    public UUID convert(String input) throws InvalidUuidException 
    { 
     if (!pattern.matcher(input).matches()) { 
      throw new InvalidUuidException(input); 
     } 

     return UUID.fromString(input); 
    } 
} 

diese Komponente zu registrieren, ich bin das Hinzufügen dieser Konverter Federn ConversionService. Verwenden Sie die ConversionServiceFactoryBean.

@Configuration 
public class ConversionServiceConfiguration 
{ 
    @Bean 
    public ConversionServiceFactoryBean conversionService() 
    { 
     ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean(); 
     bean.setConverters(getConverters()); 

     return bean; 
    } 

    private Set<Converter> getConverters() 
    { 
     Set<Converter> converters = new HashSet<>(); 
     converters.add(new UUIDConverter()); 

     return converters; 
    } 
} 

Ich habe auch versucht @Component statt @Configuration zu verwenden, wie es hier erwähnt: Spring not using mongo custom converters

Andere Lösungen, die ich ausprobiert: conversionServiceFactoryBean statt conversionService die Bohne Namen. Oder rufen bean.afterPropertiesSet() und eine ConversionService mit bean.getObject() Neuabstimmung ...

Ich habe auch von WebMvcConfigurerAdapter zu erweitern versucht, zwingende addFormatters und fügen Sie mein Konverter dort addConverter mit ...

Wie hier erwähnt: How to register custom converters in spring boot? Ich habe versuchte auch den Konverter als @Bean direkt zu registrieren.

Es spielt keine Rolle, was ich ausprobiert habe, die UUIDConverter wird nicht angewendet.

Was ist die richtige Lösung, um so etwas in Spring-Boot zu tun?
Kann mir hier jemand helfen? Was mache ich falsch?

+0

Ich habe das exakt gleiche Problem – wasabi

+0

Haben Sie SprinbWebMvc aktiviert? – hovanessyan

Antwort

0

Der idiomatische Weg im Frühjahr, um diesen Fall zu behandeln, ist eine benutzerdefinierte ExceptionHandler verwenden. Im Grunde sagst du Spring, dass du mit dieser speziellen Fehlerklasse umgehen wirst.

Die Idee ist, dass Sie die ExceptionHandler, definieren, die die geworfenen Fehler ab (zB MethodArgumentTypeMismatchException) und gibt einen individuellen ResponseEntity mit dem, was Struktur bevölkerte (zB ErrorDto) benötigen Sie, Fehlercodes, Header usw.

Hier ein Beispiel:

@ExceptionHandler({ MethodArgumentTypeMismatchException.class }) 
public ResponseEntity<Object> handleMethodArgumentTypeMismatch(
    MethodArgumentTypeMismatchException ex, WebRequest request) { 

    //populate your ErrorDto with the desired information 
    ErrorDto errorDto = 
     new ErrorDto(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), ex); 

    //return your ErrorDto wrapped in ResponseEntity 
    return new ResponseEntity<Object>(errorDto, HttpStatus.BAD_REQUEST); 
} 

UPDATE

ich war tatsächlich in der Lage einen Beispielcode fe laufen aturing your custom converter, aber was passiert, ist, die Ausnahme, die Sie werfen wird in ConversionFailedException eingewickelt, dann in TypeMismatchException und schließlich in MethodArgumentTypeMismatchException und das ist, was an den Client zurückgegeben wird. Selbst wenn Sie es mit dem benutzerdefinierten Konverter ausführen, gibt es zusätzliche Arbeit, um Ihre Ausnahme an den Client weiterzugeben und nicht in MethodArgumentTypeMismatchException eingewickelt werden.

+0

Entschuldigung, dieser Code hat nichts mit dem Problem zu tun. Die Ausnahme ** handling ** funktioniert einwandfrei. Das Problem hier ist, eine ** benutzerdefinierte Ausnahme ** zu werfen, um dem Client explizit mitzuteilen, dass die UUID das ungültige Stück in der Anfrage ist, die den Spring-Boot-Konverter verwendet. In Bezug auf Ihr Update: Dies können Sie vermeiden, indem Sie benutzerdefinierte Ausnahmen verwenden – Tim

+0

Haben Sie Ihren Code tatsächlich debugged, um zu sehen, ob die Konverter-Convert-Methode aufgerufen wird? – hovanessyan

+0

Mit dem ExceptionHandler können Sie immer noch die gewünschten Informationen an den Client senden. Soweit ich es verstehe, wird Ihre App JSON zurücksenden, also ist es egal, ob Sie den JSON aus dieser oder jener Ausnahme konstruieren oder eine andere Klasse verwenden. Normalerweise wird der Fehlerstatus in REST durch die HTTP-Statuscodes angezeigt, die Sie mit ExceptionHandler festlegen können. – hovanessyan

1

ich nur über dieses Thema wissen, weil ich die gleiche mich mit einer anderen Klasse und verbrachte Stunden getan haben Debuggen ...

Die UUIDConverter ist eine Bohne already a registered by Spring itself. Wählen Sie wörtlich einen anderen Namen und Sie sollten es sehen.

+0

Huh, muss das ausprobieren. In diesem Fall würde ich NoUniqueBean Ausnahme oder etwas Ähnliches erwarten:/Danke für Ihren Hinweis! – Tim

Verwandte Themen