json、javaBean、xml互转的几种工具介绍 (转载)

时间:2021-11-17 03:13:16

工作中经常要用到Json、JavaBean、Xml之间的相互转换,用到了很多种方式,这里做下总结,以供参考。

现在主流的转换工具有json-lib、jackson、fastjson等,我为大家一一做简单介绍,主要还是以代码形式贴出如何简单应用这些工具的,更多高级功能还需大家深入研究。

首先是json-lib,算是很早的转换工具了,用的人很多,说实在现在完全不适合了,缺点比较多,依赖的第三方实在是比较多,效率低下,API也比较繁琐,说他纯粹是因为以前的老项目很多人都用到它。不废话,开始上代码。

需要的maven依赖:

  1. <!-- for json-lib -->
  2. <dependency>
  3. <groupId>net.sf.json-lib</groupId>
  4. <artifactId>json-lib</artifactId>
  5. <version>2.4</version>
  6. <classifier>jdk15</classifier>
  7. </dependency>
  8. <dependency>
  9. <groupId>xom</groupId>
  10. <artifactId>xom</artifactId>
  11. <version>1.1</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>xalan</groupId>
  15. <artifactId>xalan</artifactId>
  16. <version>2.7.1</version>
  17. </dependency>

使用json-lib实现多种转换

  1. import java.text.SimpleDateFormat;
  2. import java.util.Date;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Map.Entry;
  7. import javax.swing.text.Document;
  8. import net.sf.ezmorph.Morpher;
  9. import net.sf.ezmorph.MorpherRegistry;
  10. import net.sf.ezmorph.bean.BeanMorpher;
  11. import net.sf.ezmorph.object.DateMorpher;
  12. import net.sf.json.JSON;
  13. import net.sf.json.JSONArray;
  14. import net.sf.json.JSONObject;
  15. import net.sf.json.JSONSerializer;
  16. import net.sf.json.JsonConfig;
  17. import net.sf.json.processors.JsonValueProcessor;
  18. import net.sf.json.util.CycleDetectionStrategy;
  19. import net.sf.json.util.JSONUtils;
  20. import net.sf.json.xml.XMLSerializer;
  21. /**
  22. * json-lib utils
  23. * @author magic_yy
  24. * @see json-lib.sourceforge.net/
  25. * @see https://github.com/aalmiray/Json-lib
  26. *
  27. */
  28. public class JsonLibUtils {
  29. public static JsonConfig config = new JsonConfig();
  30. static{
  31. config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);//忽略循环,避免死循环
  32. config.registerJsonValueProcessor(Date.class, new JsonValueProcessor() {//处理Date日期转换
  33. @Override
  34. public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2) {
  35. SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  36. Date d=(Date) arg1;
  37. return sdf.format(d);
  38. }
  39. @Override
  40. public Object processArrayValue(Object arg0, JsonConfig arg1) {
  41. return null;
  42. }
  43. });
  44. }
  45. /**
  46. * java object convert to json string
  47. */
  48. public static String pojo2json(Object obj){
  49. return JSONObject.fromObject(obj,config).toString();//可以用toString(1)来实现格式化,便于阅读
  50. }
  51. /**
  52. * array、map、Javabean convert to json string
  53. */
  54. public static String object2json(Object obj){
  55. return JSONSerializer.toJSON(obj).toString();
  56. }
  57. /**
  58. * xml string convert to json string
  59. */
  60. public static String xml2json(String xmlString){
  61. XMLSerializer xmlSerializer = new XMLSerializer();
  62. JSON json = xmlSerializer.read(xmlString);
  63. return json.toString();
  64. }
  65. /**
  66. * xml document convert to json string
  67. */
  68. public static String xml2json(Document xmlDocument){
  69. return xml2json(xmlDocument.toString());
  70. }
  71. /**
  72. * json string convert to javaBean
  73. * @param <T>
  74. */
  75. @SuppressWarnings("unchecked")
  76. public static <T> T json2pojo(String jsonStr,Class<T> clazz){
  77. JSONObject jsonObj = JSONObject.fromObject(jsonStr);
  78. T obj = (T) JSONObject.toBean(jsonObj, clazz);
  79. return obj;
  80. }
  81. /**
  82. * json string convert to map
  83. */
  84. public static Map<String,Object> json2map(String jsonStr){
  85. JSONObject jsonObj = JSONObject.fromObject(jsonStr);
  86. Map<String,Object> result = (Map<String, Object>) JSONObject.toBean(jsonObj, Map.class);
  87. return result;
  88. }
  89. /**
  90. * json string convert to map with javaBean
  91. */
  92. public static <T> Map<String,T> json2map(String jsonStr,Class<T> clazz){
  93. JSONObject jsonObj = JSONObject.fromObject(jsonStr);
  94. Map<String,T> map = new HashMap<String, T>();
  95. Map<String,T> result = (Map<String, T>) JSONObject.toBean(jsonObj, Map.class, map);
  96. MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
  97. Morpher dynaMorpher = new BeanMorpher(clazz,morpherRegistry);
  98. morpherRegistry.registerMorpher(dynaMorpher);
  99. morpherRegistry.registerMorpher(new DateMorpher(new String[]{ "yyyy-MM-dd HH:mm:ss" }));
  100. for (Entry<String,T> entry : result.entrySet()) {
  101. map.put(entry.getKey(), (T)morpherRegistry.morph(clazz, entry.getValue()));
  102. }
  103. return map;
  104. }
  105. /**
  106. * json string convert to array
  107. */
  108. public static Object[] json2arrays(String jsonString) {
  109. JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON(jsonString);
  110. //      JSONArray jsonArray = JSONArray.fromObject(jsonString);
  111. JsonConfig jsonConfig = new JsonConfig();
  112. jsonConfig.setArrayMode(JsonConfig.MODE_OBJECT_ARRAY);
  113. Object[] objArray = (Object[]) JSONSerializer.toJava(jsonArray,jsonConfig);
  114. return objArray;
  115. }
  116. /**
  117. * json string convert to list
  118. * @param <T>
  119. */
  120. @SuppressWarnings({ "unchecked", "deprecation" })
  121. public static <T> List<T> json2list(String jsonString, Class<T> pojoClass){
  122. JSONArray jsonArray = JSONArray.fromObject(jsonString);
  123. return JSONArray.toList(jsonArray, pojoClass);
  124. }
  125. /**
  126. * object convert to xml string
  127. */
  128. public static String obj2xml(Object obj){
  129. XMLSerializer xmlSerializer = new XMLSerializer();
  130. return xmlSerializer.write(JSONSerializer.toJSON(obj));
  131. }
  132. /**
  133. * json string convert to xml string
  134. */
  135. public static String json2xml(String jsonString){
  136. XMLSerializer xmlSerializer = new XMLSerializer();
  137. xmlSerializer.setTypeHintsEnabled(true);//是否保留元素类型标识,默认true
  138. xmlSerializer.setElementName("e");//设置元素标签,默认e
  139. xmlSerializer.setArrayName("a");//设置数组标签,默认a
  140. xmlSerializer.setObjectName("o");//设置对象标签,默认o
  141. return xmlSerializer.write(JSONSerializer.toJSON(jsonString));
  142. }
  143. }

