我有一个可以返回JSON数组或对象的API。JSON对象示例
{
"id": 1,
"name": "name"
}
JSON数组:
[
{
"id": 1,
"name": "name"
},
{
"id": 1,
"name": "name"
}
]
将JSON对象响应映射到POJO时,我使用:
MyEntity myEntity = new Gson().fromJson(jsonString, MyEntity.class);
当将JSON数组响应映射到POJO数组时,我使用:
MyEntity[] myEntity = new GSON().fromJson(jsonString, MyEntity[].class);
如何将这两个响应动态转换为适当的类型?
注意:我无法修改服务器响应,这是一个公共API。
谢谢!
编辑:
我正在尝试实现一种自动执行此操作的方法,但是我缺少了一些东西。方法
public <T> T convertResponseToEntity(Class<T> classOfT)
{
JsonElement jsonElement = this.gson.fromJson(getResponseAsString(), JsonElement.class);
if (jsonElement.isJsonArray()) {
Type listType = new TypeToken<T>(){}.getType();
return this.gson.fromJson(getResponseAsString(), listType);
}
return this.gson.fromJson(getResponseAsString(), (Type) classOfT);
}
它返回LinkedTreeMap
s 的列表。如何修改代码以返回与之相同的内容Object[]
?
如何将这两个响应动态转换为适当的类型?
这取决于如何在此处解释“适当的类型”,因为instanceof
一旦您每次需要处理从JSON解析的对象时,它都会导致或访问者模式获得适当的类型。如果您无法更改API,则可以简化其使用方式。这里可能的选项之一是像对待所有内容一样处理此类响应。甚至单个对象也可以仅作为一个元素处理为列表(许多库仅使用具有以下事实的序列/列表进行处理:Java中的Stream
API,.NET中的LINQ,JavaScript中的jQuery等)。
假设您具有以下MyEntity
类来处理从所需的API获得的元素:
// For the testing purposes, package-visible final fields are perfect
// Gson can deal with final fields too
final class MyEntity {
final int id = Integer.valueOf(0); // not letting javac to inline 0 since it's primitive
final String name = null;
@Override
public String toString() {
return id + "=>" + name;
}
}
接下来,让我们创建一个类型适配器,该适配器将始终将“ true”列表和单个对象对齐,就好像它是列表一样:
final class AlwaysListTypeAdapter<T>
extends TypeAdapter<List<T>> {
private final TypeAdapter<T> elementTypeAdapter;
private AlwaysListTypeAdapter(final TypeAdapter<T> elementTypeAdapter) {
this.elementTypeAdapter = elementTypeAdapter;
}
static <T> TypeAdapter<List<T>> getAlwaysListTypeAdapter(final TypeAdapter<T> elementTypeAdapter) {
return new AlwaysListTypeAdapter<>(elementTypeAdapter);
}
@Override
@SuppressWarnings("resource")
public void write(final JsonWriter out, final List<T> list)
throws IOException {
if ( list == null ) {
out.nullValue();
} else {
switch ( list.size() ) {
case 0:
out.beginArray();
out.endArray();
break;
case 1:
elementTypeAdapter.write(out, list.iterator().next());
break;
default:
out.beginArray();
for ( final T element : list ) {
elementTypeAdapter.write(out, element);
}
out.endArray();
break;
}
}
}
@Override
public List<T> read(final JsonReader in)
throws IOException {
final JsonToken token = in.peek();
switch ( token ) {
case BEGIN_ARRAY:
final List<T> list = new ArrayList<>();
in.beginArray();
while ( in.peek() != END_ARRAY ) {
list.add(elementTypeAdapter.read(in));
}
in.endArray();
return unmodifiableList(list);
case BEGIN_OBJECT:
return singletonList(elementTypeAdapter.read(in));
case NULL:
return null;
case END_ARRAY:
case END_OBJECT:
case NAME:
case STRING:
case NUMBER:
case BOOLEAN:
case END_DOCUMENT:
throw new MalformedJsonException("Unexpected token: " + token);
default:
// A guard case: what if Gson would add another token someday?
throw new AssertionError("Must never happen: " + token);
}
}
}
Gson
TypeAdapter
被设计为以流方式工作,因此从效率角度来看它们很便宜,但实施起来并不那么容易。write()
上面的方法只是为了不放在throw new UnsupportedOperationException();
那儿而实现的(我假设您只阅读了该API,但是不知道该API是否会消耗“元素或列表”修改请求)。现在有必要创建一个类型适配器工厂,以让Gson为每种特定类型选择合适的类型适配器:
final class AlwaysListTypeAdapterFactory
implements TypeAdapterFactory {
private static final TypeAdapterFactory alwaysListTypeAdapterFactory = new AlwaysListTypeAdapterFactory();
private AlwaysListTypeAdapterFactory() {
}
static TypeAdapterFactory getAlwaysListTypeAdapterFactory() {
return alwaysListTypeAdapterFactory;
}
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken)
throws IllegalArgumentException {
if ( List.class.isAssignableFrom(typeToken.getRawType()) ) {
final Type elementType = getElementType(typeToken);
// Class<T> instances can be compared with ==
final TypeAdapter<?> elementTypeAdapter = elementType == MyEntity.class ? gson.getAdapter(MyEntity.class) : null;
// Found supported element type adapter?
if ( elementTypeAdapter != null ) {
@SuppressWarnings("unchecked")
final TypeAdapter<T> castTypeAdapter = (TypeAdapter<T>) getAlwaysListTypeAdapter(elementTypeAdapter);
return castTypeAdapter;
}
}
// Not a type that can be handled? Let Gson pick a more appropriate one itself
return null;
}
// Attempt to detect the list element type
private static Type getElementType(final TypeToken<?> typeToken) {
final Type listType = typeToken.getType();
return listType instanceof ParameterizedType
? ((ParameterizedType) listType).getActualTypeArguments()[0]
: Object.class;
}
}
以及如何使用它:
private static final Type responseItemListType = new TypeToken<List<MyEntity>>() {
}.getType();
private static final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(getAlwaysListTypeAdapterFactory())
.create();
public static void main(final String... args) {
test("");
test("{\"id\":1,\"name\":\"name\"}");
test("[{\"id\":1,\"name\":\"name\"},{\"id\":1,\"name\":\"name\"}]");
test("[]");
}
private static void test(final String incomingJson) {
final List<MyEntity> list = gson.fromJson(incomingJson, responseItemListType);
System.out.print("LIST=");
System.out.println(list);
System.out.print("JSON=");
gson.toJson(list, responseItemListType, System.out); // no need to create an intermediate string, let it just stream
System.out.println();
System.out.println("-----------------------------------");
}
输出:
LIST=null
JSON=null
-----------------------------------
LIST=[1=>name]
JSON={"id":1,"name":"name"}
-----------------------------------
LIST=[1=>name, 1=>name]
JSON=[{"id":1,"name":"name"},{"id":1,"name":"name"}]
-----------------------------------
LIST=[]
JSON=[]
-----------------------------------
我面临一个问题,有时Json响应返回一个对象数组,有时是对象本身,我们如何在响应类中动态处理。在当前的eg:结果有时会得到一个对象数组 有时对象本身 例如: 我们如何处理这件事? 请协助... 有没有人能给点建议用不同的罐子来实现这个?
我的JSON的格式是: “abc”是变量,“field_1”和“value”是字段名。我希望Java中的一个类以某种格式存储这个JSON,例如: 我的班级。JAVA 我想要我的班级。java,因为将来我可能想在JSON响应中添加更多元数据。这是一个复杂的对象映射,但我不知道我的类应该是什么样子来存储JSON响应。
本文向大家介绍如何使用Jackson库将Java对象转换为JSON?,包括了如何使用Jackson库将Java对象转换为JSON?的使用技巧和注意事项,需要的朋友参考一下 JSON或JavaScript Object Notation是一种轻量级的基于文本的开放标准,旨在用于人类可读的数据交换。JSON使用的约定是程序员已知的,包括C,C ++,Java,Python,Perl等。 有几种Java
本文向大家介绍如何使用GSON库将Java对象转换为JSON?,包括了如何使用GSON库将Java对象转换为JSON?的使用技巧和注意事项,需要的朋友参考一下 JSON或JavaScript Object Notation是一种轻量级的基于文本的开放标准,旨在用于人类可读的数据交换。JSON使用的约定是程序员已知的,包括C,C ++,Java,Python,Perl等。 有几种Java库可用于处理
使用此JSON,自动JSON到POJO严重失败。 请注意,不同请求的项目数量不同。在这里,我将包含两项JSON响应。 这个JSON对象的POJO会是什么样子?
null 这是很好的,因为我可以确定我的API请求是否成功。 但是: 由于JSend格式有它自己的东西,它在响应时也有一个小的状态指示器,如下所示: 我是否应该坚持手动解析并使用而不是我的模型 对于类型paramter? 因为这样,我可以使用并将字符串转换为JSON,然后我可以手动解析模型,就像为它们编写解析器一样。