Mit TypeReference mit Jackson
Folgende test fehlschlägt,
java.util.LinkedHashMap cannot be cast to org.dabd.mapping2.MapperImplNGTest$Foo
java.lang.ClassCastException
at org.dabd.mapping2.MapperImplNGTest.testFromMap(MapperImplNGTest.java:82)
Die einzige Lösung, die ich finden konnte, ist die änderung der fromMap Signatur T fromMap(S map, Class<T> clazz)
aber ich glaube nicht, dass es notwendig ist, übergeben Sie die Klasse explizit. Ist das nicht die TypeReference genug Informationen zum instanziieren der Typ T? Danke.
import java.util.Map;
public interface Mapper<T extends Object, S extends Map<String, Object>> {
public S toMap(T obj);
public T fromMap(S map);
}
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class MapperImpl<T extends Object, S extends Map<String, Object>>
implements Mapper<T, S> {
public S toMap(T obj) {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.convertValue(obj, Map.class);
return (S) map;
}
public T fromMap(S map) {
ObjectMapper objectMapper = new ObjectMapper();
T obj = objectMapper.convertValue(map, new TypeReference<T>() {
});
return obj;
}
}
Test
import java.util.HashMap;
import java.util.Map;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
public class MapperImplNGTest {
public static class Foo {
private String a;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
public MapperImplNGTest() {
}
@Test
public void testFromMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("a", "aa");
MapperImpl<Foo, Map<String, Object>> mapper = new MapperImpl<Foo, Map<String, Object>>();
Foo foo = mapper.fromMap(map);
assertEquals(foo.getA(), map.get("a"));
}
}
InformationsquelleAutor dmz73 | 2014-10-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, Sie nicht verwenden können, geben Sie Variablen wie
T
diese Weise mitTypeReference
: Sie müssen pass eigentlichen Parametrisierung. Dies ist, weil es keine runtime-Informationen jeglicher Art im Zusammenhang mitT
hier: es ist nur ein Platzhalter. So ist es effektiv behandelt, alsjava.lang.Object
.Aber Sie bauen können strukturierte Typen programmgesteuert mithilfe
TypeFactory
(Instanz, die überObjetMapper.getTypeFactory()
). Sie müssen nochClass
Instanzen darstellen, Schlüssel-und Wert-Typen, aber mit diesen Informationen ist es möglich zu konstruierenJavaType
Werte enthalten vollständige Typ-Informationen, die Sie benötigen.ObjectMapper.getTypeFactory()
löst mein problem? Danke.Haben Sie einen Blick auf seine Methode für die Konstruktion
JavaType
s. Z. B. entspricht derMap<String,Integer>
, die Sie verwenden würdenJavaType siMapType = typeFactory.constructMapType(Map.class, String.class, Integer.class)
. Und dann diese entlang vorbei stattTypeReference
oderClass
. Rest, wie Sie sagen, ist Links als übung für den Leser...Ich habe versucht, dies vor, aber das problem ist, dass mein Typ T ist ein generischer POJO. Die typeFactory.konstruieren* Methode sollte ich verwenden?
Wenn es nicht ein
Map
-, array-oderCollection
verwenden, sollten SieconstructParametricType
Können Sie mir zeigen, ein test-Fall, wo das funktioniert? Danke.
InformationsquelleAutor StaxMan