都是些比较常见的转换,写的不是很全,基本够用了,测试代码如下:

  1. import java.util.ArrayList;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. import net.sf.ezmorph.test.ArrayAssertions;
  6. import org.junit.Assert;
  7. import org.junit.Test;
  8. public class JsonLibUtilsTest {
  9. @Test
  10. public void pojo2json_test(){
  11. User user = new User(1, "张三");
  12. String json = JsonLibUtils.pojo2json(user);
  13. Assert.assertEquals("{\"id\":1,\"name\":\"张三\"}", json);
  14. }
  15. @Test
  16. public void object2json_test(){
  17. int[] intArray = new int[]{1,4,5};
  18. String json = JsonLibUtils.object2json(intArray);
  19. Assert.assertEquals("[1,4,5]", json);
  20. User user1 = new User(1,"张三");
  21. User user2 = new User(2,"李四");
  22. User[] userArray = new User[]{user1,user2};
  23. String json2 = JsonLibUtils.object2json(userArray);
  24. Assert.assertEquals("[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]", json2);
  25. List<User> userList = new ArrayList<>();
  26. userList.add(user1);
  27. userList.add(user2);
  28. String json3 = JsonLibUtils.object2json(userList);
  29. Assert.assertEquals("[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]", json3);
  30. //这里的map的key必须为String类型
  31. Map<String,Object> map = new HashMap<>();
  32. map.put("id", 1);
  33. map.put("name", "张三");
  34. String json4 = JsonLibUtils.object2json(map);
  35. Assert.assertEquals("{\"id\":1,\"name\":\"张三\"}", json4);
  36. Map<String,User> map2 = new HashMap<>();
  37. map2.put("user1", user1);
  38. map2.put("user2", user2);
  39. String json5 = JsonLibUtils.object2json(map2);
  40. Assert.assertEquals("{\"user2\":{\"id\":2,\"name\":\"李四\"},\"user1\":{\"id\":1,\"name\":\"张三\"}}", json5);
  41. }
  42. @Test
  43. public void xml2json_test(){
  44. String xml1 = "<User><id>1</id><name>张三</name></User>";
  45. String json = JsonLibUtils.xml2json(xml1);
  46. Assert.assertEquals("{\"id\":\"1\",\"name\":\"张三\"}", json);
  47. String xml2 = "<Response><CustID>1300000428</CustID><Items><Item><Sku_ProductNo>sku_0004</Sku_ProductNo></Item><Item><Sku_ProductNo>0005</Sku_ProductNo></Item></Items></Response>";
  48. String json2 = JsonLibUtils.xml2json(xml2);
  49. //处理数组时expected是处理结果,但不是我们想要的格式
  50. String expected = "{\"CustID\":\"1300000428\",\"Items\":[{\"Sku_ProductNo\":\"sku_0004\"},{\"Sku_ProductNo\":\"0005\"}]}";
  51. Assert.assertEquals(expected, json2);
  52. //实际上我们想要的是expected2这种格式,所以用json-lib来实现含有数组的xml to json是不行的
  53. String expected2 = "{\"CustID\":\"1300000428\",\"Items\":{\"Item\":[{\"Sku_ProductNo\":\"sku_0004\"},{\"Sku_ProductNo\":\"0005\"}]}}";
  54. Assert.assertEquals(expected2, json2);
  55. }
  56. @Test
  57. public void json2arrays_test(){
  58. String json = "[\"张三\",\"李四\"]";
  59. Object[] array = JsonLibUtils.json2arrays(json);
  60. Object[] expected = new Object[] { "张三", "李四" };
  61. ArrayAssertions.assertEquals(expected, array);
  62. //无法将JSON字符串转换为对象数组
  63. String json2 = "[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]";
  64. Object[] array2 = JsonLibUtils.json2arrays(json2);
  65. User user1 = new User(1,"张三");
  66. User user2 = new User(2,"李四");
  67. Object[] expected2 = new Object[] { user1, user2 };
  68. ArrayAssertions.assertEquals(expected2, array2);
  69. }
  70. @Test
  71. public void json2list_test(){
  72. String json = "[\"张三\",\"李四\"]";
  73. List<String> list = JsonLibUtils.json2list(json, String.class);
  74. Assert.assertTrue(list.size()==2&&list.get(0).equals("张三")&&list.get(1).equals("李四"));
  75. String json2 = "[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]";
  76. List<User> list2 = JsonLibUtils.json2list(json2, User.class);
  77. Assert.assertTrue(list2.size()==2&&list2.get(0).getId()==1&&list2.get(1).getId()==2);
  78. }
  79. @Test
  80. public void json2pojo_test(){
  81. String json = "{\"id\":1,\"name\":\"张三\"}";
  82. User user = (User) JsonLibUtils.json2pojo(json, User.class);
  83. Assert.assertEquals(json, user.toString());
  84. }
  85. @Test
  86. public void json2map_test(){
  87. String json = "{\"id\":1,\"name\":\"张三\"}";
  88. Map map = JsonLibUtils.json2map(json);
  89. int id = Integer.parseInt(map.get("id").toString());
  90. String name = map.get("name").toString();
  91. System.out.println(name);
  92. Assert.assertTrue(id==1&&name.equals("张三"));
  93. String json2 = "{\"user2\":{\"id\":2,\"name\":\"李四\"},\"user1\":{\"id\":1,\"name\":\"张三\"}}";
  94. Map map2 = JsonLibUtils.json2map(json2, User.class);
  95. System.out.println(map2);
  96. }
  97. @Test
  98. public void json2xml_test(){
  99. String json = "{\"id\":1,\"name\":\"张三\"}";
  100. String xml = JsonLibUtils.json2xml(json);
  101. Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<o><id type=\"number\">1</id><name type=\"string\">张三</name></o>\r\n", xml);
  102. System.out.println(xml);
  103. String json2 = "[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]";
  104. String xml2 = JsonLibUtils.json2xml(json2);
  105. System.out.println(xml2);
  106. Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<a><e class=\"object\"><id type=\"number\">1</id><name type=\"string\">张三</name></e><e class=\"object\"><id type=\"number\">2</id><name type=\"string\">李四</name></e></a>\r\n", xml2);
  107. }
  108. public static class User{
  109. private int id;
  110. private String name;
  111. public User() {
  112. }
  113. public User(int id, String name) {
  114. this.id = id;
  115. this.name = name;
  116. }
  117. @Override
  118. public String toString() {
  119. return "{\"id\":"+id+",\"name\":\""+name+"\"}";
  120. }
  121. public int getId() {
  122. return id;
  123. }
  124. public void setId(int id) {
  125. this.id = id;
  126. }
  127. public String getName() {
  128. return name;
  129. }
  130. public void setName(String name) {
  131. this.name = name;
  132. }
  133. }
  134. }

