[英]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。 (盡管從未嘗試過,所以您的里程可能會有所不同:)
可能有兩個問題:
確保在處理此請求的REST Web服務方法之上設置了消費注釋:@Consumes(MediaType.APPLICATION_XML)
其次,您的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.