java - getmapping - Aceptar un URI REST de datos de Spring en un controlador personalizado
requestmapping spring example (2)
Estoy publicando una respuesta basada en mi último comentario.
Aparentemente, la lógica que necesita (URI de executeQueryMethod
prepareUris
de @RequestParam
a una entidad gestionada por repositorio) se implementa en algunos métodos privados de RepositorySearchController
(consulte executeQueryMethod
y prepareUris
), por lo que no hay una manera fácil de conseguirlo en controladores personalizados.
Puedes intentar crear tu propio solucionador de argumentos con Spring HATEOAS. Mire cómo se implementa la resolución PersistentEntityResourceHandlerMethodArgumentResolver
. Se resolvió una entidad basada en su @BackendId
.
Tengo una aplicación webmvc Spring Data Rest a la que me gustaría agregar algunas funciones personalizadas para las operaciones por lotes.
He creado un controlador y lo he combinado en el espacio de nombres de uri, pero me gustaría que pueda aceptar URI como lo hacen las consultas de /search
personalizadas, en lugar de simplemente una ID.
He intentado registrar un convertidor <String, Long>
(mi entidad tiene un tipo de ID Long
, pero parece que se ignora. ¿Hay alguna forma de configurar mi controlador de tal manera que adopte ese comportamiento de los controladores SDR implementados automáticamente?
Incluso si hay algún tipo de método al que pueda llamar que resolverá automáticamente una URI para una entidad, funcionaría igual de bien (ya que entonces puedo simplemente aceptar una String
en mi controlador)
Aquí es donde estoy.
@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;
}
};
}
}
Configuración de SDR
@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;
}
}
Y mi (ideado) controlador:
ApplicationType es una de mis entidades que se administran correctamente con SDR / repository magic
@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);
}
}
He mirado un poco alrededor, pero no logro hacer que nada funcione. Cuando creo un convertidor <String, ApplicationType>
que utiliza el repositorio, tampoco recibe llamadas, ya que DomainClassConverter solo llama a su convertidor <String, Long>
subyacente (lo que obviamente falla, ya que no puede analizar correctamente los types/1
en un largo
¡Aprecie la ayuda!
Olvide mencionar
- Spring Data Rest 2.4.0
- Primavera HATEOAS 0.19.0
- Primavera 4.2.1
Usando repositorios JPA
Resulta que estaba en el camino correcto al agregar un convertidor, desafortunadamente lo estaba haciendo con el método de configuración incorrecto.
Pude obtener la funcionalidad deseada moviendo mi testConverter()
a la clase de configuración de la extensión RepositoryRestMvcConfiguration
y luego agregando
@Override
public void configureConversionService(ConfigurableConversionService service) {
service.addConverter(testConverter());
}
Y trabajando según lo previsto. Me siento un poco tonto ahora por tirar eso en el lugar equivocado en primer lugar, ¡pero espero que esto ayude a alguien más!