我一直在研究Jackson,但似乎需要先将Map转换为JSON,然后再将生成的JSON转换为POJO。
有没有一种直接将Map转换为POJO的方法?
我一直在研究Jackson,但似乎需要先将Map转换为JSON,然后再将生成的JSON转换为POJO。
有没有一种直接将Map转换为POJO的方法?
嗯,你也可以用Jackson来实现这一点(似乎更方便,因为你正在考虑使用jackson)。
使用ObjectMapper
的convertValue
方法:
final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
final MyPojo pojo = mapper.convertValue(map, MyPojo.class);
不需要将其转换为JSON字符串或其他格式;直接转换速度更快。
使用Gson的解决方案:
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(map);
MyPojo pojo = gson.fromJson(jsonElement, MyPojo.class);
map.toString()
会提供正确的字符串?toString()
的实现并不保证特定格式。 - AlikElzin-kilakaObjectMapper objectMapper = new ObjectMapper();
// Use this if all properties are not in the class
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final MyPojo pojo = objectMapper.convertValue(map, MyPojo.class);
和第一个答案一样,但我使用它时出了一个错误,因为我不想将Map的所有属性转换为类。我还发现objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
是解决方案。
如果你的类中有泛型类型,你应该在使用convertValue()
时使用TypeReference
。
final ObjectMapper mapper = new ObjectMapper();
final MyPojo<MyGenericType> pojo = mapper.convertValue(map, new TypeReference<MyPojo<MyGenericType>>() {});
您还可以使用它将POJO转换回java.util.Map
。
final ObjectMapper mapper = new ObjectMapper();
final Map<String, Object> map = mapper.convertValue(pojo, new TypeReference<Map<String, Object>>() {});
@JsonIgnoreProperties(ignoreUnknown = true)
吗? - bhdrk new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- Gurkirat Singh Guliani我测试了Jackson和BeanUtils,发现BeanUtils更快。
在我的机器上(Windows8.1,JDK1.7),我得到了这个结果。
BeanUtils t2-t1 = 286
Jackson t2-t1 = 2203
public class MainMapToPOJO {
public static final int LOOP_MAX_COUNT = 1000;
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
map.put("success", true);
map.put("data", "testString");
runBeanUtilsPopulate(map);
runJacksonMapper(map);
}
private static void runBeanUtilsPopulate(Map<String, Object> map) {
long t1 = System.currentTimeMillis();
for (int i = 0; i < LOOP_MAX_COUNT; i++) {
try {
TestClass bean = new TestClass();
BeanUtils.populate(bean, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
long t2 = System.currentTimeMillis();
System.out.println("BeanUtils t2-t1 = " + String.valueOf(t2 - t1));
}
private static void runJacksonMapper(Map<String, Object> map) {
long t1 = System.currentTimeMillis();
for (int i = 0; i < LOOP_MAX_COUNT; i++) {
ObjectMapper mapper = new ObjectMapper();
TestClass testClass = mapper.convertValue(map, TestClass.class);
}
long t2 = System.currentTimeMillis();
System.out.println("Jackson t2-t1 = " + String.valueOf(t2 - t1));
}}
Map
包含map.put("data","2016-06-26")
,而TestClass
具有一个字段private LocalDate data;
,那么使用Jackson可以完成这个任务,但是BeanUtils则会失败。 - Benjamin MObjectMapper
实例需要很多时间和资源,因此建议重复使用一个映射器实例,而不是每次都创建新的实例。我认为最好将其从测试循环中移出。 - Mixaz是的,绝对可以避免中间转换为JSON。使用类似Dozer的深拷贝工具,您可以直接将map转换为POJO。以下是一个简单的示例:
POJO示例:
public class MyPojo implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private Integer age;
private Double savings;
public MyPojo() {
super();
}
// Getters/setters
@Override
public String toString() {
return String.format(
"MyPojo[id = %s, name = %s, age = %s, savings = %s]", getId(),
getName(), getAge(), getSavings());
}
}
示例转换代码:
public class CopyTest {
@Test
public void testCopyMapToPOJO() throws Exception {
final Map<String, String> map = new HashMap<String, String>(4);
map.put("id", "5");
map.put("name", "Bob");
map.put("age", "23");
map.put("savings", "2500.39");
map.put("extra", "foo");
final DozerBeanMapper mapper = new DozerBeanMapper();
final MyPojo pojo = mapper.map(map, MyPojo.class);
System.out.println(pojo);
}
}
输出:
MyPojo[id = 5, name = Bob, age = 23, savings = 2500.39]
注意:如果您将源映射更改为 Map<String, Object>
,那么您可以复制任意深度嵌套的属性(使用Map<String, String>
只能获取一级)。
POJO
进行转换,如下所示: public static <T> T convert(Map<String, Object> aMap, Class<T> t) {
try {
return objectMapper
.convertValue(aMap, objectMapper.getTypeFactory().constructType(t));
} catch (Exception e) {
log.error("converting failed! aMap: {}, class: {}", getJsonString(aMap), t.getClass().getSimpleName(), e);
}
return null;
}
objectMapper.convertValue
之外,我不认为这个实用函数有任何价值。 - Jongwook Choi将Map转换为POJO的示例。请注意,Map键包含下划线,而字段变量是驼峰式。
User.class POJO
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class User {
@JsonProperty("user_name")
private String userName;
@JsonProperty("pass_word")
private String passWord;
}
App.class测试这个例子
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
public class App {
public static void main(String[] args) {
Map<String, String> info = new HashMap<>();
info.put("user_name", "Q10Viking");
info.put("pass_word", "123456");
ObjectMapper mapper = new ObjectMapper();
User user = mapper.convertValue(info, User.class);
System.out.println("-------------------------------");
System.out.println(user);
}
}
/**output
-------------------------------
User(userName=Q10Viking, passWord=123456)
*/
@Hamedz if use many data, use Jackson to convert light data, use apache... TestCase:
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'
。 - Shajeel AfzalMap<String, Object>
实例了吗? - fIwJlxSzApHEZIl