3

I want to create a rest api that get json data and send json data.

My Book class :

@Entity
public class Book {

    @Id
    private String isbn;

    public Book() {
        
    }
......
}

My Book service :

@Path("/books")
public class BookService {

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response buyBook(Book book){
        String isbn = book.getIsbn();
        int number = book.getStock();
   
        return Response.status(Response.Status.OK).entity("OK").build();
    }
......
}

When I try to post this with POSTMAN :

POST /books HTTP/1.1    
Host: localhost:5000    
Content-Type: application/json    
Cache-Control: no-cache    
Postman-Token: 3099cd3a-184a-e442-270a-c118930df2b5    

{    
    "isbn" : "",    
    "title" : "",    
    "author" : "",    
    "stock" : "2"    
}        

My rest API send me this response :

HTTP ERROR 415
Problem accessing /books. Reason:
Unsupported Media Type

EDIT: (with pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>wholesalerservice</groupId>
  <version>1.0-SNAPSHOT</version>
  <artifactId>wholesalerservice</artifactId>
  <dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.17</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>9.2.10.v20150310</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-webapp</artifactId>
        <version>9.2.10.v20150310</version>
    </dependency>
 
    <dependency>
      <groupId>javax.ws.rs</groupId>
      <artifactId>javax.ws.rs-api</artifactId>
      <version>2.0.1</version>
      <scope>provided</scope>
    </dependency>
   
    <dependency>
        <groupId>org.hibernate.ogm</groupId>
        <artifactId>hibernate-ogm-mongodb</artifactId>
        <version>4.1.3.Final</version>
    </dependency>
 
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>persistence-api</artifactId>
        <version>1.0.2</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>eclipselink</artifactId>
      <version>2.5.2</version>
    </dependency>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.6</version>
      <type>jar</type>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.4</version>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals><goal>copy-dependencies</goal></goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>
    <name>WholesalerService</name>
</project>
Community
  • 1
  • 1
damien marchand
  • 864
  • 1
  • 13
  • 30
  • `Book` does not have members `title`, `author`, and `stock`. –  May 02 '15 at 17:25
  • 1
    Try to add @BeanParam before 'Book book' in your 'buyBook' method. – Rafal G. May 02 '15 at 18:23
  • I added @BeanParam and I have a new error : Could not send response error 500: javax.servlet.ServletException: java.lang.IllegalArgumentException: id to load is required for loading. My request is : { "isbn" : "456", "title" : "", "author" : "", "stock" : "2" } – damien marchand May 02 '15 at 21:24

2 Answers2

2

So in order to use JSON to POJO conversion for entity bodies, we need to have a MessageBodyReader (sometimes referred to as providers) to handle the conversion. With Java, Jackson has been the de-facto JSON library for a while, and they offer a module with JAX-RS support, which is the one pointed out by @Nico Müller

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.5.3</version>
</dependency>

The problem with this is that if we don't configure/register it, the only way it will be discovered is by classpath scanning, which most Jersey applications don't depend on. Instead Jersey offers a wrapper module around this artifacts which wraps it in an auto-discoverable feature (version 2.9+), so we don't need to configure it

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey2.version}</version> <!-- 2.17 latest as of now -->
</dependency>

If you are using Jersey prior to 2.9, you can always register the feature in your application class

@ApplicationPath("/api")
public class AppConfig extends ResourceConfig {
    public AppConfig() {
        packages("...");
        register(JacksonFeature.class);
    }
}

Or in a web.xml register the feature as a provider class

<init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>
        org.glassfish.jersey.jackson.JacksonFeature
    </param-value>
</init-param>
Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
1

Did you include the jackson-jaxrs-json-provider in your project?

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.5.3</version>
</dependency>

In general: Your Book service is missing title, author and stock which you are trying to post.

Nico Müller
  • 1,784
  • 1
  • 17
  • 37
  • Are you sure this is causing the 415? –  May 02 '15 at 17:41
  • I think this could be the reason (and can be easily tested by dm_fr) as the 415 Error(quoted): The Web server (running the Web site) thinks that the HTTP data stream sent by the client identifies a URL resource whose actual media type 1) does not agree with the media type specified on the request or 2) is incompatible with the current data for the resource or 3) is incompatible with the HTTP method specified on the request. – Nico Müller May 02 '15 at 17:44
  • Yes, that's the HTTP spec. Did you test if this is what happens when you use JAX-RS? It *could* be the correct answer but maybe the problem lies somewhere else. –  May 02 '15 at 17:45
  • I think we need to know the dependencies. – Nico Müller May 02 '15 at 17:51
  • Put this as a comment on the question. –  May 02 '15 at 17:52
  • my pom.xml file : http://pastebin.com/Uf7Sx3Bu . If I add title author and stock in my json nothing change. – damien marchand May 02 '15 at 21:28
  • can you give it a try adding the json provider dependency? – Nico Müller May 02 '15 at 21:31
  • Add jackson-jaxrs-json-provider does not change anything. – damien marchand May 02 '15 at 21:35
  • and did you try removing the fields from the post that you are not having specified? title, author and stock – Nico Müller May 02 '15 at 21:37
  • I added title author and stock in my Book class. Dt does not change anything. – damien marchand May 02 '15 at 21:47
  • If you do not have a provider to handle JSON to POJO (vice-versa), yes it will cause a 415. Any problem deserializing will cause a 400. So to the OP, if you didn't have a provider initially, then yes, adding a provider is necessary. But it still needs to be configured (depending on the dependency). This particular dependency still needs to be configured. If you are using web.xml for configuration, just add the Jackson package into the list of provider packages `com.fasterxml.jackson.jaxrs.json` (separated by comma with _your_ package). If you still need help, post4 your configuration file – Paul Samsotha May 02 '15 at 23:16
  • 2
    @dm_fr after looking at your pom, yes you are missing a provider. But instead of the one this answer suggest, use [this one](https://jersey.java.net/documentation/latest/media.html#json.jackson) (the first). This needs no extra configuration. It actually wraps the dependency (the above answer provides) so that we don't need to configure it – Paul Samsotha May 02 '15 at 23:30
  • @peeskillet I am working with dm_fr on this project, and i'm really glad you found the answer. Could you please post an answer, so dm_fr can accept it ? (for future users with same problem). – Yoluk May 03 '15 at 13:23