json-lib在XML转换为JSON在有数组的情况下会有问题,还有在JSON转换为XML时都会有元素标识如<o><a><e>等,在一般情况下我们可能都不需要,暂时还不知道如何过滤这些元素名称。

因为json-lib的种种缺点,基本停止了更新,也不支持注解转换,后来便有了jackson流行起来,它比json-lib的转换效率要高很多,依赖很少,社区也比较活跃,它分为3个部分:

  1. Streaming (docs) ("jackson-core") defines low-level streaming API, and includes JSON-specific implementations
  2. Annotations (docs) ("jackson-annotations") contains standard Jackson annotations
  3. Databind (docs) ("jackson-databind") implements data-binding (and object serialization) support on streaming package; it depends both on streaming and annotations packages

我们依旧开始上代码,首先是它的依赖:

  1. <!-- for jackson -->
  2. <dependency>
  3. <groupId>com.fasterxml.jackson.dataformat</groupId>
  4. <artifactId>jackson-dataformat-xml</artifactId>
  5. <version>2.1.3</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>com.fasterxml.jackson.core</groupId>
  9. <artifactId>jackson-databind</artifactId>
  10. <version>2.1.3</version>
  11. <type>java-source</type>
  12. <scope>compile</scope>
  13. </dependency>

这里我要说下,有很多基于jackson的工具,大家可以按照自己的实际需求来需找对应的依赖,我这里为了方便转换xml所以用了dataformat-xml和databind

