简体   繁体   English

RESTful WS-Jersey-客户端解组问题

[英]RESTful WS - Jersey - client side unmarshalling issue

I am trying to call a REST WS which I built myself. 我试图调用我自己构建的REST WS。 Below is my code on the client side. 下面是我在客户端的代码。 On the server side this call completes fine, I can see the arguments which I want to see in the debugger. 在服务器端,此调用可以正常完成,我可以在调试器中看到要查看的参数。 The method is POST, has an XML argument, returns JSON. 方法为POST,具有XML参数,返回JSON。 I am using Java and Jersey. 我正在使用Java和Jersey。

I am using this version of Jersey: jersey-client-1.0.3.jar jersey-core-1.0.3.jar jersey-json-1.0.3.jar jersey-server-1.0.3.jar 我正在使用以下版本的Jersey:jersey-client-1.0.3.jar jersey-core-1.0.3.jar jersey-json-1.0.3.jar jersey-server-1.0.3.jar

I cannot upgrade that easily, it's not up to me. 我无法轻松升级,这不取决于我。

package com.company.module.test;

import java.net.URI;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.company.common.DateUtil;
import com.company.module.input.AssetOperation;
import com.company.module.input.AssetOperationData;

public class MainProg002 {

    public static void main(String[] args) throws Exception {
        ClientConfig config = new DefaultClientConfig();
        Client client = Client.create(config);
        WebResource service = client.resource(getBaseURI());

        AssetOperationData data = new AssetOperationData();
        AssetOperation op1 = new AssetOperation();
        op1.setAssetID("1234");
        op1.setDate(DateUtil.getDate(2013, 12, 22));
        op1.setOperation("pause");
        AssetOperation op2 = new AssetOperation();
        op2.setAssetID("5050");
        op2.setDate(DateUtil.getDate(2013, 12, 5));
        op2.setOperation("resume");
        data.getAssetOperations().add(op1);
        data.getAssetOperations().add(op2);

        service.path("Asset").entity(data, MediaType.APPLICATION_XML).post(AssetOperationData.class, data);
    }

    private static URI getBaseURI() {
        return UriBuilder.fromUri("http://localhost:8080/module/service").build();
    }
}

Seems to me the problem is then that the client cannot unmarshal some objects properly on the client side. 在我看来,问题在于客户端无法正确地在客户端解组某些对象。 Below is the exception which I get. 以下是我得到的例外。 I think it has something to do with element namespaces in XSD?! 我认为这与XSD中的元素名称空间有关? I have no idea how to tell the client to use a particular XSD. 我不知道如何告诉客户端使用特定的XSD。 Also, I am not sure if that's needed at all, because the RESTful service returns JSON in this case. 另外,我不确定是否完全需要这样做,因为在这种情况下,RESTful服务将返回JSON。 Also I am puzzled by the fact that the exception mentiones "input" which is an element from the arguments, not from the return values?! 我也对异常提到“输入”感到困惑,因为“输入”是参数中的一个元素,而不是返回值中的一个元素?

Exception in thread "main" javax.ws.rs.WebApplicationException: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"input"). Expected elements are <{http://company.com/module/input}input>]
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:99)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:259)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:220)
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:561)
    at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69)
    at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:499)
    at com.company.module.test.MainProg002.main(MainProg002.java:36)
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"input"). Expected elements are <{http://company.com/module/input}input>]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:435)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:372)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:342)
    at com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider.readFrom(JSONRootElementProvider.java:110)
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:97)
    ... 6 more
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"input"). Expected elements are <{http://company.com/module/input}input>
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:253)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:120)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1063)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:498)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480)
    at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:75)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:246)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:180)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:370)
    ... 9 more
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"input"). Expected elements are <{http://company.com/module/input}input>
    ... 20 more
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8

I would be very thankful to any help. 我将非常感谢您的帮助。

On the client side: 在客户端:

1 * Out-bound request
1 > POST http://localhost:8080/module/service/Asset
1 > Content-Type: application/xml
1 > 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><input xmlns="http://company.com/module/input"><item><assetID>1234</assetID><date>2014-01-22-05:00</date><operation>pause</operation></item><item><assetID>5050</assetID><date>2014-01-05-05:00</date><operation>resume</operation></item></input>
1 < 200
1 < Transfer-Encoding: chunked
1 < Content-Type: application/json
1 < Server: Apache-Coyote/1.1
1 < Date: Sat, 09 Nov 2013 20:23:22 GMT
1 < 
{"error":"","id":"10"}
1 * In-bound response

This is how my method looks like. 这就是我的方法的样子。

@POST
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_JSON)
public AssetResult manageAssets(AssetOperationData data) {
    LogProvider.logInfo(this, "BEGIN");
    LogProvider.logInfo(this, "Found POST data = " + data);
    AssetResult result = new AssetResult();
    result.setId(10);
    LogProvider.logInfo(this, "END");
    return result;
}

I finally returned JSON from the method and slightly changed the client. 我最终从该方法返回了JSON,并稍微更改了客户端。 Below is a client which finally works. 下面是一个最终可以工作的客户。 The key points are two. 关键是两个。 1) Post with String.class; 1)用String.class发布; 2) Use Gson and unmarshal the returned AssetResult object on the client side with Gson. 2)使用Gson并与Gson在客户端解组返回的AssetResult对象。

package com.company.module.test;

import java.net.URI;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;

import com.google.gson.Gson;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.LoggingFilter;
import com.company.common.DateUtil;
import com.company.module.input.AssetOperation;
import com.company.module.input.AssetOperationData;
import com.company.module.result.AssetResult;

public class MainProg002 {

    public static void main(String[] args) throws Exception {
        ClientConfig config = new DefaultClientConfig();
        Client client = Client.create(config);
        client.addFilter(new LoggingFilter());

        WebResource service = client.resource(getBaseURI());

        AssetOperationData data = new AssetOperationData();
        AssetOperation op1 = new AssetOperation();
        op1.setAssetID("1234");
        op1.setDate(DateUtil.getDate(2013, 12, 22));
        op1.setOperation("pause");
        AssetOperation op2 = new AssetOperation();
        op2.setAssetID("5050");
        op2.setDate(DateUtil.getDate(2013, 12, 5));
        op2.setOperation("resume");
        data.getAssetOperations().add(op1);
        data.getAssetOperations().add(op2);

        String res = service.path("Asset").entity(data, MediaType.APPLICATION_XML).accept(MediaType.APPLICATION_JSON).post(String.class);
        Gson gson = new Gson();
        AssetResult result = gson.fromJson(res, AssetResult.class);

        System.out.println("DONE!");
    }

    private static URI getBaseURI() {
        return UriBuilder.fromUri("http://localhost:8080/module/service").build();
    }
}

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

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