Spring 数据休息 @RepositoryRestController 和 @RequestMapping
Spring Data Rest @RepositoryRestController and @RequestMapping
我想使用@RepositoryRestController 覆盖@RepositoryRestResource 自动生成的控制器方法并设置了 SDR 的基本路径
到“/api”。
Spring Data Rest 3.0(及更早版本)说:
"This controller [as shown in the snippet] will be served from the same API base path defined in RepositoryRestConfiguration.setBasePath that is used by all other RESTful endpoints (e.g. /api)"。
https://docs.spring.io/spring-data/rest/docs/3.0.1.RELEASE/reference/html/#customizing-sdr.overriding-sdr-response-handlers(第 15.4 章)
不过,此代码片段在 class 级别上没有 @RequestMapping
。
我的 SDR 应用配置了 RepositoryRestConfiguration 对象
config.setBasePath("/api");
但 @RepositoryRestController
不会覆盖 SDR 的自动生成的控制器方法。
请考虑对此 post 的公认回答:
请帮助我理解这一点! :)
AppConf.java:
@Configuration
@Import(value = {DataConf.class})
@EnableWebMvc
@ComponentScan(value = "pl.mydomain.controller")
public class AppConf
{
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer() {
return new RepositoryRestConfigurerAdapter() {
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/api");
}
};
}
}
TokenController.java:
@RepositoryRestController
public class TokenController
{
private TokenRepository repository;
@Autowired
public TokenController(TokenRepository tokenRepository) {
this.repository = tokenRepository;
}
@RequestMapping(method = GET, path = "/tokens")
public @ResponseBody ResponseEntity<?> tokens()
{
return ResponseEntity.ok("Hello");
}
}
TokenRepository.java:
@RepositoryRestResource(path = "tokens")
public interface TokenRepository extends CrudRepository<Token, Long>{
}
解决上述困境的关键是以正确的方式配置项目。也就是说,将 @ComponentScan
放在传递给 AbstractAnnotationConfigDispatcherServletInitializer::getServletConfigClasses()
方法的 class 中(而不是在传递给 getRootConfigClasses() 的 AppConf.java 中)。
DispatcherConf.java:
public class DispatcherConf extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {AppConf.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {WebConf.class}; // !!!
}
@Override
protected String[] getServletMappings() {
return new String[] {"/*"};
}
}
AppConf.java:
@Configuration
@Import({DataConf.class})
public class ApplicationConf
{
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer() {
return new RepositoryRestConfigurerAdapter() {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/api"); // !!!
}
};
}
}
DataConf.java:
@Configuration
@EnableJpaRepositories(basePackages = {
"pl.example.data.repository"
})
@EnableTransactionManagement
public class DataConf
{ ... }
WebConf.java:
@Import(RepositoryRestMvcConfiguration.class)
@ComponentScan({"pl.example.api.controller"}) // !!!
public class WebConf {
}
即使我解开了谜题,我也不明白为什么它会成为问题。相反 https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html 指出:
Annotation Type ComponentScan onfigures component scanning directives
for use with @Configuration classes.
我想使用@RepositoryRestController 覆盖@RepositoryRestResource 自动生成的控制器方法并设置了 SDR 的基本路径 到“/api”。
Spring Data Rest 3.0(及更早版本)说:
"This controller [as shown in the snippet] will be served from the same API base path defined in RepositoryRestConfiguration.setBasePath that is used by all other RESTful endpoints (e.g. /api)"。 https://docs.spring.io/spring-data/rest/docs/3.0.1.RELEASE/reference/html/#customizing-sdr.overriding-sdr-response-handlers(第 15.4 章)
不过,此代码片段在 class 级别上没有 @RequestMapping
。
我的 SDR 应用配置了 RepositoryRestConfiguration 对象
config.setBasePath("/api");
但 @RepositoryRestController
不会覆盖 SDR 的自动生成的控制器方法。
请考虑对此 post 的公认回答:
请帮助我理解这一点! :)
AppConf.java:
@Configuration
@Import(value = {DataConf.class})
@EnableWebMvc
@ComponentScan(value = "pl.mydomain.controller")
public class AppConf
{
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer() {
return new RepositoryRestConfigurerAdapter() {
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/api");
}
};
}
}
TokenController.java:
@RepositoryRestController
public class TokenController
{
private TokenRepository repository;
@Autowired
public TokenController(TokenRepository tokenRepository) {
this.repository = tokenRepository;
}
@RequestMapping(method = GET, path = "/tokens")
public @ResponseBody ResponseEntity<?> tokens()
{
return ResponseEntity.ok("Hello");
}
}
TokenRepository.java:
@RepositoryRestResource(path = "tokens")
public interface TokenRepository extends CrudRepository<Token, Long>{
}
解决上述困境的关键是以正确的方式配置项目。也就是说,将 @ComponentScan
放在传递给 AbstractAnnotationConfigDispatcherServletInitializer::getServletConfigClasses()
方法的 class 中(而不是在传递给 getRootConfigClasses() 的 AppConf.java 中)。
DispatcherConf.java:
public class DispatcherConf extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {AppConf.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {WebConf.class}; // !!!
}
@Override
protected String[] getServletMappings() {
return new String[] {"/*"};
}
}
AppConf.java:
@Configuration
@Import({DataConf.class})
public class ApplicationConf
{
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer() {
return new RepositoryRestConfigurerAdapter() {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/api"); // !!!
}
};
}
}
DataConf.java:
@Configuration
@EnableJpaRepositories(basePackages = {
"pl.example.data.repository"
})
@EnableTransactionManagement
public class DataConf
{ ... }
WebConf.java:
@Import(RepositoryRestMvcConfiguration.class)
@ComponentScan({"pl.example.api.controller"}) // !!!
public class WebConf {
}
即使我解开了谜题,我也不明白为什么它会成为问题。相反 https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html 指出:
Annotation Type ComponentScan onfigures component scanning directives for use with @Configuration classes.