(Spring Boot/CXF/JJAXRS)@GET以200正确响应,@POST以404响应,尽管配置相同



ISSUE

问题是,我使用@GET注释的端点工作得很好,结果是200@POST结果是404。它们的配置几乎相同。控制台不报告任何错误。

背景

我正在设置一个控制器来包含一系列的GET和POST。我使用的是SpringBoot/Tomcat。具体的库是cxf-spring-boot-starter-jaxrs(版本:3.3.3(

我按照以下指南进行设置:https://cxf.apache.org/docs/springboot.html

据我所知,spring启动程序处理servlet的设置,所以我不需要共享这些设置。

服务器和服务bean初始化如下所示:

@Autowired
private List<? extends BaseController> controllers;
@Bean
public Server rsServer()
{
JAXRSServerFactoryBean endpoint = new JAXRSServerFactoryBean();
endpoint.setBus(bus);
endpoint.setAddress("/");
endpoint.setServiceBeans(new ArrayList<Object>(controllers));
endpoint.setExtensionMappings(getExtensionMapping());
// jsonProvider() is an instance of org.apache.cxf.jaxrs.provider.json.JSONProvider
endpoint.setProviders(Arrays.asList(jsonProvider()));
return endpoint.create();
}

我的控制器看起来像这样:

@Path("/v1/test")
@Service
public class SimpleTestController extends BaseController
{
@GET
@Path("/gettest")
@Produces(value = { "application/json" })
@Consumes(value = { "application/json" })
public Response getTest()
{
BlankResource blankResource = new BlankResource();
blankResource.setTest("WORKING");
return Response.ok(gson.toJson(blankResource), MediaType.APPLICATION_JSON)
.build();
}
@POST
@Path("/posttest")
@Produces(value = { "application/json" })
@Consumes(value = { "application/json" })
public Response postTest(BlankResource blankResource)
{
blankResource.setTest("WORKING");
return Response.ok(gson.toJson(blankResource), MediaType.APPLICATION_JSON)
.build();
}
}

注意:BaseController实际上是空的,所以我们可以忽略它。

我还禁用了所有@Providers,以确保没有任何干扰。与弹簧安全相同。

我已经使用Postman和CURL来测试这一点。

获取有效的URL:http://localhost:8080/selector-service/v1/test/gettest

无法工作的POST URL:http://localhost:8080/selector-服务/v1/测试/测试后

curl --location --request POST 'http://localhost:8080/selector-service/v1/test/posttest' 
--header 'Accept: application/json' 
--header 'Content-Type: application/json' 
--header 'Cookie: JSESSIONID=262BEEF808419C6CEC61E064AEA3EEAA' 
--data-raw '{
"test": true
}'

更新(2020年12月31日(另一个有趣的注意事项:当我在该方法上运行POST时,它会返回404,但当我尝试获取POST端点时,它返回405。这对我来说很突出,因为服务器似乎确实已经注册了post端点。

更新(2020年1月4日(我发现了一篇来自某人的博客文章,他使用";cxf.jaxrs.组件扫描";。我遵循了这个指南,它使我的rsServer((@Bean变得多余。我试着把它去掉了。这没有效果,我仍然有同样的问题。

service.properties:

server.address=localhost
cxf.path=/
cxf.jaxrs.component-scan=true

您可以尝试将Spring的DispatcherServlet和CXF Servlet映射到不同的路径吗?

类似于:

# Spring MVC dispatcher servlet path. Needs to be different than CXF's to enable/disable Actuator endpoints access (/info, /health, ...)
server.servlet-path: /
# http://cxf.apache.org/docs/springboot.html#SpringBoot-SpringBootCXFJAX-RSStarter
cxf:
path: /api # CXFServlet URL pattern
jaxrs:
component-scan: true

顺便说一句,我是你用作参考的博客文章的作者:

https://tech.asimio.net/2017/06/12/Implementing-APIs-using-Spring-Boot-CXF-and-Swagger.html

在JAX-RS中,AcceptContent-Type标头必须与方法在@Consumes@Produces中声明的内容以及URL相匹配。因此,对于Curl,您必须执行以下操作:

curl -i -H "Accept: application/json" -H "Content-Type: application/json" http://localhost:8080/selector-service/v1/test/posttest

最新更新