使用jackson实现多种转换:

  1. package cn.yangyong.fodder.util;
  2. import java.io.StringWriter;
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Map.Entry;
  8. import com.fasterxml.jackson.core.JsonGenerator;
  9. import com.fasterxml.jackson.core.JsonParser;
  10. import com.fasterxml.jackson.core.type.TypeReference;
  11. import com.fasterxml.jackson.databind.JsonNode;
  12. import com.fasterxml.jackson.databind.ObjectMapper;
  13. import com.fasterxml.jackson.dataformat.xml.XmlMapper;
  14. /**
  15. * jsonson utils
  16. * @see http://jackson.codehaus.org/
  17. * @see https://github.com/FasterXML/jackson
  18. * @see http://wiki.fasterxml.com/JacksonHome
  19. * @author magic_yy
  20. *
  21. */
  22. public class JacksonUtils {
  23. private static ObjectMapper objectMapper = new ObjectMapper();
  24. private static XmlMapper xmlMapper = new XmlMapper();
  25. /**
  26. * javaBean,list,array convert to json string
  27. */
  28. public static String obj2json(Object obj) throws Exception{
  29. return objectMapper.writeValueAsString(obj);
  30. }
  31. /**
  32. * json string convert to javaBean
  33. */
  34. public static <T> T json2pojo(String jsonStr,Class<T> clazz) throws Exception{
  35. return objectMapper.readValue(jsonStr, clazz);
  36. }
  37. /**
  38. * json string convert to map
  39. */
  40. public static <T> Map<String,Object> json2map(String jsonStr)throws Exception{
  41. return objectMapper.readValue(jsonStr, Map.class);
  42. }
  43. /**
  44. * json string convert to map with javaBean
  45. */
  46. public static <T> Map<String,T> json2map(String jsonStr,Class<T> clazz)throws Exception{
  47. Map<String,Map<String,Object>> map =  objectMapper.readValue(jsonStr, new TypeReference<Map<String,T>>() {
  48. });
  49. Map<String,T> result = new HashMap<String, T>();
  50. for (Entry<String, Map<String,Object>> entry : map.entrySet()) {
  51. result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
  52. }
  53. return result;
  54. }
  55. /**
  56. * json array string convert to list with javaBean
  57. */
  58. public static <T> List<T> json2list(String jsonArrayStr,Class<T> clazz)throws Exception{
  59. List<Map<String,Object>> list = objectMapper.readValue(jsonArrayStr, new TypeReference<List<T>>() {
  60. });
  61. List<T> result = new ArrayList<>();
  62. for (Map<String, Object> map : list) {
  63. result.add(map2pojo(map, clazz));
  64. }
  65. return result;
  66. }
  67. /**
  68. * map convert to javaBean
  69. */
  70. public static <T> T map2pojo(Map map,Class<T> clazz){
  71. return objectMapper.convertValue(map, clazz);
  72. }
  73. /**
  74. * json string convert to xml string
  75. */
  76. public static String json2xml(String jsonStr)throws Exception{
  77. JsonNode root = objectMapper.readTree(jsonStr);
  78. String xml = xmlMapper.writeValueAsString(root);
  79. return xml;
  80. }
  81. /**
  82. * xml string convert to json string
  83. */
  84. public static String xml2json(String xml)throws Exception{
  85. StringWriter w = new StringWriter();
  86. JsonParser jp = xmlMapper.getFactory().createParser(xml);
  87. JsonGenerator jg = objectMapper.getFactory().createGenerator(w);
  88. while (jp.nextToken() != null) {
  89. jg.copyCurrentEvent(jp);
  90. }
  91. jp.close();
  92. jg.close();
  93. return w.toString();
  94. }
  95. }

