为什么我的Jersey REST API上的POST响应为500?

时间:2015-05-07 16:52:08

标签: java jersey dropwizard postman

我刚刚开始实施我的第一个Drowizard项目。这是我的第一个资源类:

@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();
    }
}

我想使用Postman对此进行测试,但以下请求导致500响应,我无法弄清楚原因:

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" }

这是我在Dropwizard控制台中看到的:

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

对我而言,这听起来就好像Content-Type标题正在变形或丢失,但正如您在上面所看到的,它被正确设置为“application / JSON”。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

Response.accepted(Object)。这会将表示返回给客户端。为了确定响应的Content-Type,我们需要指定它,它应该由Accept请求标头指定。

如果要返回表示,则应始终确保使用@Produces注释指定支持的格式。如果您想返回JSON(与接受JSON的方式相同,那么只需使用

@Produces(MediaType.APPLICATION_JSON)

当前的问题是响应正在尝试按照错误的指定编组到XML

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

默认为XMl,因为您尚未在@Produces中指定或客户端未设置Accept标头。如果有Accept: application/json,那么没有@Produces,它会查找MessageBodyWriter来处理JSON。

暂且不说......

accepted202 Accepted)表示

  

请求已被接受处理,但处理尚未完成。

您应该使用created(201 Created):

  

请求已完成,并导致创建新资源。新创建的资源可以由响应实体中返回的URI引用,其中包含Location头字段给出的资源的最具体URI。

使用created,您不需要明确调用location,您传递给该方法的URI将被设置为Location标头。如果要添加正文,可以链接entity(body)

编辑:

此外,如果您不想在响应中发送表示,则可以简单地调用no-arg accepted()方法。这不会发出响应正文,你不应该再得到异常。