1. 程式人生 > >json、javaBean、xml互轉的幾種工具

json、javaBean、xml互轉的幾種工具

      工作中經常要用到Json、JavaBean、Xml之間的相互轉換,用到了很多種方式,這裡做下總結,以供參考。

  現在主流的轉換工具有json-lib、jackson、fastjson等,我為大家一一做簡單介紹,主要還是以程式碼形式貼出如何簡單應用這些工具的,更多高階功能還需大家深入研究。

首先是json-lib,算是很早的轉換工具了,用的人很多,說實在現在完全不適合了,缺點比較多,依賴的第三方實在是比較多,效率低下,API也比較繁瑣,說他純粹是因為以前的老專案很多人都用到它。不廢話,開始上程式碼。

需要的maven依賴:

複製程式碼
<dependency>  
        <
groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> <dependency> <groupId>xom</groupId> <artifactId
>xom</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>xalan</groupId> <artifactId>xalan</artifactId> <version>2.7.1</version> </dependency>
複製程式碼

使用json-lib實現多種轉換

複製程式碼
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.swing.text.Document; import net.sf.ezmorph.Morpher; import net.sf.ezmorph.MorpherRegistry; import net.sf.ezmorph.bean.BeanMorpher; import net.sf.ezmorph.object.DateMorpher; import net.sf.json.JSON; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import net.sf.json.JSONSerializer; import net.sf.json.JsonConfig; import net.sf.json.processors.JsonValueProcessor; import net.sf.json.util.CycleDetectionStrategy; import net.sf.json.util.JSONUtils; import net.sf.json.xml.XMLSerializer; /** * json-lib utils * @author magic_yy * @see json-lib.sourceforge.net/ * @see https://github.com/aalmiray/Json-lib * */ public class JsonLibUtils { public static JsonConfig config = new JsonConfig(); static{ config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);//忽略迴圈,避免死迴圈 config.registerJsonValueProcessor(Date.class, new JsonValueProcessor() {//處理Date日期轉換 @Override public Object processObjectValue(String arg0, Object arg1, JsonConfig arg2) { SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d=(Date) arg1; return sdf.format(d); } @Override public Object processArrayValue(Object arg0, JsonConfig arg1) { return null; } }); } /** * java object convert to json string */ public static String pojo2json(Object obj){ return JSONObject.fromObject(obj,config).toString();//可以用toString(1)來實現格式化,便於閱讀 } /** * array、map、Javabean convert to json string */ public static String object2json(Object obj){ return JSONSerializer.toJSON(obj).toString(); } /** * xml string convert to json string */ public static String xml2json(String xmlString){ XMLSerializer xmlSerializer = new XMLSerializer(); JSON json = xmlSerializer.read(xmlString); return json.toString(); } /** * xml document convert to json string */ public static String xml2json(Document xmlDocument){ return xml2json(xmlDocument.toString()); } /** * json string convert to javaBean * @param <T> */ @SuppressWarnings("unchecked") public static <T> T json2pojo(String jsonStr,Class<T> clazz){ JSONObject jsonObj = JSONObject.fromObject(jsonStr); T obj = (T) JSONObject.toBean(jsonObj, clazz); return obj; } /** * json string convert to map */ public static Map<String,Object> json2map(String jsonStr){ JSONObject jsonObj = JSONObject.fromObject(jsonStr); Map<String,Object> result = (Map<String, Object>) JSONObject.toBean(jsonObj, Map.class); return result; } /** * json string convert to map with javaBean */ public static <T> Map<String,T> json2map(String jsonStr,Class<T> clazz){ JSONObject jsonObj = JSONObject.fromObject(jsonStr); Map<String,T> map = new HashMap<String, T>(); Map<String,T> result = (Map<String, T>) JSONObject.toBean(jsonObj, Map.class, map); MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry(); Morpher dynaMorpher = new BeanMorpher(clazz,morpherRegistry); morpherRegistry.registerMorpher(dynaMorpher); morpherRegistry.registerMorpher(new DateMorpher(new String[]{ "yyyy-MM-dd HH:mm:ss" })); for (Entry<String,T> entry : result.entrySet()) { map.put(entry.getKey(), (T)morpherRegistry.morph(clazz, entry.getValue())); } return map; } /** * json string convert to array */ public static Object[] json2arrays(String jsonString) { JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON(jsonString); // JSONArray jsonArray = JSONArray.fromObject(jsonString); JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setArrayMode(JsonConfig.MODE_OBJECT_ARRAY); Object[] objArray = (Object[]) JSONSerializer.toJava(jsonArray,jsonConfig); return objArray; } /** * json string convert to list * @param <T> */ @SuppressWarnings({ "unchecked", "deprecation" }) public static <T> List<T> json2list(String jsonString, Class<T> pojoClass){ JSONArray jsonArray = JSONArray.fromObject(jsonString); return JSONArray.toList(jsonArray, pojoClass); } /** * object convert to xml string */ public static String obj2xml(Object obj){ XMLSerializer xmlSerializer = new XMLSerializer(); return xmlSerializer.write(JSONSerializer.toJSON(obj)); } /** * json string convert to xml string */ public static String json2xml(String jsonString){ XMLSerializer xmlSerializer = new XMLSerializer(); xmlSerializer.setTypeHintsEnabled(true);//是否保留元素型別標識,預設true xmlSerializer.setElementName("e");//設定元素標籤,預設e xmlSerializer.setArrayName("a");//設定陣列標籤,預設a xmlSerializer.setObjectName("o");//設定物件標籤,預設o return xmlSerializer.write(JSONSerializer.toJSON(jsonString)); } }
複製程式碼

測試程式碼如下:

複製程式碼
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.ezmorph.test.ArrayAssertions;
import org.junit.Assert;
import org.junit.Test;

public class JsonLibUtilsTest {

    @Test
    public void pojo2json_test(){
        User user = new User(1, "張三");
        String json = JsonLibUtils.pojo2json(user);
        Assert.assertEquals("{\"id\":1,\"name\":\"張三\"}", json);
    }
    
    @Test
    public void object2json_test(){
        int[] intArray = new int[]{1,4,5};
        String json = JsonLibUtils.object2json(intArray);
        Assert.assertEquals("[1,4,5]", json);
        User user1 = new User(1,"張三");
        User user2 = new User(2,"李四");
        User[] userArray = new User[]{user1,user2};
        String json2 = JsonLibUtils.object2json(userArray);
        Assert.assertEquals("[{\"id\":1,\"name\":\"張三\"},{\"id\":2,\"name\":\"李四\"}]", json2);
        List<User> userList = new ArrayList<>();
        userList.add(user1);
        userList.add(user2);
        String json3 = JsonLibUtils.object2json(userList);
        Assert.assertEquals("[{\"id\":1,\"name\":\"張三\"},{\"id\":2,\"name\":\"李四\"}]", json3);
        //這裡的map的key必須為String型別
        Map<String,Object> map = new HashMap<>();
        map.put("id", 1);
        map.put("name", "張三");
        String json4 = JsonLibUtils.object2json(map);
        Assert.assertEquals("{\"id\":1,\"name\":\"張三\"}", json4);
        Map<String,User> map2 = new HashMap<>();
        map2.put("user1", user1);
        map2.put("user2", user2);
        String json5 = JsonLibUtils.object2json(map2);
        Assert.assertEquals("{\"user2\":{\"id\":2,\"name\":\"李四\"},\"user1\":{\"id\":1,\"name\":\"張三\"}}", json5);
    }
    
    @Test
    public void xml2json_test(){
        String xml1 = "<User><id>1</id><name>張三</name></User>";
        String json = JsonLibUtils.xml2json(xml1);
        Assert.assertEquals("{\"id\":\"1\",\"name\":\"張三\"}", json);
        String xml2 = "<Response><CustID>1300000428</CustID><Items><Item><Sku_ProductNo>sku_0004</Sku_ProductNo></Item><Item><Sku_ProductNo>0005</Sku_ProductNo></Item></Items></Response>";
        String json2 = JsonLibUtils.xml2json(xml2);
        //處理陣列時expected是處理結果,但不是我們想要的格式
        String expected = "{\"CustID\":\"1300000428\",\"Items\":[{\"Sku_ProductNo\":\"sku_0004\"},{\"Sku_ProductNo\":\"0005\"}]}";
        Assert.assertEquals(expected, json2);
        //實際上我們想要的是expected2這種格式,所以用json-lib來實現含有陣列的xml to json是不行的
        String expected2 = "{\"CustID\":\"1300000428\",\"Items\":{\"Item\":[{\"Sku_ProductNo\":\"sku_0004\"},{\"Sku_ProductNo\":\"0005\"}]}}";
        Assert.assertEquals(expected2, json2);
    }
    
    @Test
    public void json2arrays_test(){
        String json = "[\"張三\",\"李四\"]";
        Object[] array = JsonLibUtils.json2arrays(json);
        Object[] expected = new Object[] { "張三", "李四" };
        ArrayAssertions.assertEquals(expected, array);                                                                                            
        //無法將JSON字串轉換為物件陣列
        String json2 = "[{\"id\":1,\"name\":\"張三\"},{\"id\":2,\"name\":\"李四\"}]";
        Object[] array2 = JsonLibUtils.json2arrays(json2);
        User user1 = new User(1,"張三");
        User user2 = new User(2,"李四");
        Object[] expected2 = new Object[] { user1, user2 };
        ArrayAssertions.assertEquals(expected2, array2);
    }
    
    @Test
    public void json2list_test(){
        String json = "[\"張三\",\"李四\"]";
        List<String> list = JsonLibUtils.json2list(json, String.class);
        Assert.assertTrue(list.size()==2&&list.get(0).equals("張三")&&list.get(1).equals("李四"));
        String json2 = "[{\"id\":1,\"name\":\"張三\"},{\"id\":2,\"name\":\"李四\"}]";
        List<User> list2 = JsonLibUtils.json2list(json2, User.class);
        Assert.assertTrue(list2.size()==2&&list2.get(0).getId()==1&&list2.get(1).getId()==2);
    }
    
    @Test
    public void json2pojo_test(){
        String json = "{\"id\":1,\"name\":\"張三\"}";
        User user = (User) JsonLibUtils.json2pojo(json, User.class);
        Assert.assertEquals(json, user.toString());
    }
    
    @Test
    public void json2map_test(){
        String json = "{\"id\":1,\"name\":\"張三\"}";
        Map map = JsonLibUtils.json2map(json);
        int id = Integer.parseInt(map.get("id").toString());
        String name = map.get("name").toString();
        System.out.println(name);
        Assert.assertTrue(id==1&&name.equals("張三"));
        String json2 = "{\"user2\":{\"id\":2,\"name\":\"李四\"},\"user1\":{\"id\":1,\"name\":\"張三\"}}";
        Map map2 = JsonLibUtils.json2map(json2, User.class);
        System.out.println(map2);
    }
    
    @Test
    public void json2xml_test(){
        String json = "{\"id\":1,\"name\":\"張三\"}";
        String xml = JsonLibUtils.json2xml(json);
        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);
        System.out.println(xml);
        String json2 = "[{\"id\":1,\"name\":\"張三\"},{\"id\":2,\"name\":\"李四\"}]";
        String xml2 = JsonLibUtils.json2xml(json2);
        System.out.println(xml2);
        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);
    }
    
    public static class User{
        private int id;
        private String name;
        
        public User() {
        }
        public User(int id, String name) {
            this.id = id;
            this.name = name;
        }
        @Override
        public String toString() {
            return "{\"id\":"+id+",\"name\":\""+name+"\"}";
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}
複製程式碼

json-lib在XML轉換為JSON在有陣列的情況下會有問題,還有在JSON轉換為XML時都會有元素標識如<o><a><e>等,在一般情況下我們可能都不需要,暫時還不知道如何過濾這些元素名稱。

因為json-lib的種種缺點,基本停止了更新,也不支援註解轉換,後來便有了jackson流行起來,它比json-lib的轉換效率要高很多,依賴很少,社群也比較活躍

我們依舊開始上程式碼,首先是它的依賴:

複製程式碼
<dependency>  
    <groupId>com.fasterxml.jackson.dataformat</groupId>  
    <artifactId>jackson-dataformat-xml</artifactId>  
    <version>2.1.3</version>  
</dependency>  
<dependency>  
    <groupId>com.fasterxml.jackson.core</groupId>  
    <artifactId>jackson-databind</artifactId>  
    <version>2.1.3</version>  
    <type>java-source</type>  
    <scope>compile</scope>  
</dependency>  
複製程式碼

這裡我要說下,有很多基於jackson的工具,大家可以按照自己的實際需求來需找對應的依賴,我這裡為了方便轉換xml所以用了dataformat-xml和databind

 使用jackson實現多種轉換:

複製程式碼
package cn.yangyong.fodder.util;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;


public class JacksonUtils {
    
    private static ObjectMapper objectMapper = new ObjectMapper();
    private static XmlMapper xmlMapper = new XmlMapper();
    
    /**
     * javaBean,list,array convert to json string
     */
    public static String obj2json(Object obj) throws Exception{
        return objectMapper.writeValueAsString(obj);
    }
    
    /**
     * json string convert to javaBean
     */
    public static <T> T json2pojo(String jsonStr,Class<T> clazz) throws Exception{
        return objectMapper.readValue(jsonStr, clazz);
    }
    
    /**
     * json string convert to map
     */
    public static <T> Map<String,Object> json2map(String jsonStr)throws Exception{
        return objectMapper.readValue(jsonStr, Map.class);
    }
    
    /**
     * json string convert to map with javaBean
     */
    public static <T> Map<String,T> json2map(String jsonStr,Class<T> clazz)throws Exception{
        Map<String,Map<String,Object>> map =  objectMapper.readValue(jsonStr, new TypeReference<Map<String,T>>() {
        });
        Map<String,T> result = new HashMap<String, T>();
        for (Entry<String, Map<String,Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
        }
        return result;
    }
    
    /**
     * json array string convert to list with javaBean
     */
    public static <T> List<T> json2list(String jsonArrayStr,Class<T> clazz)throws Exception{
        List<Map<String,Object>> list = objectMapper.readValue(jsonArrayStr, new TypeReference<List<T>>() {
        });
        List<T> result = new ArrayList<>();
        for (Map<String, Object> map : list) {
            result.add(map2pojo(map, clazz));
        }
        return result;
    }
    
    /**
     * map convert to javaBean
     */
    public static <T> T map2pojo(Map map,Class<T> clazz){
        return objectMapper.convertValue(map, clazz);
    }
    
    /**
     * json string convert to xml string
     */
    public static String json2xml(String jsonStr)throws Exception{
        JsonNode ro