GWT - 在发送之前在JSON中序列化POST参数

时间:2014-08-23 14:13:52

标签: java json gwt

我正在尝试从GWT客户端调用REST服务器。服务器不受我的控制,我只是为客户端使用GWT。该服务期望收到一个JSON,它将与Jackson反序列化并映射到这样的Java bean:

public DTO {
    String username;
    String password;
    /*...*/
}

因此,在我的GWT项目中,我创建了这个类:

import com.google.gwt.json.client.JSONObject; import com.lh.clte.client.gui.util.CLTELabelProperties;

public class DTO extends JSONObject {
    String username;
    String password;
    /*...*/
}

我正试图以这种方式发送POST请求:

    DTO dto= new DTO();
    dto.setUsername(username);
    dto.setPassword(password);

    RequestBuilder b = new RequestBuilder(RequestBuilder.POST, url);
    b.setHeader("content-type", "application/x-www-form-urlencoded");
    /***** ERROR *************/
    String data = dto.toString(); // JSONObject.toString(), no ovveriding
    /*************************/
    b.setRequestData(data);
    b.setCallback(new MyCallback<DTO>());
    try {
        b.send();
    } catch (RequestException e) {
        e.printStackTrace();
    }

但是,toString方法不会生成预期的JSON,而是生成字符串“{}”。我在哪里做错了? 我也尝试过com.google.gwt.json.client.dev.JsonObject,但它不会改变结果。

4 个答案:

答案 0 :(得分:1)

您必须在通过电汇发送之前对JSO对象进行字符串化:

String data = JsonUtils.stringify(dto);

此功能在2.7.0-SNAPSHOT中可用,对于2.6.1,您必须创建自己的JSNI方法

String data = stringify(dto);

private native String stringfy(JavaScriptObject jso) /*-{
  return JSON.stringify(obj);
}-*/;

答案 1 :(得分:1)

JSONObject是&#34;地图&#34;,它无意延长。

您可以让访问者将值存储在内部JSONObject而不是字段中,或者您可以使用带有JSNI编写的访问者的JavaScriptObject并使用JsonUtils进行解析和{ {1}}用于序列化(JSONObject,等待GWT 2.7&#39; new JSONObject(myJso).toString()),或者您可以使用AutoBeans。

另请参阅https://stackoverflow.com/a/10685489/116472How to genearte JSON on the client以及其他许多内容。

答案 2 :(得分:0)

如果你的后端使用杰克逊,你应该试试gwt-jackson。 如果您有权访问源,您将能够使用任何DTO甚至服务器bean。

你声明你的映射器:

public static interface DTOWriter extends ObjectWriter<DTO> {}

然后:

DTOWriter dtoWriter = GWT.create(DTOWriter.class);
String data = dtoWriter.write(dto);

顺便说一句,您的内容类型标题不应该是application/json吗?

答案 3 :(得分:0)

另一种方法是使用RestyGWT(http://restygwt.fusesource.org/)。

RestyGWT将负责与JSON进行序列化以及进行POST请求。

在您的示例中,您将需要一个定义哪些字段可序列化的类:

public class DTO {

    @Json(name = "username") // 'username' will be the name of the parameter in the json object
    private String username;
    @Json(name = "password")
    private String password;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

然后,通过扩展RestService

来定义服务
public interface DTORestService extends RestService {

    /**
     * Utility/Convenience class.
     * Use DTORestService.App.getInstance() to access static instance of DTORestService
     */
    public static class App {
        private static DTORestService ourInstance = null;

        public static DTORestService getInstance() {
            if (ourInstance == null) {
                Defaults.setServiceRoot(host); // the host from the 'url' you want the POST to be sent
                ourInstance = (DTORestService) GWT.create(DTORestService.class);
            }
            return ourInstance;
        }
    }

    @POST
    @Path("/dto.json") // the path from the 'url' you want the POST to be sent
    public void getDTO(DTO dto, // the json object you want to add to the post
                    MethodCallback<DTO> callback); // the method callback with any json result you will receive
}

最后,你可以这样做:

DTO dto = new DTO();
dto.setUsername(username);
dto.setPassword(password);
DTORestService.getInstance().getDTO(dto, new AMethodCallback<DTO>());

希望有所帮助