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

时间:2015-01-18 21:53:24

标签: java spring spring-data-jpa spring-data-rest

我正在尝试实现自定义控制器来处理自定义存储库中定义的方法,以便能够通过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/*"};
     }

}

ApplicationConfig:

@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
    }
}

ExperimentRepository:

@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
    }

}

ExperimentController:

@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容器中注册,或者我缺少一些关于控制器方法的其他设置。有什么建议?

提前致谢!

1 个答案:

答案 0 :(得分:2)

您需要配置才能加载控制器。一种方法是添加一个配置类来加载控制器并将其添加到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/*" };
    }

}