【问题标题】:Spring Data Rest Not MappedSpring Data Rest 未映射
【发布时间】:2017-03-07 05:44:25
【问题描述】:

我正在尝试使用弹簧数据休息。我已将其依赖项包含在 pom 中并定义了以下 bean,但没有为 repos 创建映射。我从哪里开始寻找问题?

@Bean
    public RepositoryRestConfigurer repositoryRestConfigurer(){

        return new RepositoryRestConfigurerAdapter(){

            @Override
            public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config){
                config.setBasePath("/api");
            }
        };
    }

以下是 pom.xml

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <springframework.version>4.3.1.RELEASE</springframework.version>
        <springsecurity.version>4.2.0.RELEASE</springsecurity.version>
        <hibernate.core.version>4.3.11.Final</hibernate.core.version>
        <hibernate.validator.version>5.1.3.Final</hibernate.validator.version>
        <mysql.connector.version>5.1.31</mysql.connector.version>
        <postgresql.version>9.4-1200-jdbc41</postgresql.version>
        <joda-time.version>2.3</joda-time.version>
        <jackson-version>2.7.5</jackson-version>
        <maven-compiler-plugin-version>3.2</maven-compiler-plugin-version>
        <maven-war-plugin-version>2.4</maven-war-plugin-version>
        <source-jdk>1.8</source-jdk>
        <target-jdk>1.8</target-jdk>
        <war-source-directory>src/main/webapp</war-source-directory>
        <war-name>dmapp</war-name>
        <final-name>dmapp</final-name>
  </properties> 

  <dependencies>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>1.7.2.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-rest-webmvc</artifactId>
        <version>2.6.1.RELEASE</version>
    </dependency>


    <!--    SPRING SECURITY -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${springsecurity.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${springsecurity.version}</version>
    </dependency>


    <!-- Hibernate -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.core.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.3.11.Final</version>
    </dependency>

    <!-- jsr303 validation -->
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>${hibernate.validator.version}</version>
    </dependency>



    <!--  Javax Transactions -->    
    <dependency>
        <groupId>javax.transaction</groupId>
        <artifactId>jta</artifactId>
        <version>1.1</version>  
    </dependency>




    <!-- POSTGRESQL -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>${postgresql.version}</version>
    </dependency>

    <!-- Joda-Time -->       
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>${joda-time.version}</version>
    </dependency>

    <!-- To map JodaTime with database type -->      
    <dependency>
        <groupId>org.jadira.usertype</groupId>
        <artifactId>usertype.core</artifactId>
        <version>3.0.0.CR1</version>
    </dependency>

    <!-- Servlet+JSP+JSTL -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-version}</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version>
    </dependency> -->

  </dependencies>

  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin-version}</version>
            <configuration>
                <source>${source-jdk}</source>
                <target>${target-jdk}</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>${maven-war-plugin-version}</version>
            <configuration>
                <warSourceDirectory>${war-source-directory}</warSourceDirectory>
                <warName>${war-name}</warName>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
    </plugins>
    <finalName>${final-name}</finalName>
  </build>

AppConfig.java

package com.pdma.dmapp.configuration;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.pdma.dmapp")
public class AppConfig extends WebMvcConfigurerAdapter{

    @Bean(name="multipartResolver")
    public StandardServletMultipartResolver resolver(){
        return new StandardServletMultipartResolver();
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry){
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        registry.viewResolver(viewResolver);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/webResources/**").addResourceLocations("/webResources/");
        registry.addResourceHandler("/app/**").addResourceLocations("/app/");
    }
}

PersistenceContext.java

package com.pdma.dmapp.configuration;

@Configuration
@EnableTransactionManagement
@PropertySource(value = {"classpath:db.properties"})
@EnableJpaRepositories("com.pdma.dmapp.module")
public class PersistenceContext {

    @Autowired
    private Environment environment;


    @Bean
    @Autowired
    public LocalSessionFactoryBean sessionFactory(){

        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String [] {"com.pdma.dmapp.module"});
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    @Bean
    @Autowired
    LocalContainerEntityManagerFactoryBean entityManagerFactory(
            DataSource dataSource,
            Environment env){

        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = 
                new LocalContainerEntityManagerFactoryBean();

        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        entityManagerFactoryBean.setPackagesToScan(new String [] {"com.pdma.dmapp.module"});

        entityManagerFactoryBean.setJpaProperties(hibernateProperties());

        return entityManagerFactoryBean;

    }

    @Bean
    public DataSource dataSource(){

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(  environment.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(              environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(         environment.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(         environment.getRequiredProperty("jdbc.password"));
        return dataSource;
    }

    private Properties hibernateProperties(){

        Properties properties = new Properties();
        properties.put("hibernate.dialect",     environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql",    environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql",  environment.getRequiredProperty("hibernate.format_sql"));
        return properties;
    }

    @Bean
    @Autowired
    public HibernateTransactionManager hibernateTXManager(SessionFactory sessionFactory){

        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory);    
        return txManager;
    }

    @Bean
    @Autowired
    JpaTransactionManager jpaTXManager(EntityManagerFactory entityManagerFactory){

        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory);
        return txManager;
    }


    /*  Same Bean Created as above because CrudRepository Methods are annotated with @Transactional
     *  So they require a bean named transactionManager*/

    @Bean
    @Autowired
    JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory){

        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory);
        return txManager;
    }

    @Bean
    @Autowired
    public RepositoryRestConfigurer repositoryRestConfigurer(){

        return new RepositoryRestConfigurerAdapter(){

            @Override
            public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config){
                config.setBasePath("/api");
            }
        };
    }
}

