簡體   English   中英

使用JSON反序列化為Java對象嗎?

[英]Deserialization to a Java object using JSON?

我必須接收以下JSON:

{
   "method":"methodName1",
   "args":{
      "arg1Name":"arg1Value",
      "arg2Name":"arg2Value"
   }

}

這是另一個例子:

{
   "method":"methodName2",
   "args":{
      "arg1Name":"arg1Value",
      "arg2Name":"arg2Value"
      "arg3Name":"arg3Value"
      "arg4Name":"arg4Value"
   }

}

我需要解析那些JSON,以便使用指定的“ args”作為參數來調用指定的方法。

對我而言,最簡單的方法是使用JsonParser來獲取JsonElement ,然后是JsonObject ,然后使用.get()提取每個值...像這樣:

JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(jsonString);
if (jsonElement.isJsonObject()) {
     JsonObject jsonObject = jsonElement.getAsJsonObject();
     String method = jsonObject.get("method").getAsString();
     JsonObject jsonArgs = jsonObject.getAsJsonObject("args");
     String arg1 = jsonArgs.get("arg1Name").getAsString();
     String arg2 = jsonArgs.get("arg2Name").getAsString();

}

然后,我可以使用適當的參數(使用switch )調用指定的方法。

我只是想知道是否會有更簡單(或更漂亮)的方法來實現這一目標。

我可以改用.fromJson()來檢索對象,但是我不知道如何創建我的類來這樣做(有些東西像一個args數組,並且並非所有方法都具有相同數量的args)。

我是JSON(以及Java)的新手。

我設法做到了:

import lotus.domino.*;
import com.google.gson.*;
import java.io.*;
import java.lang.reflect.Method;

public class JavaAgent extends AgentBase {
    public void NotesMain() {
        try {
            String jsonReceived = "{\"method\":\"methodName\",\"args\":{\"arg1Name\":\"arg1Value\",\"arg2Name\":\"arg2Value\"}}";
            Gson gson = new Gson();
            MethodCall mc = gson.fromJson(jsonReceived, MethodCall.class);

            JavaAgent ja = new JavaAgent();
            Method method = getClass().getMethod(mc.getMethod(), MethodCall.class);
            String s = (String)method.invoke(ja, mc);

            PrintWriter pw = getAgentOutput();
            pw.println(s);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public String methodName(MethodCall mc) {
        String s = mc.getArgs().get("arg1Name") + " " + mc.getArgs().get("arg2Name");
        return s;
    }
}

import java.util.*;
public class MethodCall {
    private String method;
    private Map<String, String> args;

    public String getMethod() {
        return method;
    }

    public Map<String, String> getArgs() {
        return args;
    }
}

似乎可行...但是由於我是Java新手,因此我不確定這是否是正確的方法。 你怎么看?

也許Gson Map序列化器足夠聰明,可以反序列化?

public class MethodCall {
    private String method;
    private Map<String, String> args;
}

(沒有時間對其進行徹底的測試,但我希望它能起作用!:))

您必須將代碼反序列化兩次,因為它包含在其他數組中

JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(jsonString);
if (jsonElement.isJsonObject()) {
     JSONObject jsonObject = jsonElement.getAsJsonObject();
     String method = jsonObject.get("method").getAsString();
     JSONObject jsonArgs = (JSONObject) jsonObject.get("args");     
     String arg1 = jsonArgs.get("arg1Name").getAsString();
     String arg2 = jsonArgs.get("arg2Name").getAsString();

}

按照通常使用Gson的方式執行此操作的問題在於,JSON "args"是一個對象,根據您的示例,該對象可以具有可變數量的字段(參數及其名稱)。 如果"args"只是方法的參數的JSON數組(沒有參數名稱)會更好,因為無論如何在調用方法時您將無法使用參數名稱。 然后,您可以編寫一個簡單的類,例如:

class MethodCall {
   private String method;
   private List<String> args;
   ...
}

可以從JSON解析。

我猜測您無法更改所接收的格式,因此另一種選擇可能是使用上面列出的相同類,但JsonDeserializer注冊一個自定義JsonDeserializer 可能看起來像這樣:

public MethodCall fromJson(JsonElement json, Type typeOfT, 
                           JsonDeserializationContext context)
      throws JsonParseException {
  JsonObject obj = json.getAsJsonObject();
  String method = obj.get("method").getAsString();
  JsonObject argsObj = obj.getAsJsonObject("args");
  List<String> args = new ArrayList<String>();
  for(Map.Entry<String,JsonElement> entry : argsObj.entrySet()) {
    args.add(entry.getValue().getAsString());
  }
  return new MethodCall(method, args);
}

然后,您可以使用反射來調用該方法。 理想情況下,執行該操作的方法將是MethodCall上的方法,因此在獲取MethodCall對象之后,您只需編寫call.callMethod(obj) ,而obj是您希望方法被調用的對象。

編輯

最容易調用Java方法的JSON格式如下所示:

{
  "method":"methodName2",
  "args": [
    "arg1Value",
    "arg2Value",
    "arg3Value",
    "arg4Value"
  ]
}

Gson可以自動將JSON數組轉換為ListList ,然后可以通過反射來調用該方法。

使用Java反射。

List<String> args = new ArrayList<String>();
// add the args to the list here
Method method = myClass.getClass().getMethod(method, List.class);
Object o = method.invoke(myClass, args);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM