Принятие URI-кода Spring Data REST в пользовательском контроллере
У меня есть приложение Spring Data Rest webmvc, которое я хотел бы добавить для пользовательских функций для пакетных операций.
Я создал контроллер и объединил его в пространство имен uri, но я хотел бы, чтобы он мог принимать URI, как пользовательские запросы /search
, а не просто ID.
Я пробовал зарегистрировать собственный конвертер <String, Long>
(мой объект имеет тип идентификатора Long
, но это кажется проигнорированным. Есть ли способ настроить мой контроллер таким образом, чтобы он принимал это поведение из автоматически реализованного SDR-контроллеры?
Даже если есть какой-то метод, который я могу вызвать, который автоматически разрешит URI для объекта, который будет работать так же хорошо (поскольку я могу просто принять String
в моем контроллере)
Здесь, где я нахожусь.
@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
@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;
}
}
И мой (надуманный) контроллер:
ApplicationType - это одно из моих объектов, которое правильно управляется магией хранилища SDR/репозитория
@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);
}
}
Я немного оглянулся, но не могу ничего сделать. Когда я создаю конвертер <String, ApplicationType>
, который использует репозиторий, он также не вызывается, поскольку DomainClassConverter просто вызывает свой базовый конвертер <String, Long>
(который явно не работает, поскольку он не может правильно разобрать types/1
в длинный.
Цените помощь!
Забыл упомянуть
- Spring Data Rest 2.4.0
- Spring HATEOAS 0.19.0
- Spring 4.2.1
Использование репозиториев JPA
Ответы
Ответ 1
Как оказалось, я был на правильном пути с добавлением конвертера, к сожалению, я делал это в неправильном способе настройки.
Мне удалось получить желаемую функциональность, переместив мой testConverter()
bean в класс конфигурации расширения RepositoryRestMvcConfiguration
, а затем добавив
@Override
public void configureConversionService(ConfigurableConversionService service) {
service.addConverter(testConverter());
}
И работаем по назначению. Я чувствую себя немного глупо сейчас за то, что выбрал это не в том месте, но, надеюсь, это поможет кому-то другому!
Ответ 2
Я отправляю ответ на основании моего последнего комментария.
По-видимому, требуемая логика - автокодирование URI от @RequestParam
до объекта, управляемого репозиторией, - реализована в нескольких частных методах RepositorySearchController
(см. executeQueryMethod
и prepareUris
), поэтому нет простого способ получить его в пользовательских контроллерах.
Вы можете попробовать создать свой собственный преобразователь аргументов с помощью Spring HATEOAS. Посмотрите, как реализуется преобразователь PersistentEntityResourceHandlerMethodArgumentResolver
. Он разрешил сущность, основанную на ее @BackendId
.