繁体   English   中英

Spring Data Rest @RepositoryRestController和@RequestMapping

[英]Spring Data Rest @RepositoryRestController and @RequestMapping

我想使用已将SDR的基本路径设置为“ / api”的@RepositoryRestController覆盖@RepositoryRestResource自动生成的控制器方法。

Spring Data Rest 3.0(及更早版本)说:

“此控制器(如代码段所示)将由RepositoryRestConfiguration.setBasePath中定义的同一API基本路径提供服务,所有其他RESTful端点(例如/ api)都使用该API。” https://docs.spring.io/spring-data/rest/docs/3.0.1.RELEASE/reference/html/#customizing-sdr.overriding-sdr-response-handlers (第15.4章)

但是,此代码段在类级别上没有@RequestMapping

我的SDR应用配置了RepositoryRestConfiguration对象

config.setBasePath("/api");

但是@RepositoryRestController不会覆盖SDR的自动生成的控制器方法。

请考虑这篇文章的公认答案: Spring Data Rest控制器:@ BasePathAwareController,@ RepositoryRestController,@ Controller和@RestController的行为和用法

请帮助我理解这一点! :)

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()方法的类中(不在AppConf.java中传递给getRootConfigClasses()的类中)。

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声明:

注释类型ComponentScan用于@Configuration类的组件扫描指令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM