简体   繁体   中英

Why am I getting a 500 response for my POST on my Jersey REST API?

I have just begun implementing my first Drowizard project. Here's my first resource class:

@Path("/bill")
public class CommandResource {
    //...

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/createBillForStudy")
    public Response handleCreateBillForStudyCommand(CreateBillForStudyCommand cmd, @Context UriInfo uriInfo)
    {
        System.out.println("Creating bill for command: " + cmd);

        UUID newId = billCreator.handle(cmd);

        URI location = uriInfo.getBaseUriBuilder().path(CommandResource.class).path("/" + newId).build();

        return Response.accepted(cmd).contentLocation(location).build();
    }
}

I want to test this using Postman, but the following request leads to a 500 response and I can't figure out why:

POST /bill/createBillForStudy HTTP/1.1
Host: localhost:8080
Content-Type: application/JSON
Cache-Control: no-cache

{ "idAccount": "123", "idStudy": "456", "timeStamp": "2014-01-01" }

This is what I see in the Dropwizard console:

ERROR [2015-05-07 16:43:08,558] org.glassfish.jersey.message.internal.WriterInterceptorExecutor: MessageBodyWriter not found for media type=application/xml, type=class com.statista.billing.domain.commands.CreateBillForStudyCommand, genericType=class com.statista.billing.domain.commands.CreateBillForStudyCommand.
0:0:0:0:0:0:0:1 - - [07/Mai/2015:16:43:08 +0000] "POST /bill/createBillForStudy/ HTTP/1.1" 500 332 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36" 8

To me this sounds as if the Content-Type header is wring or missing, but as you can see above, it's correctly set to "application/JSON".

Any ideas?

Response.accepted(Object) . This will return the representation to the client. In order to determine the Content-Type of the response, we need to specify it, it it should be specified by the Accept request header.

If you are going to return a representation, you should always make sure to specify the formats supported, using the @Produces annotation. If you wan to return JSON (the same way you are accepting JSON, then just use

@Produces(MediaType.APPLICATION_JSON)

The current problem is that the response is trying to me marshalled to the XML, as specified by the error

MessageBodyWriter not found for media type=application/xml, 
          type=class com.s.b.d.c.CreateBillForStudyCommand

It's default to XMl, since you haven't specified in a @Produces or the client set no Accept header. If there was an Accept: application/json , then without the @Produces , it would look for the MessageBodyWriter to handle JSON.

As an aside...

accepted ( 202 Accepted ) means

The request has been accepted for processing, but the processing has not been completed.

You should instead use created (201 Created):

The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field.

With created , you don't need to explicitly call location , the URI you pass to the method will be set as the Location header. If you want to add a body, you can chain entity(body)


Edit:

Also if you don't want to send a representation in the response, you can simple call the no-arg accepted() method. This will not send out a response body, and you should no longer get the exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM