我正在一个项目中使用JSON作为创建Java对象的配置框架。这也是我来自CF / PHP / JS等方面多年经验的第一个专业Java项目。
在将JSON转换为Java时,我能找到的所有资源都基于以下想法:您必须先在Java中手动构建对象,即POJO,然后使用JSON进行填充。
作为网络语言的资深人士,我对此想法感到窒息。我发现编译后的语言起着不同的作用,但是我认为从命令行到机器语言的共享是一个原则:“如果必须执行两次以上,请使其自动化。”
……但似乎Java的主要智慧是:每次都手工构建繁琐的结构,然后使用GSON / Jackson
/任何方法填充刚性结构。如果您的JSON发生了更改(并且因为JSON而发生了更改),则将再次执行整个操作。
是否有与Web代码类似的思维方式?
1)加载JSON
2)基于JSON结构构建本地语言结构。
3)用结构中的数据填充新对象。
4)随意使用对象。
(正如@Thomas所指出的,为什么需要这样做的最准确的情况是返回JSON的API响应,它可能会定期有所不同,尽管对于高级语言而言,鸭子输入通常不舒服,甚至可以将EVERYTHING转换为字符串保存与每次都重新构建框架相比(或拥有一个将无数来源的JSON转换为可被任何其他工具使用的工具)所花费的时间和精力。同样,从牛仔语言的角度看,这似乎很明显,但对于高级语言来说却是陌生的语言人们不理解这个问题。)
我仔细阅读了上面的注释,并且认为在非常普遍的情况下,即使在编译时就知道了API结构, 临时 Java对象也将非常有用。
假设您处理一个API,该API返回一个复杂的JSON对象,您仅对非常特定的属性值感兴趣。
以以下Google Map API调用示例为例,获取地理详细信息并提供地址:
https://maps.googleapis.com/maps/api/geocode/json?address=sunnyvale,CA
如您所见,响应结构非常复杂。假设您只想获取lat
and lng
属性值,应该有一种更简单的方法,而不是预先定义完整的对应Java类。
因此,是的,如果您不想使用强类型的预定义Java类,则需要使用原始Object类型和Maps。更具体地说,是一个StringMap。
现在终于可以给出一个解决方案:
理想情况下,您希望使用与JS中相同的本机符号来访问属性。像这样:
String url = "https://maps.googleapis.com/maps/api/geocode/json?address=" + address;
String responseStr = fetch(url);
JsonHelper response = JsonHelper.forString(responseStr);
String status = (String) response.getValue("status");
if(status != null && status.equals("OK")) {
lat = (Double) response.getValue("results[0].geometry.location.lat");
lng = (Double) response.getValue("results[0].geometry.location.lng");
}
以下 JsonHelper
类代码摘自jello-framework,它使您可以准确地做到这一点。
package jello.common;
import java.util.List;
import com.google.gson.Gson;
import java.util.AbstractMap;
public class JsonHelper {
private Object json;
public JsonHelper(String jsonString) {
Gson g = new Gson();
json = g.fromJson(jsonString, Object.class);
}
public static JsonHelper forString(String jsonString) {
return new JsonHelper(jsonString);
}
@SuppressWarnings("unchecked")
public Object getValue(String path) {
Object value = json;
String [] elements = path.split("\\.");
for(String element : elements) {
String ename = element.split("\\[")[0];
if(AbstractMap.class.isAssignableFrom(value.getClass())) {
value = ( (AbstractMap<String, Object>) value).get(ename);
if(element.contains("[")) {
if(List.class.isAssignableFrom(value.getClass())) {
Integer index = Integer.valueOf(element.substring(element.indexOf("[")+1, element.indexOf("]")) );
value = ((List<Object>) value).get(index);
}
else {
return null;
}
}
}
else {
return null;
}
}
return value;
}
}
输入数据上有一个例子。 这是我在向服务器发出适当请求后收到的数据示例。我得到了这样的数据。如何序列化此类数据?由于嵌套结构列表的动态名称,我的尝试失败了。如何正确处理这种嵌套动态结构?
问题内容: 在输入数据上有一个示例。 这是在向服务器发出适当请求后我收到的数据的示例。我得到了这样的数据。此类数据如何序列化?由于嵌套结构列表的动态名称,我的尝试失败了。如何正确处理此类嵌套的动态结构? 问题答案: 使用地图(类型为)在JSON中对对象进行建模: 然后拆封: 将导致(在Go Playground上尝试): {Status:OK StatusCode:100 Sms:map [790
我正试图将一个动态结构数组的内容复制到另一个动态结构数组中,但我得到了一个错误,“无效的数组赋值”,希望有人能给我指明正确的方向。 下面是我的结构: 我的功能: 最后,我正在尝试加密代理的内容,然后复制到encryptArr,但我现在只是想弄清楚如何复制。这是一个课程,我们还没有涵盖memcpy,所以这不是一个选项。
问题内容: 我正在尝试解组以下YAML(使用gopkg.in/yaml.v2): 使用以下代码: 但这给了我以下错误: 顶级属性是动态的,因此我需要将它们解析为字符串,结构中的所有其他键将始终相同,因此这些部分的结构也是如此。我该如何解析? (完整代码位于https://github.com/tirithen/unit- conversion/blob/master/convert.go#L84
问题内容: 我有以下几点: 我正在尝试对结构进行json编码,但是在我需要更改json键之前,例如,最终的json应该如下所示: 我注意到value.Type()。Field(i).Tag.Get(“ json”)的方法,但是没有设置方法。为什么?以及如何获取所需的json输出。 另外,如何遍历所有字段,包括嵌入式结构Another? https://play.golang.org/p/Qi8Jq
我是golang的新手,正在尝试解析来自web服务的一些响应,响应看起来像这样: 您可以看到每个元素都有一个键“数据”和“类型”(必须),但不同的“类型”会带来不同的“数据”字段。 你能建议一种有效的方法来构建这种对Golang结构的响应吗? 谢谢你。