在我们的项目中,我们使用 Spring Boot 2.7.17、OpenAPI 规范和 RestAssured 进行测试。这是根据我们的规范生成的 API 接口部分:
@RequestMapping(
method = RequestMethod.GET,
value = "/accounts/{accountId}/statements/{statementId}",
produces = {"application/pdf", "image/gif", "image/jpeg", "image/tiff", "image/png", "application/json"}
)
ResponseEntity<Resource> getAccountStatement(
@Parameter(name = "accountId", description = "Account Identifier", required = true, in = ParameterIn.PATH) @PathVariable("accountId") String accountId,
@Parameter(name = "statementId", description = "Statement Identifier", required = true, in = ParameterIn.PATH) @PathVariable("statementId") String statementId
);
实施不会改变任何东西:
@Override
public ResponseEntity<Resource> getAccountStatement(String accountId, String statementId) {
var consentId = customerClaimsProvider.getConsentId();
var subject = getSubject();
return accountListService.getAccountStatement(accountId, statementId, consentId, subject);
}
这是我们的Groovy测试(使用spock框架),注意URI中的空格:
def "Run endpoint with undefined and empty data for getAccountStatement"() {
setup:
//...
when:
Response responseEmpty = baseSpec(accessToken)
.get("accounts/v1/accounts/ /statements/ ")
then:
responseEmpty.then().statusCode(400)
}
在迁移之前,测试正常,但在将 SB 升级到 3.2.1 后,测试开始失败,因为控制器现在返回 404 而不是 400:
Condition failed with Exception:
responseEmpty.then().statusCode(400)
| | |
| | java.lang.AssertionError: 1 expectation failed.
| | Expected status code <400> but was <404>.
在后端对应的是:
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource accounts/%20/statements.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585) ~[spring-webmvc-6.1.2.jar:6.1.2]
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52) ~[spring-webmvc-6.1.2.jar:6.1.2]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.2.jar:6.1.2]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.2.jar:6.1.2]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.2.jar:6.1.2]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.1.2.jar:6.1.2]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.17.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.2.jar:6.1.2]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.17.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
上下文路径描述为
server:
servlet:
context-path: /open-banking/accounts/v1
有吗
似乎由于上下文路径配置而出现问题。在这种情况下,问题出在其他地方,我认为与 Spring boot v2 到 v3 的迁移有关。我建议您删除上下文路径并使用其他方式。你也可以把它看作一个工作环境:
在应用程序属性中:
app.apiPrefix=/open-banking/accounts/v1
并将其添加到您的控制器类中:
@RequestMapping(value = "${app.apiPrefix}")
这应该可以解决您的问题。