只用了其中的一部分功能,有关annotation部分因为从没用到所以没写,大家可以自行研究下,我这里就不提了。jackson的测试代码如下:

  1. package cn.yangyong.fodder.util;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import org.junit.Assert;
  7. import org.junit.Test;
  8. import cn.yangyong.fodder.util.JacksonUtils;
  9. public class JacksonUtilsTest {
  10. @Test
  11. public void test_pojo2json() throws Exception{
  12. String json = JacksonUtils.obj2json(new User(1, "张三"));
  13. Assert.assertEquals("{\"id\":1,\"name\":\"张三\"}", json);
  14. List<User> list = new ArrayList<>();
  15. list.add(new User(1, "张三"));
  16. list.add(new User(2, "李四"));
  17. String json2 = JacksonUtils.obj2json(list);
  18. Assert.assertEquals("[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]", json2);
  19. Map<String,User> map = new HashMap<>();
  20. map.put("user1", new User(1, "张三"));
  21. map.put("user2", new User(2, "李四"));
  22. String json3 = JacksonUtils.obj2json(map);
  23. Assert.assertEquals("{\"user2\":{\"id\":2,\"name\":\"李四\"},\"user1\":{\"id\":1,\"name\":\"张三\"}}", json3);
  24. }
  25. @Test
  26. public void test_json2pojo() throws Exception{
  27. String json = "{\"id\":1,\"name\":\"张三\"}";
  28. User user = JacksonUtils.json2pojo(json, User.class);
  29. Assert.assertTrue(user.getId()==1&&user.getName().equals("张三"));
  30. }
  31. @Test
  32. public void test_json2map() throws Exception{
  33. String json = "{\"id\":1,\"name\":\"张三\"}";
  34. Map<String,Object> map = JacksonUtils.json2map(json);
  35. Assert.assertEquals("{id=1, name=张三}", map.toString());
  36. String json2 = "{\"user2\":{\"id\":2,\"name\":\"李四\"},\"user1\":{\"id\":1,\"name\":\"张三\"}}";
  37. Map<String,User> map2 = JacksonUtils.json2map(json2, User.class);
  38. User user1 = map2.get("user1");
  39. User user2 = map2.get("user2");
  40. Assert.assertTrue(user1.getId()==1&&user1.getName().equals("张三"));
  41. Assert.assertTrue(user2.getId()==2&&user2.getName().equals("李四"));
  42. }
  43. @Test
  44. public void test_json2list() throws Exception{
  45. String json = "[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]";
  46. List<User> list = JacksonUtils.json2list(json,User.class);
  47. User user1 = list.get(0);
  48. User user2 = list.get(1);
  49. Assert.assertTrue(user1.getId()==1&&user1.getName().equals("张三"));
  50. Assert.assertTrue(user2.getId()==2&&user2.getName().equals("李四"));
  51. }
  52. @Test
  53. public void test_map2pojo(){
  54. Map<String,Object> map = new HashMap<String, Object>();
  55. map.put("id", 1);
  56. map.put("name", "张三");
  57. User user = JacksonUtils.map2pojo(map, User.class);
  58. Assert.assertTrue(user.getId()==1&&user.getName().equals("张三"));
  59. System.out.println(user);
  60. }
  61. @Test
  62. public void test_json2xml() throws Exception{
  63. String json = "{\"id\":1,\"name\":\"张三\"}";
  64. String xml = JacksonUtils.json2xml(json);
  65. Assert.assertEquals("<ObjectNode xmlns=\"\"><id>1</id><name>张三</name></ObjectNode>", xml);
  66. String json2 = "{\"Items\":{\"RequestInterfaceSku\":[{\"Sku_ProductNo\":\"sku_0004\"},{\"Sku_ProductNo\":\"sku_0005\"}]}}";
  67. String xml2 = JacksonUtils.json2xml(json2);
  68. Assert.assertEquals("<ObjectNode xmlns=\"\"><Items><RequestInterfaceSku><Sku_ProductNo>sku_0004</Sku_ProductNo></RequestInterfaceSku><RequestInterfaceSku><Sku_ProductNo>sku_0005</Sku_ProductNo></RequestInterfaceSku></Items></ObjectNode>", xml2);
  69. }
  70. @Test
  71. public void test_xml2json() throws Exception{
  72. String xml = "<ObjectNode xmlns=\"\"><id>1</id><name>张三</name></ObjectNode>";
  73. String json = JacksonUtils.xml2json(xml);
  74. Assert.assertEquals("{\"id\":1,\"name\":\"张三\"}", json);
  75. String xml2 = "<ObjectNode xmlns=\"\"><Items><RequestInterfaceSku><Sku_ProductNo>sku_0004</Sku_ProductNo></RequestInterfaceSku><RequestInterfaceSku><Sku_ProductNo>sku_0005</Sku_ProductNo></RequestInterfaceSku></Items></ObjectNode>";
  76. String json2 = JacksonUtils.xml2json(xml2);
  77. //expected2是我们想要的格式,但实际结果确实expected1,所以用jackson实现xml直接转换为json在遇到数组时是不可行的
  78. String expected1 = "{\"Items\":{\"RequestInterfaceSku\":{\"Sku_ProductNo\":\"sku_0004\"},\"RequestInterfaceSku\":{\"Sku_ProductNo\":\"sku_0005\"}}}";
  79. String expected2 = "{\"Items\":{\"RequestInterfaceSku\":[{\"Sku_ProductNo\":\"sku_0004\"},{\"Sku_ProductNo\":\"sku_0005\"}]}}";
  80. Assert.assertEquals(expected1, json2);
  81. Assert.assertEquals(expected2, json2);
  82. }
  83. private static class User{
  84. private int id;
  85. private String name;
  86. public User() {
  87. }
  88. public User(int id, String name) {
  89. this.id = id;
  90. this.name = name;
  91. }
  92. @Override
  93. public String toString() {
  94. return "{\"id\":"+id+",\"name\":\""+name+"\"}";
  95. }
  96. public int getId() {
  97. return id;
  98. }
  99. public void setId(int id) {
  100. this.id = id;
  101. }
  102. public String getName() {
  103. return name;
  104. }
  105. public void setName(String name) {
  106. this.name = name;
  107. }
  108. }
  109. }

