POST期间REST Web服务中的HTTP 400错误,其中FormParam包含自己的对象(例如enities) [英] HTTP 400 error in REST web service during POST with FormParam containing own objects (e.g. enities)

查看:179
本文介绍了POST期间REST Web服务中的HTTP 400错误,其中FormParam包含自己的对象(例如enities)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的REST服务中的订购流程,我必须从客户端向服务器发送文章列表。这些文章对象是自制的实体类型。我已经发现发送一个STRING或INTEGER对象列表确实有效,通过@FormParam发送。

For an ordering process in my REST service I have to send a list of "articles" from client to server. These article objects are of a self-made entity type. I already found out that sending a list of STRING or INTEGER objects does work, sending it via @FormParam.

但是一旦我尝试发送一个我自己的列表对象(甚至只有一个对象),我总是得到 HTTP 400错误错误请求

But as soon as I try to send a list of my own objects (even only ONE object), I always get a HTTP 400 error "Bad Request".

我试着像下面这样的代码(只改变了form.add()的参数和服务器方法的参数)并且成功地输出了字符串,整数和字符串列表。它只会导致发送自己的对象类型的问题。

日志告诉我没有达到服务器方法。这个过程在之前的某个地方被破坏了。

I tried excatly the same code like below (only the parameters of form.add() and the parameters of the server method were altered) and postet Strings, Integers and lists of Strings successfully. It only makes problems sending own object types.
Logging told me that the server method isn't reached. The process is broken somewhere before.

我也试图通过使用代理(Apache JMeter)来获取请求。这里它表示参数 kunde 包含值 entities.Kunde%40af8358 。所以我猜这个对象没有彻底序列化(或根本没有)。但是在响应中将这种对象从服务器发送到客户端工作正常 - 这里XML序列化没有问题。

I also tried to get the request by using a proxy (Apache JMeter). Here it says that the parameter kunde contains the value entities.Kunde%40af8358. So I guess the object is not serialized thoroughly (or at all). But sending this kind of object from server to client in a response works fine - here the XML-serialization is no problem.

可能是什么原因?是否可能无法通过POST发送自己的类型?

(PS:我的示例中的类型 Kunde 是可序列化的,并使用<$ c $进行注释c> @XmlRootElement 。)

What might be the reason? Is it maybe NOT possible to send own types through POST?
(PS: The type Kundein my example is serializable and annotated with @XmlRootElement.)

提前感谢您的帮助!

Jana

Thank you in advance for your help!
Jana

注意:我正在使用SAP Netweaver AS。但直到现在它的表现与其他所有Java AS一样,所以我认为这不是原因。每个其他REST操作都可以工作,甚至是没有自己实体的POST。

Note: I'm using the SAP Netweaver AS. But until now it behaved like every other Java AS, so I don't think this will be the reason. Every other REST operation does work, even POST without own entities.

添加:我正在使用JERSEY库。

Addition: I'm using the JERSEY library.

服务器端的我的代码:

@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中):

My code on client side (the method is in a Session 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的新信息没有正确传输我发现了一个

解决方案

Due to the new information that the entity "Kunde" isn't trasmitted correctly I found a
SOLUTION:

我明确地将实体类转换为XML / JSON(无论哪种方式都有效)并将XML / JSON作为String放在表单中。在服务器端,我将XML / JSON字符串转换回实体,这很有效。

(看起来像是不可能传输一个不是字符串或整数的对象,因为它是。)

I explicitely transformed the entity class into XML/JSON (either way is working) and put that XML/JSON as a String in the form. On the server's side I transformed the XML/JSON String back into the Entity, this worked.
(Seems like it is NOT possible to transmit an object not beeing String or Integer as it is.)

希望这能帮助每个面临同样问题的人通过REST将对象从客户端传输到服务器。

发送一个列表的XML / JSON转换对象仍在测试。我将很快在这里添加结果。




问候并感谢chrylis的评论和提示。

Jana

Hope this will help everyone who faces the same problem transmitting objects from client to server via REST.
(Sending a List of XML/JSON-converted objects is still to test. I'll add the result here soon.)

Greetings and thanks to chrylis for his/her comments and hints.
Jana

以下是解决方案的代码,但简而言之,它只是新的部分。

Here's the code for the solution, but for shortness it's only the new parts.

1)XML解决方案:

在客户端将实体更改为XML字符串:

For changing Entity into XML String on Client's side:

...
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:

For transforming the XML back to an Object on the Server's side:

...
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字符串:

For changing Entity into JSON String on Client's side:

...
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:

For transforming the JSON String back to an Object on the Server's side:

...
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。*

The classes JAXB, JAXBContext, Marshaller etc. are from package javax.xml.bind.*. The class ObjectMapper is from package org.codehaus.jackson.map.*.

PS:因为现在传输plain String,你也可以使用 @QueryParam 。但我不推荐这样做,因为你将整个XML作为URL中的文本字符串传输。同样适用于 @PathParam

PS: Because transmitting plain String now, you also could use @QueryParam. But I wouldn't recomment that, because you'd be transmitting the whole XML as a text String in the URL. Same goes for @PathParam.

我推荐使用JSON ,因为格式比XML格式更纤细,更纤细是REST的目标。

I'd recommend JSON, because the format is more slender than the XML format, and being slender is the aim of REST.

这篇关于POST期间REST Web服务中的HTTP 400错误,其中FormParam包含自己的对象(例如enities)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