@RepositoryRestController 带有 RepositoryRestMvcConfiguration 和 AbstractAnnotationConfigDispatcherServletInitializer 的自定义控制器

@RepositoryRestController custom controller with RepositoryRestMvcConfiguration and AbstractAnnotationConfigDispatcherServletInitializer

我正在尝试实现自定义控制器来处理自定义存储库中定义的方法,以便能够使用此方法通过 REST 公开资源(根据 Implementing custom methods of Spring Data repository and exposing them through REST)。

这里是配置和其他相关代码:

public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

     @Override
     protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {ApplicationConfig.class};
     }

     @Override
     protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {RepositoryRestMvcConfiguration.class};
     }

     @Override
     protected String[] getServletMappings() {
        return new String[]{"/api/*"};
     }

}

应用程序配置:

@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
public class ApplicationConfig {

    @Bean
    public DataSource dataSource() {
        // data source settings
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        // em factory settings
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        // tx mng settings
    }
}

实验资料库:

@RepositoryRestResource
public interface ExperimentRepository extends PagingAndSortingRepository<Experiment, Long>,
    ExperimentRepositoryCustom {

    @RestResource(rel = "byName", path = "byName")
    Page<Experiment> findByNameContaining(@Param("name") String name, Pageable pageable);

}

ExperimentRepositoryCustom:

public interface ExperimentRepositoryCustom {

    Page<Experiment> findUsingCustomFilter(...);

}

ExperimentRepositoryImpl:

public class ExperimentRepositoryImpl implements ExperimentRepositoryCustom {

    @Override
    public Page<Experiment> findUsingCustomFilter(...) {
        // search for experiment based on given filter
    }

}

实验控制器:

@RepositoryRestController
public class ExperimentController {

    @Autowired
    private ExperimentRepository experimentRepository;


    @RequestMapping(value = "/experiments/search/findByFilter", method= RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<Experiment> searchUsingFilter(@RequestParam Long id) {
        // for test purpose call method from CrudRepository (will be replaced by findUsingCustomFilter(...)) 
        return new ResponseEntity(experimentRepository.findOne(id), HttpStatus.OK);
    }
}

项目结构:

basepackage.model.Experiment
basepackage.repository.ExperimentController
basepackage.repository.ExperimentRepository
basepackage.repository.ExperimentRepositoryImpl
basepackage.repository.ExperimentRepositoryCustom
basepackage.ApplicationInitializer
basepackage.ApplicationConfig

根据使用的存储库自动生成的链接公开的所有资源都可以毫无问题地访问,但在 http://localhost:8080/app/api/experiments/search/findByFilter?id=1 上调用 GET 方法以 404 结束(根据使用的存储库自动生成的链接公开的资源工作正常)。我假设 ExperimentController 没有在 Spring 容器中注册,或者我缺少一些关于控制器方法的额外设置。有什么建议么?

提前致谢!

您需要配置才能加载您的控制器。一种方法是添加一个配置 class 来加载您的控制器并将其添加到您的 ApplicationInitializer。

//PLACE THIS IN A PACKAGE WHERE YOUR CONTROLLERS ARE
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;

@ComponentScan
@Import(RepositoryRestMvcConfiguration.class)
public class WebConfig {
}

把你ApplicationInitializer改成

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import com.spring.data.rest.test.web.WebConfig;

public class ApplicationInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { ApplicationConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/api/*" };
    }

}