java - tutorial - not marked as ignorable 0 known properties])
Jackson-Deserialize Variable de clase genérica (4)
Yo había publicado la pregunta erróneamente. Estoy publicando la pregunta correctamente aquí ...
Estoy recibiendo una cadena json como respuesta HTTP. Sé la estructura de eso. Es como sigue:
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;
}
El campo "datos" puede pertenecer a cualquier clase. Lo sabré en tiempo de ejecución solamente. Lo obtendré como un parámetro. Así es como estoy deserializando.
public <T> void deSerialize(Class<T> clazz {
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(jsonString, new TypeReference<Json<T>>() {});
}
Pero estoy obteniendo un error -
no se puede acceder a java.lang.class.Class () privado desde java.lang.class. Error al establecer el acceso No se puede hacer que un constructor java.lang.Class esté accesible
Deserializar variable de clase genérica
...
¿Cómo se lo digo a Jackson? ¿Lo hará mejor Gson?
La guía del usuario de Gson incluye una sección sobre exactamente lo que entiendo que estás tratando de lograr, aunque ese ejemplo documentado aún puede estar incompleto.
En una publicación de blog, cubrí con más detalle la solución usando Gson 1.7.1. A continuación se muestra el ejemplo de código relevante.
Soluciones similares (pero más complicadas) que usan Jackson (1.8.2) también se demuestran y describen en la misma publicación del blog. (Los diferentes enfoques y ejemplos usan cientos de líneas de código, así que he omitido reenviarlos aquí).
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);
}
}
¿Está serializando y deserializando un objeto de Clase a JSON? Tal vez mantenerlo como String in Hit y crear getter adicional que lanza Class.forName, por ejemplo
public class Hit {
public String id;
public String data;
public Class<?> getDataClass() throws Exception {
return Class.forName(data);
}
}
Tendrá que compilar JavaType
explícitamente, si el tipo genérico solo está dinámicamente disponible:
// 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));
}
Interfaz de deserialización genérica de muestra:
public interface Deserializable<T> {
static final ObjectMapper mapper = new ObjectMapper();
@SuppressWarnings("unchecked")
default T deserialize(String rawJson) throws IOException {
return mapper.readValue(rawJson, (Class<T>) this.getClass());
}
}