Col*_*inD 19 java rest spring spring-data-rest
我有一个Spring Data Rest webmvc应用程序,我想为批处理操作添加一些自定义功能.
我已经创建了一个控制器,并将其混合到uri命名空间中,但我希望它能够像自定义/search查询一样接受URI ,而不仅仅是ID.
我试过注册一个自定义<String, Long>转换器(我的实体有一个Long ID类型,但似乎被忽略.有没有办法配置我的控制器,使其采用自动实现的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;
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
而我的(人为的)控制器:
ApplicationType是我的实体之一,由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);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经看了很多,但不能完全做任何事情.当我创建一个<String, ApplicationType>利用存储库的转换器时,它也不会被调用,因为DomainClassConverter只是调用它的底层<String, Long>转换器(显然失败了,因为它无法正确地解析types/1为long.
感谢帮助!
忘了提
使用JPA存储库
事实证明,我在添加转换器时走在正确的轨道上,不幸的是我在错误的配置方法中做到了这一点.
通过将我的testConverter()bean 移动到RepositoryRestMvcConfiguration扩展配置类然后添加,我能够获得所需的功能
@Override
public void configureConversionService(ConfigurableConversionService service) {
service.addConverter(testConverter());
}
Run Code Online (Sandbox Code Playgroud)
并按预期工作.我现在感觉有点傻,因为首先把它扔在错误的地方,但希望这会帮助别人出去!
我根据我的上次评论发布了答案.
显然,您需要的逻辑 - 将URI自动转换@RequestParam为存储库管理的实体 - 是在RepositorySearchController(参见executeQueryMethod和prepareUris)的一些私有方法中实现的,因此没有简单的方法可以在自定义控制器中获取它.
您可以尝试使用Spring HATEOAS创建自己的参数解析器.了解PersistentEntityResourceHandlerMethodArgumentResolver解析器的实现方式.它解决了一个基于它的实体@BackendId.