Search code examples
javajsonrestjerseypojo

Unable to send JSON object to Rest web service


I have a REST web servce configure as the following:

@Path("/users")
public class UserManager {

@Context
UriInfo uriInfo;

@POST
@Consumes("application/json")
public void createUser(User user) {
    URI uri = uriInfo.getAbsolutePathBuilder().path(user.getUserName())
            .build();
    Response res = Response.created(uri).build();
    try {
        MongoDbDataAccess.getInstance().addUser(user);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

And My Tomcat server configure as the following:

<servlet>
  <servlet-name>Jersey REST Service</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
   <param-name>com.sun.jersey.config.property.packages</param-name>
   <param-value>anyq.server.anyq.manager</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
   <servlet-name>Jersey REST Service</servlet-name>
   <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

The POJO I create look like the following:

@XmlRootElement
public class User {

private long userId;
private String userName;
private String userPassword;

public User() {
    super();
}

public User(long userId, String userName, String userPassword) {
    super();
    this.userId = userId;
    this.userName = userName;
    this.userPassword = userPassword;
}

public long getUserId() {
    return userId;
}

public void setUserId(long userId) {
    this.userId = userId;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getUserPassword() {
    return userPassword;
}

public void setUserPassword(String userPassword) {
    this.userPassword = userPassword;
}

}

I create the a test client in order to test the createUser method:

public class tester {

public static void main(String[] args) throws UnknownHostException {

    String USER_URI = "http://localhost:8080/AnyAppserver/rest/users";
    User user = new User((long) 451, "mosssi", "464asd64");

    Client client = Client.create();

    WebResource r = client.resource(USER_URI);

    ClientResponse response = r.accept(MediaType.APPLICATION_JSON).post(
            ClientResponse.class, user);


}

But I get the following error:

POST http://localhost:8080/AnyAppserver/rest/users returned a response status of 415 Unsupported Media Type

The wierd issue is when I change everything to appliction/xml it work perfectly

Any Idea why Json doesnt work for me?


Solution

  • You are doing:

    User user = new User((long) 451, "mosssi", "464asd64");
    
    ClientResponse response = r.accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, user);
    

    It's wrong. You should send to your service a real JSON String.

    Get JSON parser, for example: gson, and do this:

    User user = new User(451, "mosssi", "464asd64");
    String request = gson.toJson(user);
    ClientResponse response = r.type(MediaType.APPLICATION_JSON).post(ClientResponse.class, request );
    

    Don't use old Jersey-bundle library. Download 2.0 version: https://jersey.java.net/download.html

    add all libs (lib and ext libraries) to your classpath.

    Next, you need the jackson packages in your classpath: jackson-annotations-2.2.2.jar jackson-core-2.2.2.jar jackson-databind-2.2.2.jar jackson-jaxrs-base-2.2.1.jar jackson-jaxrs-json-provider-2.2.1.jar jackson-module-jaxb-annotations-2.2.2.jar

    Your service class should be similiar to this:

    package anyq.server.anyq.manager;
    
    import javax.ws.rs.Consumes;
    import javax.ws.rs.POST;
    import javax.ws.rs.Path;
    import javax.ws.rs.core.Context;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    import javax.ws.rs.core.UriInfo;
    
    import anyq.server.common.bean.User;
    
    @Path("/users")
    public class AnyQUserManager {
    
    @Context
    UriInfo uriInfo;
    
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createUser(User user) {
        System.out.println("HELLO WORLD");
        return Response.status(666).entity("Hello world").build();
    }
    }
    

    And, finaly, your web.xml should look like:

    <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
    
    <servlet>
        <servlet-name>Jersey REST Service</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>anyq.server.anyq.manager, com.fasterxml.jackson.jaxrs.json</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>Jersey REST Service</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    

    In your client class, do this:

        String USER_URI = "http://localhost:8080/AnyQserver/rest/users";
        User user = new anyq.server.common.bean.User();
        user.setUserId(15);
        user.setUserName("asd");
        user.setUserPassword("asd");
    
        Client client = Client.create();
        String request = new Gson().toJson(user);
        System.out.println(request);
        WebResource r = client.resource(USER_URI);
        ClientResponse response = r.type(MediaType.APPLICATION_JSON).post(
                ClientResponse.class, request);
        System.out.println(response.getStatus());
    

    Restart server and run client. If everything went fine, server should print:

    INFO: Server startup in 2256 ms
    HELLO WORLD
    

    and client:

    {"userId":15,"userName":"asd","userPassword":"asd"}
    666
    

    Good luck!

    Also, I really sugest you to migrate to maven.