簡體   English   中英

使用澤西(Jersey)開機自檢以服務-“未找到消息正文編寫器...”

[英]Using Jersey to POST to service - “A message body writer … was not found”

我已經使用Java / Jersey編寫了用於管理訂戶的基本RESTful服務,現在我正試圖創建一個客戶端來與該服務進行通信,但是卻遇到了我不理解的運行時錯誤。 這是出現問題的精簡版本:

訂戶類別:

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Subscriber {

    private String firstName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Subscriber() {
    }

}

主要測試應用:

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;

public class MyTestClient {

    public static void main(String[] args) {
        ClientConfig config = new DefaultClientConfig();
        Client client = Client.create(config);
        WebResource service = client.resource(UriBuilder.fromUri("http://localhost:8080/MyService").build());

        Subscriber s = new Subscriber() {{
            setFirstName("John");
            setLastName("Doe");
        }};

        System.out.println(service.path("subscriber")
                .type(MediaType.APPLICATION_XML)
                .entity(s)
                .post(String.class));
    }
}

我得到這個錯誤:

Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type, class MyTestClient$1, and MIME media type, application/xml, was not found

我不清楚這個錯誤消息的確切含義。 這似乎與訂閱者向XML的轉換有關(盡管對我來說,錯誤消息表明它正在嘗試轉換MyTestClient,這是不對的……)我在其中使用了相同的Subscriber類我的服務,創建XML發送到客戶端沒有問題,所以我很困惑。

如果我用包含XML的字符串替換Subscriber對象,則不會收到錯誤消息,但是由於許多原因,我想使用對象。

該錯誤消息的原因是什么,如何解決?

編輯:供參考,盡管我不確定它是否相關,但是這是代碼服務端的相關部分:

@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Subscriber post(Subscriber subscriber) {
          /// doesn't get here
    }

同樣,這可行,但是不使用Subscriber對象:

    String xml = "<subscriber><firstName>John</firstName><lastName>Doe</lastName></subscriber>";

    System.out.println(service.path("subscriber")
                .type(MediaType.APPLICATION_XML)
                .entity(xml)
                .post(String.class));

更新:我可以通過將對象首先顯式轉換為字符串來解決此問題,因此:

JAXBContext context = JAXBContext.newInstance(Subscriber.class);
Marshaller m = context.createMarshaller();
StringWriter sw = new StringWriter();
m.marshal(s, sw);
String xml = sw.toString();

System.out.println(service.path("subscriber")
.type(MediaType.APPLICATION_XML)
.entity(xml)
.post(String.class));

但這很混亂,我不明白為什么要這樣做。

錯誤“ Java類型的消息正文編寫器,類MyTestClient $ 1”報告它正在嘗試編組匿名內部類。 我們通常希望看到“類訂戶”。 執行此新的Subscriber(){{}}時,您可能會失去JAXB批注。

我的第一個建議是將名稱傳遞給構造器,該構造器將更清潔並且不會使您失去JAXB批注。

Subscriber s = new Subscriber("John","Doe");

或調用默認構造函數,然后再設置字段:

Subscriber s = new Subscriber();
s.setFirstName("John");
s.setLastName("Doe");

如果需要定義匿名內部類,則可以嘗試在新的匿名類定義之前重新注釋@XmlRootElement。 (盡管從未嘗試過,所以您的里程可能會有所不同:)

可能有兩個問題:

  1. 確保在處理此請求的REST Web服務方法之上設置了消費注釋:@Consumes(MediaType.APPLICATION_XML)

  2. 其次,您的bean似乎缺少getter上的注釋。 這是您的udpated豆:

@XmlRootElement公共類訂戶{

private String firstName;
private String lastName;

@XmlElement (name = "firstName")
public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

@XmlElement (name = "lastName")
public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public Subscriber() {
}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM