一、介绍
在前后端数据传输交互中,经常会遇到字符串与JSON、XML等格式相互转换与解析,其中JSON以跨语言,跨前后端的优点在开发中被频繁使用,基本上可以说是标准的数据交换格式。FastJson是阿里巴巴用Java语言编写的高性能且功能完善的JSON库,用于对JSON格式的数据进行解析。FastJSON 是一个开源项目,你可以在 GitHub 上找到它的源代码和文档。
二、FastJson使用
第一步:导入依赖
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><!--(起码1.2.48以上)因为这个版本一下存在漏洞--><version>版本根据自己需要</version>
</dependency>
第二步:具体使用
FastJson 提供了大量的方法来处理 JSON 数据。以下是其中一些常用的方法。另外,我们知道 JSON 字符串大多是很多嵌套了很多层的,我们可以通过链式调用获取底层的 JSON 字符串所对应的 JSONObject 对象。
//把JSON文本解析为JSONObject或者JSONArray
public static final Object parse(String text); //把JSON文本解析成JSONObject
public static final JSONObject parseObject(String text); //把JSON文本解析为JavaBean
public static final <T> T parseObject(String text, Class<T> clazz); //把JSON文本解析成JSONArray。只有字符串是JSON数组的时候才能转,不然会报错。
public static final JSONArray parseArray(String text); //把JSON文本解析成JavaBean集合
public static final <T> List<T> parseArray(String text, Class<T> clazz); //将JavaBean序列化为JSON文本
public static final String toJSONString(Object object); //将JavaBean序列化为带格式的JSON文本
public static final String toJSONString(Object object, boolean prettyFormat); //将JavaBean转换为JSONObject或者JSONArray。
public static final Object toJSON(Object javaObject);
三、XML和JSON之间的转换
某些情况下,我们也会涉及到 XML 格式的字符串和 JSONObject 对象之间的转换,可使用下面的工具类完成:
第一步:导入FastJson和dom4j的依赖
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><!--(起码1.2.48以上)因为这个版本一下存在漏洞--><version>版本根据自己需要</version>
</dependency>
<dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version>
</dependency>
第二步:在项目的工具类包下添加下面的工具类即可使用
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;/*** fastjson工具类*/
public class FastJsonUtil {/*** xml字符串转为fastjson中的JSONObject对象* @param xml 待转换数据xml字符串* @return JSONObject对象*/public static JSONObject xmlToFastJson(String xml){JSONObject jsonObject = null;try {jsonObject = new JSONObject();Document document = DocumentHelper.parseText(xml);//获取根节点元素对象Element root = document.getRootElement();iterateNodes(root, jsonObject);}catch (Exception e){return jsonObject;}return jsonObject;}/*** fastjson中JSONObject对象的转为xml字符串* @param jsonStr 待转换json字符串* @param escape 是否忽略特殊字符(即特殊字符转xml后追加CDATA)* @return xml字符串*/public static String fastJsonToXml(String jsonStr,Boolean escape) {try {StringBuffer buffer = new StringBuffer();//带顺序JSONObject json = JSONObject.parseObject(jsonStr, Feature.OrderedField);jsonToXmlStr(json,buffer, escape != null && escape);return buffer.toString();} catch (Exception e) {e.printStackTrace();return "";}}/*** object转JSONObject* @param t 待转换的Java对象* @return JSONObject对象*/public static <T> JSONObject objectToJSONObject(T t){return JSONObject.parseObject(JSON.toJSONString(t));}/*** json字符串转实体对象* @param jsonString json字符串* @param clazz 实体对象的类型* @return 解析出的实体对象*/public static <T> T jsonStrToEntity(String jsonString,Class<T> clazz){return JSONObject.parseObject(jsonString,clazz);}public static void iterateNodes(Element node, JSONObject json) {//获取当前元素的名称String nodeName = node.getName();//判断已遍历的JSON中是否已经有了该元素的名称if (json.containsKey(nodeName)) {//该元素在同级下有多个Object Object = json.get(nodeName);JSONArray array;if (Object instanceof JSONArray) {array = (JSONArray) Object;}else {array = new JSONArray();array.add(Object);}//获取该元素下所有子元素List<Element> listElement = node.elements();if (listElement.isEmpty()) {// 该元素无子元素,获取元素的值String nodeValue = node.getTextTrim();array.add(nodeValue);json.put(nodeName, array);return;}//有子元素JSONObject newJson = new JSONObject();//遍历所有子元素for (Element e : listElement) {//递归iterateNodes(e, newJson);}array.add(newJson);json.put(nodeName, array);return;}//该元素同级下第一次遍历//获取该元素下所有子元素List<Element> listElement = node.elements();if (listElement.isEmpty()) {// 该元素无子元素,获取元素的值String nodeValue = node.getTextTrim();json.put(nodeName, nodeValue);return;}//有子节点,新建一个JSONObject来存储该节点下子节点的值JSONObject object = new JSONObject();//遍历所有一级子节点for (Element e : listElement) {//递归iterateNodes(e, object);}json.put(nodeName, object);return;}private static void jsonToXmlStr(JSONObject json,StringBuffer buffer,Boolean isEscape){Iterator<Map.Entry<String,Object>> it = json.entrySet().iterator();Map.Entry<String,Object> en;while(it.hasNext()){en = it.next();if(en.getKey().startsWith("-")){continue;}if(en.getKey().equals("#text")){//直接输出文本buffer.append(en.getValue());continue;}if(en.getValue() instanceof JSONObject){buffer.append("<").append(en.getKey()).append(getAttr((JSONObject) en.getValue())).append(">");JSONObject jo = json.getJSONObject(en.getKey());jsonToXmlStr(jo,buffer,isEscape);buffer.append("</").append(en.getKey()).append(">");}else if(en.getValue() instanceof JSONArray){JSONArray jsonArray = json.getJSONArray(en.getKey());for (int i = 0; i < jsonArray.size(); i++) {JSONObject jsonobject = jsonArray.getJSONObject(i);buffer.append("<").append(en.getKey()).append(getAttr(jsonobject)).append(">");jsonToXmlStr(jsonobject,buffer,isEscape);buffer.append("</").append(en.getKey()).append(">");}}else{buffer.append("<").append(en.getKey()).append(">").append(isEscape ? escape(String.valueOf(en.getValue())) : String.valueOf(en.getValue())).append("</").append(en.getKey()).append(">");}}}/*** 拼当前节点属性* @param json* @return*/private static String getAttr(JSONObject json){StringBuilder sb = new StringBuilder();for(Map.Entry<String,Object> entity:json.entrySet()){if(entity.getKey().startsWith("-")){sb.append(" ").append(entity.getKey().substring(1)).append("=\"").append(entity.getValue().toString()).append("\"");}}return sb.toString();}/*** 特殊字符pattern*/private static Pattern pattern = Pattern.compile("[<>&\"',]");/*** json转xml中遇到特殊字符对内容追加![CDATA[]]* @param string* @return*/private static String escape(String string) {return pattern.matcher(string).find() ? "<![CDATA[" + string + "]]>" : string;}/*** 判断是否是JSON数组* @param str JSON字符串* @return true或false*/public static boolean isJsonArray(String str) {if (str.isEmpty()) {return false;}return isWrap(str.trim(), '[', ']');}public static boolean isWrap(CharSequence str, char prefixChar, char suffixChar) {if (null == str) {return false;}return str.charAt(0) == prefixChar && str.charAt(str.length() - 1) == suffixChar;}
}