测试后发现xml转换为json时也有问题,居然不认识数组,真是悲剧。好吧就由它吧,也可能是我的方法不正确。

jackson一直很主流,社区和文档支持也很充足,但有人还是嫌它不够快,不够简洁,于是便有了fastjson,看名字就知道它的主要特点就是快,可能在功能和其他支持方面不能和jackson媲美,但天下武功,唯快不破,这就决定了fastjson有了一定的市场。不解释,直接上代码。

  1. <!-- for fastjson -->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>fastjson</artifactId>
  5. <version>1.1.33</version>
  6. </dependency>

沃,除了自身零依赖,再看它的API使用。
使用fastjson实现多种转换:

  1. package cn.yangyong.fodder.util;
  2. import java.util.Date;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Map.Entry;
  6. import com.alibaba.fastjson.JSON;
  7. import com.alibaba.fastjson.JSONObject;
  8. import com.alibaba.fastjson.TypeReference;
  9. import com.alibaba.fastjson.serializer.SerializeConfig;
  10. import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
  11. /**
  12. * fastjson utils
  13. *
  14. * @author magic_yy
  15. * @see https://github.com/alibaba/fastjson
  16. * @see http://code.alibabatech.com/wiki/display/FastJSON
  17. */
  18. public class FastJsonUtils {
  19. private static SerializeConfig mapping = new SerializeConfig();
  20. static{
  21. mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
  22. }
  23. /**
  24. * javaBean、list、map convert to json string
  25. */
  26. public static String obj2json(Object obj){
  27. //      return JSON.toJSONString(obj,SerializerFeature.UseSingleQuotes);//使用单引号
  28. //      return JSON.toJSONString(obj,true);//格式化数据,方便阅读
  29. return JSON.toJSONString(obj,mapping);
  30. }
  31. /**
  32. * json string convert to javaBean、map
  33. */
  34. public static <T> T json2obj(String jsonStr,Class<T> clazz){
  35. return JSON.parseObject(jsonStr,clazz);
  36. }
  37. /**
  38. * json array string convert to list with javaBean
  39. */
  40. public static <T> List<T> json2list(String jsonArrayStr,Class<T> clazz){
  41. return JSON.parseArray(jsonArrayStr, clazz);
  42. }
  43. /**
  44. * json string convert to map
  45. */
  46. public static <T> Map<String,Object> json2map(String jsonStr){
  47. return json2obj(jsonStr, Map.class);
  48. }
  49. /**
  50. * json string convert to map with javaBean
  51. */
  52. public static <T> Map<String,T> json2map(String jsonStr,Class<T> clazz){
  53. Map<String,T> map = JSON.parseObject(jsonStr, new TypeReference<Map<String, T>>() {});
  54. for (Entry<String, T> entry : map.entrySet()) {
  55. JSONObject obj = (JSONObject) entry.getValue();
  56. map.put(entry.getKey(), JSONObject.toJavaObject(obj, clazz));
  57. }
  58. return map;
  59. }
  60. }

