简体   繁体   English

使用JAXB在Jersey中解析JSON

[英]Using JAXB to parse JSON in Jersey

I'm trying to create a very simple RESTful web service using Jersey. 我正在尝试使用Jersey创建一个非常简单的RESTful Web服务。 I'm trying to make it so that it consumes and produces a JSON by using JAXB. 我正在尝试使其通过使用JAXB消耗并产生JSON。 The problem is that I get an error when I pass a JSON to it. 问题是当我向其传递JSON时出现错误。

Below is the resource code. 下面是资源代码。 Both status() and echo() are working properly. status()和echo()均正常工作。 Please note that on processRequest() I'm currently producing a text response, but that will be changed later to produce a JSON. 请注意,在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;
    }
}

This is the Request model: 这是请求模型:

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
}

My web.xml: 我的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>

Finally, this is an example of the POST that I'm doing (headers set to 'Content-Type: application/json'); 最后,这是我正在执行的POST的示例(标头设置为“ Content-Type:application / json”);

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

When I run this, Tomcat gives me the following Exception: 当我运行它时,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.

And I get the following response: 我得到以下回应:

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

在此处输入图片说明

I'm very new to this and this is not making a lot of sense. 我对此很陌生,这没有什么意义。 Hopefully, one of you will be able to give me a hand. 希望你们中的一个能够帮上我的忙。 Thanks! 谢谢!

Try this in your endpoint: 在端点中尝试以下操作:

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

where Coordinates is a simple POJO mirroring the JSON content you are posting. 其中, Coordinates是一个简单的POJO,用于镜像您发布的JSON内容。

Then use Jackson, which has JAXB support, by adding all the libraries to your project and adding this configuration: 然后,通过将所有库添加到项目中并添加以下配置,使用具有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>

to the "Jersey REST Service" servlet. 到“ Jersey REST服务” servlet。

JAXB (Java Architecture for XML Binding) avaialable in java for binding xml not for JSON .Here you are trying to convert JavaScript Object Notation with the help of xml binder in this situation and that is not possible. JAXB (用于XML绑定的Java体系结构)可用于Java而不是用于JSONxml绑定。在这种情况下,您正在尝试借助xml绑定器转换JavaScript对象表示法 ,这是不可能的。 And i am pretty sure that you must be getting the error generated by " BodyWriter class " in the JAX-RS package.... 而且我很确定您一定会收到JAX-RS软件包中“ BodyWriter class ”生成的错误。

Anyway If you want to produce and consume JSON using your resource you gonna need " moxy " JAR available in your project library for handing this conversion :) 无论如何,如果您想使用资源来生成和使用JSON,则需要在项目库中使用“ moxy ” JAR来进行此转换:)

Hope what i am writing here will be helpful for other programmers 希望我在这里写的内容对其他程序员有帮助

this error happends when you are requesting without specified headers. 当您在没有指定标题的情况下进行请求时,会发生此错误。 In your service @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) 在您的服务中@Consumes(MediaType.APPLICATION_JSON)@Produces(MediaType.TEXT_PLAIN)

Ensure that your request gets the header "content-type" ? 确保您的请求获取标头“ content-type”? application/json and the header "accept" contains text/html application / json和标头“ accept”包含text / html

I think, there is problem with your Request model class. 我认为您的Request模型类存在问题。 Your model class is not specifying @XmlaccessType, so by default it is being considered as PUBLIC_MEMBER. 您的模型类未指定@XmlaccessType,因此默认情况下将其视为PUBLIC_MEMBER。 As your instance variables are also public along with getters and setters, So JAXB is not able to figure out proper bindings.That's why that exception is coming. 由于您的实例变量也与getter和setter一起公开,因此JAXB无法找出适当的绑定,这就是该异常发生的原因。 So there are two fixes to your problem. 因此,针对您的问题有两种解决方法。

1)You can make your instance variables as private. 1)您可以将实例变量设为私有。 2)Or you can explicitly specify @XmlaccessType for your model class and likewise provide annotations in it which are non-conflicting. 2)或者,您可以为模型类明确指定@XmlaccessType,并在其中提供不冲突的注释。

Add this to your web.xml 将此添加到您的web.xml

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

For more details look at jersey documentation : https://jersey.java.net/documentation/1.18/json.html 有关更多详细信息,请参阅球衣文档: https : //jersey.java.net/documentation/1.18/json.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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