![](/img/trans.png)
[英]Getting 405 “Method Not Allowed” error using POST with @FormParam (Java web service with Jersey REST)
[英]HTTP 400 error in REST web service during POST with FormParam containing own objects (e.g. enities)
对于我的REST服务中的订购过程,我必须从客户端向服务器发送“文章”列表。 这些商品对象属于自制实体类型。 我已经发现发送STRING或INTEGER对象的列表确实可以通过@FormParam发送。
但是,一旦我尝试发送自己的对象列表(甚至只有一个对象),我总是会收到HTTP 400错误“错误的请求” 。
我尝试了如下相同的代码(仅更改了form.add()的参数和server方法的参数),并且成功地发布了Postet字符串,整数和字符串列表。 这只会使发送自己的对象类型产生问题。
日志记录告诉我未达到服务器方法。 这个过程以前被打破了。
我还尝试通过使用代理(Apache JMeter)来获取请求。 这里说参数kunde
包含值entities.Kunde%40af8358
。 因此,我猜该对象没有被彻底(或根本没有)序列化。 但是在响应中将这种对象从服务器发送到客户端可以很好地工作-在这里XML序列化没有问题。
可能是什么原因? 是否可能无法通过POST发送自己的类型?
(PS:类型Kunde
在我的例子是可序列化和带注释@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());
由于新的信息,即实体“ Kunde”的传输不正确,我发现
解决方案 :
我明确地将实体类转换为XML / JSON(无论哪种方式都可行),然后将该XML / JSON作为String形式放入表单中。 在服务器端,我将XML / JSON字符串转换回了Entity,这很有效。
(似乎无法传输不像String或Integer 那样的对象。)
希望这将帮助遇到相同问题的每个人都通过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转换回服务器端的对象:
...
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解决方案:
要在客户端将Entity更改为JSON String:
...
OutputStream out = new ByteArrayOutputStream();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(out, kunde);
out.close();
Form form = new Form();
form.add("entity", out.toString());
...
要将JSON字符串转换回服务器端的对象:
...
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中的文本String传输。 @PathParam
。
我建议使用JSON ,因为该格式比XML格式更细长,而细长是REST的目标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.