SecurityConfiguration.java

package com.pdma.dmapp.configuration;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.inMemoryAuthentication()
        .withUser("Admin")
        .password("admin123")
        .roles("Admin");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
        .antMatchers("/login","/webResources/**").permitAll()
            .antMatchers("/**").access("hasRole('Admin')")
            .and().formLogin()
                  .loginPage("/login")
                  .usernameParameter("username")
                  .passwordParameter("password")
            .and().csrf()
            .and().exceptionHandling().accessDeniedPage("/accessDenied");

        http.sessionManagement()
            .maximumSessions(1)
            .expiredUrl("/login.html");
    }
}

AppInitializer.java

package com.pdma.dmapp.configuration;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{

    private static final String LOCATION = "D:/uploads/";
    private static final long MAX_FILE_SIZE = 1024*1024*200;
    private static final long MAX_REQUEST_SIZE = 1024*1024*200;
    private static final int FILE_SIZE_THRESHOLD = 0;

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return new Class [] {AppConfig.class, PersistenceContext.class, SecurityConfiguration.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        // TODO Auto-generated method stub
        return new String [] {"/"};
    }

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration){
        registration.setMultipartConfig(getMultipartConfigElement());
    }

    private MultipartConfigElement getMultipartConfigElement(){
        MultipartConfigElement element = new MultipartConfigElement(LOCATION,
                                                                    MAX_FILE_SIZE,
                                                                    MAX_REQUEST_SIZE,
                                                                    FILE_SIZE_THRESHOLD);
        return element;
    }


     @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
        servletContext.addListener(new SessionListener());
    }
}

存储库

package com.pdma.dmapp.module.surveys.repo;

@Transactional("jpaTXManager")
@RepositoryRestResource(exported = true)
public interface SurveyorRepo extends CrudRepository<Surveyor, Integer> {

    Surveyor findByDeviceImeiNo1OrDeviceImeiNo2(String deviceImeiNo1, String deviceImeiNo2);
    List<Surveyor> findByDistrictDistrictId(Integer districtId);
}

【问题讨论】:

    标签: spring-data-rest


    【解决方案1】:

    首先,尝试通过以下方式配置Sprint Data REST

    @Configuration
    public class CustomRepositoryRestConfiguration extends RepositoryRestMvcConfiguration {
                @Override
                public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config){
                    config.setBasePath("/api");
                }
    ...
    }
    

    此外,请确保您的存储库 bean 在 Spring 上下文中可用,并使用 @RepositoryRestResource 注释对其进行注释。

    编辑:我认为主要问题是如何将 MVC 与 Spring Data REST 混合使用。使用RepositoryRestMvcConfiguration 而不是RepositoryRestConfigurerAdapter。您可以在官方指南herehere 中找到有关如何设置的详细指南。

    更新:对于较新版本的Spring Data REST,基本路径的设置方式不同:

    @Configuration
    public class RestDataConfig  extends RepositoryRestMvcConfiguration {
    
        @Override
        @Bean
        public BaseUri baseUri() {
            config().setBasePath("/api");
            return new BaseUri(config().getBaseUri());
        }
    }
    

    【讨论】:

    • 这样做了,但仍然无法正常工作。我的配置文件位于 com.pdma.dmapp.configuration 中。而我将 com.pdma.dmapp 指定为要扫描的基本包。
    • 应该这样工作,但仍然最好将配置放在基本包中,在您的情况下为 com.pdma.dmapp。另外,请分享您拥有的所有 Spring 配置和存储库代码。
    • 添加了配置文件。
    • 我认为主要问题是如何将 MVC 与 Spring Data REST 混合使用。您需要使用RepositoryRestMvcConfiguration。检查我更新的答案。
    • 好像用Spring Data REST的新版本删除了。尝试通过覆盖 baseUri() 方法来提供 BaseUri bean。 docs.spring.io/spring-data/rest/docs/current/api/org/…
    【解决方案2】:

    值得一提的是,在 Spring Data REST 3.+ 中,RepositoryRestMvcConfiguration 的 API 发生了变化,如果人们寻求版本 3+ 的答案,可以:

    1. @Import RepositoryRestMvcConfiguration

      @Import( ...,
          RepositoryRestMvcConfiguration.class,
          ...)
      public class YourConfig { //snip }
      
    2. 通过扩展 RepositoryRestConfigurerAdapter 并覆盖 basePath 来注册 RepositoryRestConfigurer @Bean

      @Bean
      public RepositoryRestConfigurer repositoryRestConfigurer() {
          return new RepositoryRestConfigurerAdapter() {
              @Override
              public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config){
                  // snip
                  config.setBasePath("/data");
                  // snip               
      
      }
      

    值得注意的是,可以使用相同的方法来公开实体的 ID 并管理 RepositoryRestConfigurer 负责的其他功能。

    【讨论】:

      猜你喜欢
      • 2016-03-13
      • 2016-07-18
      • 1970-01-01
      • 2018-05-06
      • 1970-01-01
      • 2023-03-09
      • 2017-05-18
      • 2016-12-18
      • 1970-01-01
      相关资源
      最近更新 更多