对于我的REST服务中的订购流程,我必须从客户端向服务器发送“文章”列表.这些文章对象属于自制实体类型.我已经发现发送STRING或INTEGER对象列表确实有效,通过@FormParam发送它.
但是一旦我尝试发送我自己的对象列表(甚至只有一个对象),我总是得到HTTP 400错误“错误请求”.
我尝试了像下面这样相同的代码(只有form.add()的参数和服务器方法的参数被更改)和postet字符串,整数和字符串列表成功.它只会让问题发送自己的对象类型.
记录告诉我没有达到服务器方法.这个过程在某个地方被打破了.
我还试图通过使用代理(Apache JMeter)来获取请求.这里它表示参数kunde包含值entities.Kunde@af8358.所以我猜这个对象没有彻底序列化(或根本没有).但是在响应中将这种对象从服务器发送到客户端工作正常 – 这里XML序列化没有问题.
可能是什么原因?是否可能无法通过POST发送自己的类型?
(PS:Kundein类型我的例子是可序列化的,并用@XmlRootElement注释.)
预先感谢您的帮助!
贾纳
注意:我正在使用SAP Netweaver AS.但直到现在它的表现与其他所有Java AS一样,所以我认为这不是原因.每个其他REST操作都可以工作,甚至没有自己的实体的POST.
另外:我正在使用JERSEY库.
服务器端的我的代码:
@Path("/test")
@POST
@Produces(MediaType.TEXT_XML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String test(
@FormParam("kunde") Kunde kunde) {
return "The name of the customer is: "
+kunde.getVorname()+" "+kunde.getNachname();
}
我在客户端的代码(该方法在会话Bean中):
public String test() {
Kunde kunde = new Kunde();
kunde.setNachname("Müller");
kunde.setVorname("Kurt");
Form form = new Form();
form.add("kunde", kunde);
return service
.path("test")
.type(MediaType.APPLICATION_FORM_URLENCODED)
.accept(MediaType.TEXT_XML)
.post(String.class, form);
}
服务的构建方式如下:
com.sun.jersey.api.client.Client;
com.sun.jersey.api.client.WebResource;
com.sun.jersey.api.client.config.ClientConfig;
com.sun.jersey.api.client.config.DefaultClientConfig;
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
service = client.resource(UriBuilder.fromUri("<service-url>").build());
最佳答案 由于新的信息,实体“昆德”没有正确传输我发现了一个
解:
我明确地将实体类转换为XML / JSON(无论哪种方式都在工作)并将XML / JSON作为String放在表单中.在服务器端,我将XML / JSON字符串转换回实体,这很有用.
(似乎不可能传输一个不是字符串或整数的对象.)
希望这将帮助每个面临同样问题的人通过REST将对象从客户端传输到服务器.
(发送XML / JSON转换对象的列表仍然要测试.我将很快在这里添加结果.)
问候并感谢chrylis的评论和提示.
贾纳
这是解决方案的代码,但简而言之,它只是新的部分.
1)XML解决方案:
在客户端将实体更改为XML字符串:
...
OutputStream out = new ByteArrayOutputStream();
JAXBContext context = JAXBContext.newInstance(Kunde.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(kunde, out);
out.close();
Form form = new Form();
form.add("entity", out.toString());
...
要将XML转换回服务器端的Object:
...
public String test(
@FormParam("entity") String entityString) {
InputStream inputStream = new ByteArrayInputStream(entityString.getBytes());
Kunde kunde = JAXB.unmarshal(inputStream, Kunde.class);
return "Der Name des Kunden ist: "+kunde.getVorname()+" "+kunde.getNachname();
}
2)JSON解决方案:
在客户端将实体更改为JSON字符串:
...
OutputStream out = new ByteArrayOutputStream();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(out, kunde);
out.close();
Form form = new Form();
form.add("entity", out.toString());
...
要将JSON字符串转换回服务器端的Object:
...
public String test(
@FormParam("entity") String entityString) {
InputStream inputStream = new ByteArrayInputStream(entityString.getBytes());
Kunde kunde = new ObjectMapper().read((inputStream, Kunde.class));
return "Der Name des Kunden ist: "+kunde.getVorname()+" "+kunde.getNachname();
}
JAXB,JAXBContext,Marshaller等类来自包javax.xml.bind.*. ObjectMapper类来自包org.codehaus.jackson.map.*.
PS:因为现在传输普通字符串,你也可以使用@QueryParam.但我不推荐这样做,因为你将整个XML作为URL中的文本字符串传输. @PathParam也是如此.
我推荐使用JSON,因为格式比XML格式更纤细,而且修长是REST的目标.