Quantcast
Channel: Active questions tagged rest - Stack Overflow
Viewing all articles
Browse latest Browse all 4807

How to receive JSON Messages in POST body in a JAX-RS Restful web service in CXF?

$
0
0

I'm trying to develop a REST service using Apache-CXF, on top of JAX-RS. For starters, I have a method called test that receives a String message and int value. I want the clients to be able to pass these parameters in a POST message body. I can't seem to achieve this.

Before I paste the code here, here are some details:

  • I'm using CXF without Spring
  • It's not a web app, so I don't have the WEB-INF folder with the web.xml
  • I test the service using SoapUI and Postman (Google Chrome application)

With the following code, I get WARNING: javax.ws.rs.BadRequestException: HTTP 400 Bad Request:

DemoService.java

@WebService(targetNamespace = "http://demoservice.com")@Path("/demoService")public interface DemoService {    @POST    @Path("/test")    @Produces(MediaType.APPLICATION_JSON)    @Consumes(MediaType.APPLICATION_JSON)    public String test (String message, int value);}

DemoServiceImpl.java

public class DemoServiceImpl implements DemoService {    @Override    public String test(String message, int value) {        return "test message: "+ message +" value =  : "+ value;    }}

DemoServer.java

public class DemoServer{    public static void main(String[] args) {        JAXRSServerFactoryBean serverFactory = new JAXRSServerFactoryBean();        DemoService demoService = new DemoServiceImpl();        serverFactory.setServiceBean(demoService);        serverFactory.setAddress("http://localhost:9090");        serverFactory.create();    }}

My POM.xml (minus the attributes in the root tag, everything's there)

<project ...><modelVersion>4.0.0</modelVersion><groupId>demo</groupId><artifactId>demoService</artifactId><version>1.0-SNAPSHOT</version><properties><cxf.version>3.0.0</cxf.version></properties><dependencies><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>${cxf.version}</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxrs</artifactId><version>${cxf.version}</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>${cxf.version}</version></dependency><!-- Jetty is needed if you're are not using the CXFServlet --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http-jetty</artifactId><version>${cxf.version}</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-rs-service-description</artifactId><version>3.0.0-milestone1</version></dependency></dependencies></project>

Testing with {"message":"hello there!", "value":"50"} to the URL http://localhost:9090/demoService/test gave a HTTP 400 Bad Reuest.

Then I saw this question on S.O.: How to access parameters in a RESTful POST method and tried this:

added the following nested class in DemoServer.java:

    @XmlRootElement    public static class TestRequest {        private String message;        private int value;        public String getMessage() { return message; }        public void setMessage(String message) { this.message = message; }        public int getValue() { return value; }        public void setValue(int value) { this.value = value; }    }

I also modified the DemoService interface and the implementation to use this class as a parameter in the test method, although this is still ultimately not what I want to do. (just showing the implementation here, question's already getting long):

@Overridepublic String test(TestRequest testRequest) {    String message = testRequest.getMessage();    int value = testRequest.getValue();    return "test message: "+ message +" value =  : "+ value;}

And to fix this error that I got: SEVERE: No message body reader has been found for class DemoService$TestRequest, ContentType: application/json (in Postman I see error 415 - unsupported media type) I added the following dependencies (jettison and another thing) to the POM.xml:

<dependency><groupId>org.codehaus.jettison</groupId><artifactId>jettison</artifactId><version>1.3.5</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-rs-extension-providers</artifactId><version>2.6.0</version></dependency>

I tested the service using the following JSON message, in a HTTP POST request:

{"testRequest":{"message":"hello there!", "value":"50"}}

This works. Though this solution where I use a TestRequest class to encapsulate the parameters works, that's not the solution I'm looking for. I want to be able to pass the two parameters in a JSON message, without having to introduce this TestRequest class (explicitly).

Questions:

  • Would this be easier to implement using Jersey?
  • I don't have a web.xml nor a WEB-INF folder, so I can't configure CXF in a cxf.xml file can I? A lot of tutorials online seem ot use a lot of XML configuration, but I don't want to deploy a framework like TomEE or Spring or Glassfish just to do that.
  • Searching online for solutions, I came across Spring Boot. Would you recommend using that, perhaps? Would that make developing web services like this easier?
  • Also, how do I get it to return the value in JSON format (or is it not supposed to do that for Strings?)

Viewing all articles
Browse latest Browse all 4807

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>