[英]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數組轉換為List
或List
,然后可以通過反射來調用該方法。
使用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.