在自定义控制器中接受 Spring 数据 REST URI
Accepting a Spring Data REST URI in custom controller
我有一个 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;
}
};
}
}
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/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);
}
}
我环顾四周但无法完全解决任何问题。当我创建一个使用存储库的 <String, ApplicationType>
转换器时,它也不会被调用,因为 DomainClassConverter 只是调用其底层的 <String, Long>
转换器(这显然失败了,因为它无法正确解析 types/1
成长.
感谢您的帮助!
忘了说
- Spring 数据休息 2.4.0
- Spring HATEOAS 0.19.0
- Spring 4.2.1
使用 JPA 存储库
我将根据我上一条评论发布一个答案。
显然,您需要的逻辑——将 URI 从 @RequestParam
自动转换为存储库管理的实体——是在 RepositorySearchController
的一些私有方法中实现的(参见 executeQueryMethod
和 prepareUris
), 所以没有简单的方法在自定义控制器中获取它。
您可以尝试使用 Spring HATEOAS 创建您自己的参数解析器。查看 PersistentEntityResourceHandlerMethodArgumentResolver
解析器是如何实现的。它根据 @BackendId
.
解析了一个实体
事实证明,我在添加转换器方面走在了正确的轨道上,不幸的是我使用了错误的配置方法。
我能够通过将我的 testConverter()
bean 移动到 RepositoryRestMvcConfiguration
扩展配置 class 然后添加
来获得所需的功能
@Override
public void configureConversionService(ConfigurableConversionService service) {
service.addConverter(testConverter());
}
并按预期工作。我现在觉得一开始就把它扔错了地方有点傻,但希望这能帮助其他人!
我有一个 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;
}
};
}
}
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/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);
}
}
我环顾四周但无法完全解决任何问题。当我创建一个使用存储库的 <String, ApplicationType>
转换器时,它也不会被调用,因为 DomainClassConverter 只是调用其底层的 <String, Long>
转换器(这显然失败了,因为它无法正确解析 types/1
成长.
感谢您的帮助!
忘了说
- Spring 数据休息 2.4.0
- Spring HATEOAS 0.19.0
- Spring 4.2.1
使用 JPA 存储库
我将根据我上一条评论发布一个答案。
显然,您需要的逻辑——将 URI 从 @RequestParam
自动转换为存储库管理的实体——是在 RepositorySearchController
的一些私有方法中实现的(参见 executeQueryMethod
和 prepareUris
), 所以没有简单的方法在自定义控制器中获取它。
您可以尝试使用 Spring HATEOAS 创建您自己的参数解析器。查看 PersistentEntityResourceHandlerMethodArgumentResolver
解析器是如何实现的。它根据 @BackendId
.
事实证明,我在添加转换器方面走在了正确的轨道上,不幸的是我使用了错误的配置方法。
我能够通过将我的 testConverter()
bean 移动到 RepositoryRestMvcConfiguration
扩展配置 class 然后添加
@Override
public void configureConversionService(ConfigurableConversionService service) {
service.addConverter(testConverter());
}
并按预期工作。我现在觉得一开始就把它扔错了地方有点傻,但希望这能帮助其他人!