ISSUE
The issue is that my endpoints with @GET annotation work just fine and results in a 200. @POST results in a 404. They are configured almost identically. Console does not report any errors.
Background
I am setting up a controller to contain a series of GETs and POSTs. I am using SpringBoot/Tomcat. The specific library is cxf-spring-boot-starter-jaxrs (version: 3.3.3)
I followed this guide for setup: https://cxf.apache.org/docs/springboot.html
As I understand, the spring boot starter handles the servlet setup, so I don't have that to share.
Server and service bean initialization looks like this:
@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();
}
My controller looks like this:
@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();
}
}
Note: BaseController is effectively empty, so we can ignore that.
I have also disabled all @Providers to ensure nothing is interfering. Same with spring security.
I have used both Postman and CURL to test this.
GET URL that works: http://localhost:8080/selector-service/v1/test/gettest
POST URL that does not work: http://localhost:8080/selector-service/v1/test/posttest
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
}'
Update(12/31/2020) Another interesting note: When I run a POST on the method, it returns a 404 but when I try to GET the POST endpoint it returns a 405. This stands out to me because it appears that the server has indeed registered the post endpoint.
Update(1/4/2020) I found a blog post from someone who configured a similar setup using "cxf.jaxrs.component-scan". I followed this guide which rendered my rsServer() @Bean redundant. I have tried removing it. This had no effect and I am still having the same issue.
service.properties:
server.address=localhost
cxf.path=/
cxf.jaxrs.component-scan=true
Could you try mapping Spring's DispatcherServlet and CXF Servlet to different paths?
Something like:
# 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
Btw, I'm the author of the blog post you are using as a reference:
https://tech.asimio.net/2017/06/12/Implementing-APIs-using-Spring-Boot-CXF-and-Swagger.html