API真的很简洁,很方便,这里依旧只用了部分功能,关于注解部分请大家自行研究。测试代码如下:

  1. package cn.yangyong.fodder.util;
  2. import java.text.SimpleDateFormat;
  3. import java.util.ArrayList;
  4. import java.util.Date;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. import org.junit.Assert;
  9. import org.junit.Test;
  10. public class FastJsonTest {
  11. @Test
  12. public void test_dateFormat(){
  13. Date date = new Date();
  14. String json = FastJsonUtils.obj2json(date);
  15. String expected = "\""+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)+"\"";
  16. Assert.assertEquals(expected, json);
  17. }
  18. @Test
  19. public void test_obj2json(){
  20. User user = new User(1, "张三");
  21. String json = FastJsonUtils.obj2json(user);
  22. Assert.assertEquals("{\"id\":1,\"name\":\"张三\"}", json);
  23. List<User> list = new ArrayList<>();
  24. list.add(new User(1, "张三"));
  25. list.add(new User(2, "李四"));
  26. String json2 = FastJsonUtils.obj2json(list);
  27. Assert.assertEquals("[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]", json2);
  28. Map<String,User> map = new HashMap<>();
  29. map.put("user1", new User(1, "张三"));
  30. map.put("user2", new User(2, "李四"));
  31. String json3 = FastJsonUtils.obj2json(map);
  32. Assert.assertEquals("{\"user1\":{\"id\":1,\"name\":\"张三\"},\"user2\":{\"id\":2,\"name\":\"李四\"}}", json3);
  33. }
  34. @Test
  35. public void test_json2obj(){
  36. String json = "{\"id\":1,\"name\":\"张三\"}";
  37. User user = FastJsonUtils.json2obj(json, User.class);
  38. Assert.assertTrue(user.getId()==1&&user.getName().equals("张三"));
  39. }
  40. @Test
  41. public void test_json2list(){
  42. String json = "[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]";
  43. List<User> list = FastJsonUtils.json2list(json, User.class);
  44. User user1 = list.get(0);
  45. User user2 = list.get(1);
  46. Assert.assertTrue(user1.getId()==1&&user1.getName().equals("张三"));
  47. Assert.assertTrue(user2.getId()==2&&user2.getName().equals("李四"));
  48. }
  49. @Test
  50. public void test_json2map() throws Exception{
  51. String json = "{\"id\":1,\"name\":\"张三\"}";
  52. Map<String,Object> map = FastJsonUtils.json2map(json);
  53. Assert.assertEquals("{id=1, name=张三}", map.toString());
  54. String json2 = "{\"user2\":{\"id\":2,\"name\":\"李四\"},\"user1\":{\"id\":1,\"name\":\"张三\"}}";
  55. Map<String,User> map2 = FastJsonUtils.json2map(json2, User.class);
  56. User user1 = map2.get("user1");
  57. User user2 = map2.get("user2");
  58. Assert.assertTrue(user1.getId()==1&&user1.getName().equals("张三"));
  59. Assert.assertTrue(user2.getId()==2&&user2.getName().equals("李四"));
  60. }
  61. private static class User{
  62. private int id;
  63. private String name;
  64. public User() {
  65. }
  66. public User(int id, String name) {
  67. this.id = id;
  68. this.name = name;
  69. }
  70. @Override
  71. public String toString() {
  72. return "{\"id\":"+id+",\"name\":\""+name+"\"}";
  73. }
  74. public int getId() {
  75. return id;
  76. }
  77. public void setId(int id) {
  78. this.id = id;
  79. }
  80. public String getName() {
  81. return name;
  82. }
  83. public void setName(String name) {
  84. this.name = name;
  85. }
  86. }
  87. }

只有json和javaBean直接的相互转换,没有xml的转换,真可惜。好吧,谁叫人家定位不一样呢,要想功能全还是用jackson吧。

最后给大家介绍下json和xml之间不依赖javaBean直接相互转换的工具staxon,相比很多时候大家都想动态的将json和xml相互转换却不依赖其他javaBean,自己写真的是很麻烦,要人命,用jackson等其他转换工具时结果都不是我想要的

比如有下面xml和json,他们是等价的:

  1. <Response>
  2. <CustID>1300000428</CustID>
  3. <CompID>1100000324</CompID>
  4. <Items>
  5. <Item>
  6. <Sku_ProductNo>sku_0004</Sku_ProductNo>
  7. <Wms_Code>1700386977</Wms_Code>
  8. <Sku_Response>T</Sku_Response>
  9. <Sku_Reason></Sku_Reason>
  10. </Item>
  11. <Item>
  12. <Sku_ProductNo>0005</Sku_ProductNo>
  13. <Wms_Code>1700386978</Wms_Code>
  14. <Sku_Response>T</Sku_Response>
  15. <Sku_Reason></Sku_Reason>
  16. </Item>
  17. </Items>
  18. </Response>
  1. {
  2. "Response" : {
  3. "CustID" : 1300000428,
  4. "CompID" : 1100000324,
  5. "Items" : {
  6. "Item" : [ {
  7. "Sku_ProductNo" : "sku_0004",
  8. "Wms_Code" : 1700386977,
  9. "Sku_Response" : "T",
  10. "Sku_Reason" : null
  11. }, {
  12. "Sku_ProductNo" : "0005",
  13. "Wms_Code" : 1700386978,
  14. "Sku_Response" : "T",
  15. "Sku_Reason" : null
  16. } ]
  17. }
  18. }
  19. }

