2015-09-10 12 views
17

Ho un'applicazione webmvc di Spring Data Rest che mi piacerebbe aggiungere alcune funzionalità personalizzate per le operazioni batch.Accettazione di un URI REST di dati primari nel controller personalizzato

Ho creato un controller e l'ho fuso nel namespace uri, ma mi piacerebbe che fosse in grado di accettare URI come le query personalizzate /search, piuttosto che semplicemente un ID.

ho cercato la registrazione di un convertitore personalizzato <String, Long> (la mia entità ha un tipo Long ID, ma che sembra avere ignorato. C'è un modo per configurare il mio controller in modo tale che esso adotta che il comportamento dei controllori auto-implementato SDR?

Anche se v'è una sorta di metodo posso chiamare che la volontà di auto-risolvere un URI a un'entità, che avrebbe funzionato altrettanto bene (come posso poi semplicemente accettare un String nel mio controller)

Ecco dove sono.

@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; 
    } 


} 

E la mia (fittizia) di controllo:

ApplicationType è uno dei miei soggetti, che siano correttamente gestito da SDR/repository magia

@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); 
    } 
} 

Ho guardato in giro un bel po 'ma non riesco a far funzionare nulla. Quando creo un convertitore <String, ApplicationType> che utilizza il repository, anche non ottenere chiamato, come il DomainClassConverter semplicemente chiama il suo sottostante <String, Long> convertitore (che non riesce ovviamente, in quanto non in grado di analizzare correttamente types/1 in una lunga.

apprezzare l'aiuto !

dimenticato di dire

  • primavera dati Resto 2.4.0
  • Primavera hateoas 0.19.0
  • Primavera 4 .2.1

Uso repository JPA

+0

Avete provato ad annotare il controller con @RepositoryRestController? In effetti, non ho avuto problemi nell'ottenere automaticamente le entità SDR da PathVariables nei normali controller, ma poi, sto usando Spring Boot e include qualche autoconfigurazione. –

+0

Lo farò, grazie Ilya! – CollinD

+0

@IlyaNovoseltsev Sfortunatamente nessun dado. Mi piacerebbe essere in grado di interrogarlo in questo modo 'GET domain.com/api/applications/batch/removeType? Type = types/7' ma sta ancora lanciando un errore di conversione. – CollinD

risposta

4

Come risulta, ero sulla strada giusta con l'aggiunta di un convertitore, sfortunatamente lo stavo facendo nel modo di configurazione sbagliato.

sono stato in grado di ottenere la funzionalità desiderata spostando il mio testConverter() fagiolo per la classe config RepositoryRestMvcConfiguration estensione e quindi aggiungendo

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

e di lavoro come previsto. Mi sento un po 'stupido ora per averlo buttato nel posto sbagliato, ma spero che questo possa aiutare qualcun altro!

+0

Non ho potuto farlo funzionare. Cos'è 'mvcConversionService()'? – aycanadal

+0

Vedere: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.html#mvcConversionService-- Viene fornito estendendo 'WebMvcConfigurationSupport' – CollinD

4

sto inviando una risposta in base alla mia ultima osservazione.

A quanto pare la logica si richiede - autoconverting URI da @RequestParam a un'entità repository gestiti - è implementato in un paio di metodi privati ​​di RepositorySearchController (vedi executeQueryMethod e prepareUris), quindi non c'è modo facile per ottenere in controller personalizzati .

Puoi provare a creare il tuo risolutore di argomenti con Spring HATEOAS. Guarda come viene implementato il resolver PersistentEntityResourceHandlerMethodArgumentResolver. Ha risolto un'entità basata sul suo @BackendId.

+0

Non c'è un esempio funzionante completo di quello? Il controllore dovrebbe chiedere un parametro myEntity o un parametro URI? Grazie – drenda

Problemi correlati