使用JAXB解析Jersey中的JSON

时间:2013-11-04 23:16:55

标签: java json rest jaxb jersey

我尝试使用Jersey创建一个非常简单的RESTful Web服务。我试图通过使用JAXB来消费并生成JSON。问题是当我向其传递JSON时出现错误。

以下是资源代码。 status()和echo()都正常工作。请注意,在processRequest()上,我目前正在生成文本响应,但稍后会更改以生成JSON。

package web_service;

import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("/")
public class WebService {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String status() {
        return "Web service is up and running.";
    }

    @POST
    @Consumes(MediaType.TEXT_PLAIN)
    @Produces(MediaType.TEXT_PLAIN)
    public String echo(String consumed) {
        return consumed;
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_PLAIN)
    public String processRequest(JAXBElement<Request> r) {
        Request request = r.getValue();
        return "Latitude: " + request.latitude +
            "\n:Longitude: " + request.longitude;
    }
}

这是请求模型:

package web_service;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Request {

    public String latitude;
    public String longitude;

    public Request() {}

    public Request(String latitude, String longitude) {
        this.latitude = latitude;
        this.longitude = longitude;
    }

    // Getters and setters for both
}

我的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    id="WebApp_ID" 
    version="2.5">

     <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>web_service</param-value>
         </init-param>

         <load-on-startup>1</load-on-startup>
    </servlet>

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

最后,这是我正在进行的POST的示例(标题设置为&#39; Content-Type:application / json&#39;);

{
    "latitude":"25.764084501106787",
    "longitude":"-80.37422332275389"
}

当我运行它时,Tomcat给了我以下异常:

WARNING: WebApplicationException cause:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=class web_service.Request, genericType=class     web_service.Request.

我收到以下回复:

415 Unsupported Media Type

Content-Length: 1 kB
Content-Type:   text/html;charset=utf-8
Date:           2013 Nov 4 17:41:20
Server:         Apache-Coyote/1.1

enter image description here

我对此非常陌生,这并没有多大意义。希望你们中的一个能够帮助我。谢谢!

5 个答案:

答案 0 :(得分:1)

在您的终端中尝试此操作:

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public String processRequest(Coordinates coordinates) {
    return "Latitude: " + coordinates.getLatitude() +
        "\n:Longitude: " + coordinates.getLongitude();
}

其中Coordinates是一个简单的POJO镜像您发布的JSON内容。

然后使用具有JAXB支持的Jackson,将所有库添加到项目中并添加此配置:

<init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>org.foobar.rest.services;org.codehaus.jackson.jaxrs</param-value>   
</init-param>

到“Jersey REST Service”servlet。

答案 1 :(得分:1)

JAXB (用于XML绑定的Java体系结构)在java中可用于绑定xml而不是用于 JSON 。您试图转换 JavaScript Object Notation 在这种情况下,在 xml binder 的帮助下,这是不可能的。而且我很确定您必须在JAX-RS包中获得由“ BodyWriter类”生成的错误....

无论如何如果您想使用您的资源生成和使用JSON,您需要在项目库中使用“ moxy ”JAR来处理此转换:)

希望我在这里写的内容对其他程序员有用

答案 2 :(得分:0)

当您请求没有指定标头时,会发生此错误。 在您的服务中 @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN)

确保您的请求获得标题“content-type”? application / json和标题“accept”包含text / html

答案 3 :(得分:0)

我认为,您的Request模型类存在问题。您的模型类未指定@XmlaccessType,因此默认情况下它被视为PUBLIC_MEMBER。由于您的实例变量也是公共的以及getter和setter,因此JAXB无法找出正确的绑定。这就是异常即将到来的原因。所以你的问题有两个修复。

1)您可以将实例变量设为私有。 2)或者您可以为您的模型类显式指定@XmlaccessType,同样在其中提供非冲突的注释。

答案 4 :(得分:0)

将此添加到您的web.xml

<init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

有关详细信息,请查看泽西文档:https://jersey.java.net/documentation/1.18/json.html