下面我们使用staxon来实现上面2种互转

  1. <!-- for staxon -->
  2. lt;dependency>
  3. <groupId>de.odysseus.staxon</groupId>
  4. <artifactId>staxon</artifactId>
  5. <version>1.2</version>
  6. lt;/dependency>

嗯,没有第三方依赖,上转换代码:

  1. package cn.yangyong.fodder.util;
  2. import java.io.IOException;
  3. import java.io.StringReader;
  4. import java.io.StringWriter;
  5. import javax.xml.stream.XMLEventReader;
  6. import javax.xml.stream.XMLEventWriter;
  7. import javax.xml.stream.XMLInputFactory;
  8. import javax.xml.stream.XMLOutputFactory;
  9. import de.odysseus.staxon.json.JsonXMLConfig;
  10. import de.odysseus.staxon.json.JsonXMLConfigBuilder;
  11. import de.odysseus.staxon.json.JsonXMLInputFactory;
  12. import de.odysseus.staxon.json.JsonXMLOutputFactory;
  13. import de.odysseus.staxon.xml.util.PrettyXMLEventWriter;
  14. /**
  15. * json and xml converter
  16. * @author magic_yy
  17. * @see https://github.com/beckchr/staxon
  18. * @see https://github.com/beckchr/staxon/wiki
  19. *
  20. */
  21. public class StaxonUtils {
  22. /**
  23. * json string convert to xml string
  24. */
  25. public static String json2xml(String json){
  26. StringReader input = new StringReader(json);
  27. StringWriter output = new StringWriter();
  28. JsonXMLConfig config = new JsonXMLConfigBuilder().multiplePI(false).repairingNamespaces(false).build();
  29. try {
  30. XMLEventReader reader = new JsonXMLInputFactory(config).createXMLEventReader(input);
  31. XMLEventWriter writer = XMLOutputFactory.newInstance().createXMLEventWriter(output);
  32. writer = new PrettyXMLEventWriter(writer);
  33. writer.add(reader);
  34. reader.close();
  35. writer.close();
  36. } catch( Exception e){
  37. e.printStackTrace();
  38. } finally {
  39. try {
  40. output.close();
  41. input.close();
  42. } catch (IOException e) {
  43. e.printStackTrace();
  44. }
  45. }
  46. if(output.toString().length()>=38){//remove <?xml version="1.0" encoding="UTF-8"?>
  47. return output.toString().substring(39);
  48. }
  49. return output.toString();
  50. }
  51. /**
  52. * xml string convert to json string
  53. */
  54. public static String xml2json(String xml){
  55. StringReader input = new StringReader(xml);
  56. StringWriter output = new StringWriter();
  57. JsonXMLConfig config = new JsonXMLConfigBuilder().autoArray(true).autoPrimitive(true).prettyPrint(true).build();
  58. try {
  59. XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(input);
  60. XMLEventWriter writer = new JsonXMLOutputFactory(config).createXMLEventWriter(output);
  61. writer.add(reader);
  62. reader.close();
  63. writer.close();
  64. } catch( Exception e){
  65. e.printStackTrace();
  66. } finally {
  67. try {
  68. output.close();
  69. input.close();
  70. } catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. return output.toString();
  75. }
  76. }

当然,这里我也就只用到了它的部分功能,最主要的还是json和xml直接的转换了撒。其他功能自己看咯,不多做介绍了。测试代码如下:

  1. package cn.yangyong.fodder.util;
  2. import org.junit.Test;
  3. public class StaxonUtilsTest {
  4. @Test
  5. public void test_json2xml(){
  6. String json = "{\"Response\" : {\"CustID\" : 1300000428,\"CompID\" : 1100000324,\"Items\" : {\"Item\" : [ {\"Sku_ProductNo\" : \"sku_0004\",\"Wms_Code\" : 1700386977,\"Sku_Response\" : \"T\",\"Sku_Reason\" : null}, {\"Sku_ProductNo\" : \"0005\",\"Wms_Code\" : 1700386978,\"Sku_Response\" : \"T\",\"Sku_Reason\" : null}]}}}";
  7. String xml = StaxonUtils.json2xml(json);
  8. System.out.println(xml);
  9. }
  10. @Test
  11. public void test_xml2json(){
  12. String xml = "<Response><CustID>1300000428</CustID><CompID>1100000324</CompID><Items><Item><Sku_ProductNo>sku_0004</Sku_ProductNo><Wms_Code>1700386977</Wms_Code><Sku_Response>T</Sku_Response><Sku_Reason></Sku_Reason></Item><Item><Sku_ProductNo>0005</Sku_ProductNo><Wms_Code>1700386978</Wms_Code><Sku_Response>T</Sku_Response><Sku_Reason></Sku_Reason></Item></Items></Response>";
  13. String json = StaxonUtils.xml2json(xml);
  14. System.out.println(json);
  15. }
  16. }