2015-09-10 8 views
17

Mam aplikację webmvc Spring Data Rest, do której chciałbym dodać niestandardową funkcjonalność dla operacji wsadowych.Akceptacja identyfikatora URI REST danych Spring w niestandardowym kontrolerze

Stworzyłem kontroler i wstawiłem go w przestrzeń nazw uri, ale chciałbym, aby był w stanie zaakceptować zapytania URI, takie jak niestandardowe zapytania, a nie po prostu identyfikator.

Próbowałem zarejestrować niestandardowy konwerter <String, Long> (moja jednostka ma typ ID Long ID, ale to wydaje się być ignorowane.Czy istnieje sposób skonfigurować mój kontroler tak, aby przyjęła to zachowanie z automatycznie wdrażanych kontrolerów SDR?

Nawet jeśli istnieje jakiś sposób mogę nazwać zostanie automatycznie rozwiązać URI do podmiotu, który będzie działać tak samo dobrze (jak mogę po prostu przyjąć String w moim kontrolera)

Oto gdzie jestem.

@Configuration 
public class CustomWebConfiguration extends WebMvcConfigurationSupport { 

    //irrelevant code omitted 

    @Bean 
    public DomainClassConverter<?> domainClassConverter() { 
     DomainClassConverter<FormattingConversionService> dc = new DomainClassConverter<FormattingConversionService>(mvcConversionService()); 
     return dc; 
    } 

    @Override 
    public void addFormatters(FormatterRegistry registry) { 
      registry.addConverter(String.class, Long.class, testConverter()); 
    } 

    @Bean 
    Converter<String, Long> testConverter() { 
     return new Converter<String, Long>() { 

      @Override 
      public Long convert(String source) { 
       //this code does _not_ get run at any point 
       if (source.indexOf('/') == -1) { return Long.parseLong(source); } 

       source = source.substring(source.lastIndexOf('/') + 1); 
       Long id = Long.parseLong(source); 

       return id; 
      } 
     }; 
    } 
} 

SDR Config

@Configuration 
@EnableHypermediaSupport(type = { HypermediaType.HAL }) 
public class CustomRestConfiguration extends RepositoryRestMvcConfiguration { 

    @Override 
    public RepositoryRestConfiguration config() { 
     RepositoryRestConfiguration config = super.config(); 
     config.setBasePath("/api"); 
     config.exposeIdsFor(ApplicationMembership.class); 
     return config; 
    } 


} 

A moja (wymyślony) Kontroler:

TypAplikacji jest jednym z moich jednostek, które są prawidłowo zarządzane przez SDR/repozytorium magicznym

@BasePathAwareController 
@RepositoryRestController 
@RequestMapping("applications/special") 
public class ApplicationExtensionController { 
    @RequestMapping("a") 
    public ResponseEntity<?> reply(@RequestParam("type") ApplicationType type) { 
     return new ResponseEntity<String>(type.getIcon(), HttpStatus.OK); 
    } 
} 

szukałem wokół trochę, ale nie udaje im się nic zrobić. Kiedy tworzę <String, ApplicationType> konwerter, który wykorzystuje repozytorium, to również nie sprawdzony, gdyż DomainClassConverter po prostu wywołuje jego podstawowej <String, Long> konwertera (co oczywiście nie powiedzie się, ponieważ nie można prawidłowo analizować out types/1 w długi.

Doceń pomoc !

Zapomniałem wspomnieć

  • Wiosna danych Rest 2.4.0
  • Wiosna hateoas 0.19.0
  • sprężyna 4 .2.1

Korzystanie repozytoria JPA

+0

Czy próbowałeś zanotować swój kontroler za pomocą @RepositoryRestController? W rzeczywistości nie miałem problemów z automatycznym pozyskiwaniem obiektów SDR z PathVariables w standardowych kontrolerach, ale potem używam Spring Boot i zawiera ono trochę autokonfiguracji. –

+0

Oddam to, dzięki Ilya! – CollinD

+0

@IlyaNovoseltsev Niestety nie ma kości. Chciałbym móc zapytać go tak, jak "GET domain.com/api/applications/batch/removeType? Type = types/7", ale wciąż nie można przekonwertować błędu. – CollinD

Odpowiedz

4

Jak się okazało, byłem na dobrej drodze z dodaniem konwertera, niestety robiłem to w niewłaściwej metodzie konfiguracji.

I był w stanie uzyskać pożądaną funkcjonalność przesuwając mój testConverter() fasoli do klasy RepositoryRestMvcConfiguration przedłużacza config, a następnie dodanie

@Override 
public void configureConversionService(ConfigurableConversionService service) { 
    service.addConverter(testConverter()); 
} 

I działa zgodnie z przeznaczeniem. Czuję się teraz trochę głupio, gdy wrzucam to w niewłaściwym miejscu, ale mam nadzieję, że to pomoże komuś innemu!

+0

Nie mogłem tego uruchomić. Co to jest 'mvcConversionService()'? – aycanadal

+0

Zobacz: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.html#mvcConversionService - Dostarczane przez rozszerzenie 'WebMvcConfigurationSupport' – CollinD

4

jestem delegowania odpowiedzi w oparciu o moim ostatnim komentarzu.

Widocznie logika wymagają - autoconverting URI z @RequestParam podmiotowi repozytorium zarządzane - jest realizowany w kilku prywatnych metod RepositorySearchController (patrz executeQueryMethod i prepareUris), więc nie ma łatwego sposobu, aby ją w sterownikach niestandardowych .

Możesz spróbować stworzyć własny argument rozstrzygający z HATEOAS wiosny. Sprawdź, w jaki sposób jest realizowany przelicznik PersistentEntityResourceHandlerMethodArgumentResolver. Rozwiązał jednostkę na podstawie jej @BackendId.

+0

Czy nie ma na to pełnego działającego przykładu? Czy kontroler powinien prosić o parametr myEntity lub parametr URI? Dzięki – drenda