我错误地发布了这个问题。我在这里正确地发布了这个问题......
我将json字符串作为HTTP响应。我知道它的结构。它如下:
public class Json<T> {
public Hits<T> hits;
}
public class Hits<T> {
public int found;
public int start;
public ArrayList<Hit<T>> hit;
}
public class Hit<T> {
public String id;
public Class<T> data;
}
“data”字段可以属于任何类。我只会在运行时知道它。我会把它作为一个参数。这就是我反序列化的方式。
public <T> void deSerialize(Class<T> clazz) {
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(jsonString, new TypeReference<Json<T>>() {});
}
但是我收到了错误 -
无法从java.lang.class访问私有java.lang.class.Class()。无法设置访问权限。无法使java.lang.Class构造函数可访问
答案 0 :(得分:19)
如果通用类型仅动态可用,则需要显式构建JavaType
:
// do NOT create new ObjectMapper per each request!
final ObjectMapper mapper = new ObjectMapper();
public Json<T> void deSerialize(Class<T> clazz, InputStream json) {
return mapper.readValue(json,
mapper.getTypeFactory().constructParametricType(Json.class, clazz));
}
答案 1 :(得分:3)
示例通用反序列化接口:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_actionbar"
style="@style/ToolBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:minHeight="@dimen/abc_action_bar_default_height_material">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textAllCaps="true"
android:textColor="#ffffff"
android:textSize="18sp"
android:textStyle="bold" />
</android.support.v7.widget.Toolbar>
答案 2 :(得分:1)
您是否将Class对象序列化和反序列化为JSON?也许在Hit中保持它为String并创建另外的启动Class.forName的getter,例如
public class Hit {
public String id;
public String data;
public Class<?> getDataClass() throws Exception {
return Class.forName(data);
}
}
答案 3 :(得分:0)
需要反序列化的JSON字符串必须包含有关参数T
的类型信息。
您必须将Jackson注释放在可以作为参数T
传递给类Json
的每个类上,以便可以从JSON字符串读取/写入有关参数类型T
的类型信息杰克逊。
让我们假设T
可以是任何扩展抽象类Result
的类。
public class Json<T extends Result> {
public Hits<T> hits;
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@JsonSubTypes.Type(value = ImageResult.class, name = "ImageResult"),
@JsonSubTypes.Type(value = NewsResult.class, name = "NewsResult")})
public abstract class Result {
}
public class ImageResult extends Result {
}
public class NewsResult extends Result {
}
一旦可以作为参数T
传递的每个类(或它们的常用超类型)被注释,Jackson将在JSON中包含有关参数T
的信息。然后可以在编译时不知道参数T
的情况下反序列化这样的JSON
这篇Jackson documentation link讨论了多态反序列化,但也可用于引用这个问题。
答案 4 :(得分:-1)
反序列化通用类变量
...
我怎么告诉杰克逊? gson会做得更好吗?
The Gson user guide includes a section关于我理解你正在努力完成的事情,尽管有记录的例子可能仍然不完整。
In a blog post, I covered in more detail the solution using Gson 1.7.1.以下是相关的代码示例。
使用Jackson(1.8.2)的类似(但更多参与)解决方案也在同一博客文章中进行了演示和描述。 (不同的方法和示例使用了数百行代码,所以我在这里省略了重新发布它们。)
public class GsonInstanceCreatorForParameterizedTypeDemo
{
public static void main(String[] args)
{
Id<String> id1 = new Id<String>(String.class, 42);
Gson gson = new GsonBuilder().registerTypeAdapter(Id.class,
new IdInstanceCreator()).create();
String json1 = gson.toJson(id1);
System.out.println(json1);
// actual output: {"classOfId":{},"value":42}
// This contradicts what the Gson docs say happens.
// With custom serialization, as described in a
// previous Gson user guide section,
// intended output may be
// {"value":42}
// input: {"value":42}
String json2 = "{\"value\":42}";
Type idOfStringType=new TypeToken<Id<String>>(){}.getType();
Id<String> id1Copy = gson.fromJson(json2, idOfStringType);
System.out.println(id1Copy);
// output: classOfId=class java.lang.String, value=42
Type idOfGsonType = new TypeToken<Id<Gson>>() {}.getType();
Id<Gson> idOfGson = gson.fromJson(json2, idOfGsonType);
System.out.println(idOfGson);
// output: classOfId=class com.google.gson.Gson, value=42
}
}
class Id<T>
{
private final Class<T> classOfId;
private final long value;
public Id(Class<T> classOfId, long value)
{
this.classOfId = classOfId;
this.value = value;
}
@Override
public String toString()
{
return "classOfId=" + classOfId + ", value=" + value;
}
}
class IdInstanceCreator implements InstanceCreator<Id<?>>
{
@SuppressWarnings({ "unchecked", "rawtypes" })
public Id<?> createInstance(Type type)
{
Type[] typeParameters =
((ParameterizedType) type).getActualTypeArguments();
Type idType = typeParameters[0];
return new Id((Class<?>) idType, 0L);
}
}