我正在使用 Spring Data Rest 来公开我可以在我的用户界面中使用的其余端点。但是,在测试过程中,我注意到当点击 base rest url (http://localhost:8080/rest) 时,端点的暴露不一致。我正在使用基于注释的 RepositoryDetectionStrategies。
如果您能帮助我理解和解决问题,我将不胜感激。
示例:
首次启动:所有端点都正确暴露:
{
"_links" : {
"orders" : {
"href" : "http://localhost:8080/rest/orders{?page,size,sort}","templated" : true
},"reports" : {
"href" : "http://localhost:8080/rest/reports{?page,"buySells" : {
"href" : "http://localhost:8080/rest/positions{?page,"profile" : {
"href" : "http://localhost:8080/rest/profile"
}
}
}
在没有任何代码或配置更改的情况下重新启动后:
{
"_links" : {
"orders" : {
"href" : "http://localhost:8080/rest/orders{?page,"profile" : {
"href" : "http://localhost:8080/rest/profile"
}
}
}
如您所见,在应用程序重新启动后,报告端点未公开。 曝光失败非常不一致;有时所有 3 个端点都未公开,有时缺少 1 或 2 个(不一致),有时一切正常。
我无法在日志中找到任何故障,即使将其放入 TRACE 也是如此。
配置
这里是主要的pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rvh</groupId>
<artifactId>project-parent</artifactId>
<version>0.0.1-snAPSHOT</version>
<name>project-parent</name>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.7.30</slf4j.version>
</properties>
<modules>
<!-- <module>compiler-plugin-java-9</module> --> <!-- We haven't upgraded to java 9. -->
<module>web</module>
<module>api-engine</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>nl.rvh</groupId>
<artifactId>business-rule-validator</artifactId>
<version>1.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- <version>2.5.3</version>-->
<!-- </dependency>-->
</dependencies>
</dependencyManagement>
<dependencies>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <optional>true</optional>-->
<!-- </dependency>-->
</dependencies>
<build>
<finalName>collector</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>com.rvh.collector.CollectorApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
<!-- mvn sonar:sonar \-->
<!-- -Dsonar.projectKey=baralga \-->
<!-- -Dsonar.organization=baralga \-->
<!-- -Dsonar.host.url=https://sonarcloud.io \-->
<!-- -Dsonar.login=<GENERATED_TOKEN>-->
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.7.0.1746</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
<argLine>-Dfile.encoding=UTF8</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
这里是 web 模块 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.rvh</groupId>
<artifactId>project-parent</artifactId>
<version>0.0.1-snAPSHOT</version>
</parent>
<artifactId>collector</artifactId>
<version>0.0.1-snAPSHOT</version>
<name>collector</name>
<description>collector application</description>
<packaging>war</packaging>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<m2eclipse.wtp.contextRoot>/</m2eclipse.wtp.contextRoot>
<java.version>11</java.version>
<sonar.coverage.jacoco.xmlReportPaths>${project.build.directory}/site/jacoco/jacoco.xml
</sonar.coverage.jacoco.xmlReportPaths>
</properties>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-data</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <optional>true</optional>-->
<!-- </dependency>-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>17-ea+14</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.rvh.api.engine</groupId>
<artifactId>apiEngine</artifactId>
<version>1.0-snAPSHOT</version>
</dependency>
<!-- Provided -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>nl.rvh.trade</groupId>
<artifactId>kraken-api</artifactId>
<version>1.0-snAPSHOT</version>
</dependency>
<dependency>
<groupId>nl.rvh</groupId>
<artifactId>business-rule-validator</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
这是主类的注释方式:
@Configuration
@ComponentScan("com.rvh.**")
@EnableAutoConfiguration
@EnableJpaRepositories("com.rvh.collector")
@EnableScheduling
public class CollectorApplication {
这是其余的配置类:
@Configuration
public class RestRepositoryConfig implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config,CorsRegistry cors) {
//Only expose annotated repositories
config.setRepositoryDetectionStrategy(RepositoryDetectionStrategy.RepositoryDetectionStrategies.ANNOTATED);
config.setBasePath("/rest");
ExposureConfiguration exposureConfiguration = config.getExposureConfiguration();
exposureConfiguration.withItemExposure((metadata,httpMethods) -> httpMethods
.disable(HttpMethod.PATCH,HttpMethod.DELETE,HttpMethod.TRACE,HttpMethod.HEAD,HttpMethod.PUT,HttpMethod.POST));
}
}
和我的 rest 存储库,它们都是 com.rvh.collector.rest 包的一部分。
@RepositoryRestResource
@PreAuthorize("hasRole('ROLE_ADMIN')")
public interface OrdersRest extends PagingAndSortingRepository<Order,Integer> {
}
@RepositoryRestResource(path = "positions")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public interface PositionRestRepo extends PagingAndSortingRepository<BuySell,Integer> {
}
@RepositoryRestResource
@PreAuthorize("hasRole('ROLE_ADMIN')")
public interface ReportsDao extends PagingAndSortingRepository<Report,Long> {
@Query("select report from Report report where report.accountId in "
+ "(select acc.id from User user join user.accounts acc where user.username = ?#{ principal?.username }) ")
Iterable<Report> findAll();
@Query("select report from Report report where report.accountId in "
+ "(select acc.id from User user join user.accounts acc where user.username = ?#{ principal?.username })"
+ "and report.id = :aLong ")
Optional<Report> findById(Long aLong);
}