Java 在GWT中创建JSON字符串的更好方法?

Java 在GWT中创建JSON字符串的更好方法?,java,json,gwt,generics,Java,Json,Gwt,Generics,我有一个定义为Object[]的变量参数,使我的应用程序能够向函数发送一系列键/值对。下面的代码处理字符串、整数以及字符串和整数的数组列表。我想扩展它以支持double和boolean(以及两者的ArrayLists) 这个函数有很多重复的代码 更新:我正在使用GWT框架 问题1。这是正确的方法,但需要一个泛型类来提供更容易的维护吗?如果是,怎么做? 问题2。有更好的替代方法吗 final static int KEY = 0; final static int VALUE = 1; ... S

我有一个定义为Object[]的变量参数,使我的应用程序能够向函数发送一系列键/值对。下面的代码处理字符串、整数以及字符串和整数的数组列表。我想扩展它以支持double和boolean(以及两者的ArrayLists)

这个函数有很多重复的代码

更新:我正在使用GWT框架

问题1。这是正确的方法,但需要一个泛型类来提供更容易的维护吗?如果是,怎么做? 问题2。有更好的替代方法吗

final static int KEY = 0;
final static int VALUE = 1;
...
String buildParamaters(Object[][] arguments) {
    JSONObject parameters = new JSONObject();
    for (Object[] arg : arguments) {
        if (isType(arg[VALUE], "java.util.ArrayList")) {
            JSONArray array = new JSONArray();
            if (isType(arg[VALUE], "java.lang.Integer")) {
                ArrayList<String> values = (ArrayList<String>) arg[VALUE];
                for (int i=0; i<values.size(); i++) {
                    array.set(i, new JSONString(values.get(i)));
                }
            } else {
                ArrayList<Integer> values = (ArrayList<Integer>) arg[VALUE];
                for (int i=0; i<values.size(); i++) {
                    array.set(i, new JSONNumber(values.get(i)));
                }
            }
            parameters.put(arg[KEY].toString(), array);
        } else if (isType(arg[VALUE], "java.lang.Integer")) {
            parameters.put(arg[KEY].toString(), new JSONNumber(((Integer)arg[VALUE]).doubleValue()));
        } else {
            parameters.put(arg[KEY].toString(), new JSONString((String)arg[VALUE]));
        }
    }
    return parameters.toString();
}
final static int KEY=0;
最终静态int值=1;
...
字符串构建参数(对象[][]参数){
JSONObject参数=新的JSONObject();
for(对象[]参数:参数){
if(isType(arg[VALUE],“java.util.ArrayList”)){
JSONArray数组=新的JSONArray();
if(isType(arg[VALUE],“java.lang.Integer”)){
ArrayList值=(ArrayList)arg[VALUE];

对于(int i=0;i您应该使用类似Jackson的框架,它能够将任何Java对象映射到JSON,反之亦然:

public class User {

    private int age = 29;
    private String name = "mkyong";
    private List<String> messages = new ArrayList<String>() {
        {
            add("msg 1");
            add("msg 2");
            add("msg 3");
        }
    };

    //getter and setter methods

    @Override
    public String toString() {
        return "User [age=" + age + ", name=" + name + ", " +
                "messages=" + messages + "]";
    }
}

//1. Convert Java object to JSON format
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new File("c:\\user.json"), user);
资料来源:


(顺便说一句:你需要向用户添加getter和setter)

你可以看看。

你可以构建自己的类来防止这种不安全的混乱。或者你可以使用一个框架(GSON在安卓上运行良好,Jackson有问题,但在JavaSE上运行良好),但如果你希望它更快、更小一些(例如安卓开发人员)您可以这样做:

引入一个接口:

public interface JSONRepresentable {
   public JSONValue getJsonValue();
}
这样,您就可以引入如下列表类:

public class IntList extends ArrayList<Integer> implements JSONRepresentable {
   @Override
   public JSONValue getJsonValue() {
       JSONArray arr = new JSONArray();
       int size = this.size();

       for(int i = 0; i < size; i++) { 
          arr.set(i, new JSONNumber(get(i)));
       }

       return arr;
   }
} 
StringValue implements JSONRepresentable {
   private String val;

   public StringValue(String val) { this.val = val; }
   public StringValue() { this(""); }

   public String value() { return val; }
   public void setValue(String val) { this.val = val; }

   @Override
   public JSONValue getJsonValue() {
       return new JSONString(val);
   }
}
然后为ArrayList实现您自己的JSONRepresentable,如上所述

然后,您可以将对象[]替换为Map[String,JSONRepresentable]。也许这对您来说并不完美,但它可以为您提供如何解决该问题的指针,而无需走反射路线

与基于反射的框架(如GSON或Jackson)相比,这将是非常快的,但这只有在使用具有此类层次结构的JSON框架时才起作用


您使用什么?

您可以使用它将Java对象转换为JSON数组,反之亦然。这个第三方工具是由Google团队自己开发的。它使用起来非常简单和安全。另一个类似的GWT第三方库是

谢谢您的建议。我喜欢它提供的类型检查,但这种方法实际上并没有减少重复代码,但会有许多看起来非常相似的类。每次向类中添加字段时,也必须编辑toString方法。如果OP的json字符串没有提前定义(例如,它基于某些用户输入,具体来说,键基于用户输入),则jackson将有一个硬(er)时间转换,因为您没有要转换的现有bean类,最终得到的是本质上的映射。如果是这种情况,还不如通过gwt javascript对象覆盖使用真实的映射。您能扩展示例代码吗?我完全接受您的“不安全混乱”要点!@Carl我添加了一点代码。这还不是一个完美的解决方案,但可能会帮助您找到一个。谢谢@schlingel。这让人深思。我会进一步调查。必须为参数声明新的StringValue(“…”)确实感觉方向不对。也许有一种方法可以直接使用字符串。
StringValue implements JSONRepresentable {
   private String val;

   public StringValue(String val) { this.val = val; }
   public StringValue() { this(""); }

   public String value() { return val; }
   public void setValue(String val) { this.val = val; }

   @Override
   public JSONValue getJsonValue() {
       return new JSONString(val);
   }
}