java中用到json

最近一個項目要對藝龍,攜程等酒店預訂網站進行價格信息採集.因爲這兩個網站都不是省油的燈啊,多次提交ajax表單,參數編碼,獲取特定的城市和酒店代碼等等手段,可謂過五關斬六將,總算是把數據採集回來,但是又面臨一個難題:採集回來的信息是json格式的,那就涉及到json數據轉換成java對象了
  
  
  
首先要了解json數據的格式
  
[{"CityType":"hotel","TabList":[{"TabId":"1","Name":"\u70ED\u95E8","NameEn":"Hot",
"CityList":[{"ProvinceId":null,"CityId":"0101","CityCode":"0101",
"CityNameCn":"\u5317\u4EAC","CityNameEn":"Beijing",
"CityThreeSign":"","CityType":"hotel","OldEnglishName":"peking"},
{"ProvinceId":null,"CityId":"0201","CityCode":"0201",
"CityNameCn":"\u4E0A\u6D77","CityNameEn":"Shanghai",
"CityThreeSign":"","CityType":"hotel","OldEnglishName":""},
{"ProvinceId":null,"CityId":"2001","CityCode":"2001",
"CityNameCn":"\u5E7F\u5DDE","CityNameEn":"Guangzhou",
"CityThreeSign":"","CityType":"hotel","OldEnglishName":"canton"}]}]}];
  
jsonViewer是個好東西,不過HTTPAnalysis直接就集成了jsonViewer,不過還是前者比較輕巧:
json和java之間的互換可以使用json-lib, 基本的使用可以看文檔就行.網上也有一些集成的類,我建議直接看它的源代碼,瞭解他是如何通過反射和使用臨時對象解析json數據,並封裝成java對象.
這個json數據時list的嵌套,如果要對整個json文件解析,需要使用如下方法,需要構造跟json數據對應的Tab.class 和City.class,而且字段名稱必須一致(駱駝首字母小寫),提供默認構造方法,這樣就可以將json數據作爲一個完整的對象,想怎麼幹都行了.
  
HashMap<String,Class> map = new HashMap<String,Class>();
map.put("tabList", Tab.class);
map.put("cityList", City.class);
 
        /**
         * 從一個JSON數組得到一個java對象集合,其中對象中包含有集合屬性
         * @param object
         * @param clazz
         * @param map 集合屬性的類型 (key : 集合屬性名, value : 集合屬性類型class)
eg: ("beansList" : Bean.class)
         * @return
         */
        public static List getDTOList(String jsonString, Class clazz, Map map){
            setDataFormat2JAVA();
            JSONArray array = JSONArray.fromObject(jsonString);
            List list = new ArrayList();
            for(Iterator iter = array.iterator(); iter.hasNext();){
                JSONObject jsonObject = (JSONObject)iter.next();
                list.add(JSONObject.toBean(jsonObject, clazz, map));
            }
            return list;
        }    
由於我的需求只是需要重json數據中獲取特定的信息對象,如上面的cityList,像tabList等對象我沒必要去構造和獲取,而且在實際使用過程中我發現
JSON數據中變量如果不是首字母小寫,是無法轉換成JAVA對象的.這個確實很坑爹!!!!!
  
於是乎,我就寫了個直接讀取和解析一個片段json數據的類,有了這個類,加上對象映射,基本上沒什麼解析不了
  
package com.engine.logic.component.loader.impl.json.utils;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
 
public class JSonStrUtils {
 
    /**
     * json 數據括號自動補全
     * **/
    public static String autoComplete(String targetJson){
        LinkedList<Character> stack = new LinkedList<Character>();
        String returnStr ="";
        char[] charArray = targetJson.toCharArray();
        for(int i = 0;i<charArray.length;i++){
            if(charArray[i]=='['||charArray[i]=='{'){//入棧
                stack.addFirst(charArray[i]);
            }else if(charArray[i]==']'){
                //判斷是否閉合
                char last = stack.peekFirst();
                if(last !='['){//不閉合,補 }
                    returnStr+='}';
                }else//閉合
                {
                    stack.pollFirst();
                }
            }else if(charArray[i]=='}'){
                //判斷是否閉合
                char last = stack.peekFirst();
                if(last !='{'){//不閉合,補 }
                    returnStr+=']';
                }else//閉合
                {
                    stack.pollFirst();
                }
            }
            returnStr+=charArray[i];
        }
        for(char c:stack){
            System.out.println("left in stack:"+c);
        }
        return returnStr;
    }
 
    /***
     * 用於處理json數據中出現變量名非首字母小寫的情況,利用正則匹配變量,然後把首字母變成小寫
     * */
    public static String dealWithFirstChar(String jsonInput){
        String originalInput = jsonInput;
        StringBuilder inputStr = new StringBuilder(jsonInput);
        String regex = "\"(\\w+)\":";
        Pattern p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(inputStr);
        List<String> result=new ArrayList<String>();
        while(m.find()){
            String valueName = m.group(1);
            String newValueName = null;
            char[] words =valueName.toCharArray();
            if(Character.isUpperCase(words[0])){//首字母大寫,不符合變量命名規範
 
                words[0] = Character.toLowerCase(words[0]);
                newValueName = new String(words);
//              System.out.println("orignal value:"+valueName+" new value :"
+ newValueName);
//              String regexWord = "\""+valueName+"\":";
                String regx1 = "\""+valueName+"\":";
                String replace = "\""+newValueName+"\":";
                originalInput=originalInput.replaceAll(regx1, replace);
            }
            result.add(valueName);
            inputStr.delete(0, m.end(0));
            m=p.matcher(inputStr);
        }
        return originalInput;
 
    }
 
    /***
     * 用戶將unicode編碼轉換成漢字
     * */
    public static String UnicodeToString(String str) {
        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
        Matcher matcher = pattern.matcher(str);
        char ch;
        while (matcher.find()) {
            ch = (char) Integer.parseInt(matcher.group(2), 16);
            str = str.replace(matcher.group(1), ch + "");
        }
        return str;
    }
 
    /***
     * 用戶將漢字轉換成unicode編碼
     * */
    public static String toUNICODE(String s)
    {
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<s.length();i++)
        {
            if(s.charAt(i)<=256)
            {
                sb.append("\\u00");
            }
            else
            {
                sb.append("\\u");
            }
            sb.append(Integer.toHexString(s.charAt(i)).toUpperCase());
        }
        return sb.toString();
    }
 
    /**
     * 讀取json文件,轉換爲字符串
     * */
    public static String readJSonFile(String fileName){
        InputStream in = null;
        String jsonStr = "";
        try {
            in = JSonStrUtils.class.getResourceAsStream(fileName);
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String temp = reader.readLine();
            while(temp!=null){
                jsonStr+=temp;
                temp = reader.readLine();
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("read json file failed :"+fileName);
        }
        return jsonStr;
    }
 
    /***
     * 在指定的JSONObject 中尋找特定屬性的第一個值
     * */
    public static List<String> findTargetProperty(JSONObject object,
String propertyName,boolean isRecursive){
        List<String> values = new ArrayList<String>();
        for( Iterator entries = object.names().iterator();
         entries.hasNext(); ){
            String name = (String) entries.next();
            Object value = object.get(name);
            if(name.equals(propertyName)){//找到目標屬性
                values.add(value.toString());
            }else if(isRecursive){
                if(value instanceof JSONObject){
                    values.addAll(findTargetProperty((JSONObject)value,
propertyName,isRecursive));
                }else if(value instanceof JSONArray){
                    JSONArray array = (JSONArray)value;
                    for(Iterator iter = array.iterator(); iter.hasNext();){
                        JSONObject jsonObject = (JSONObject)iter.next();
                        values.addAll(findTargetProperty(jsonObject,
propertyName,isRecursive));
                    }
                }
            }
        }
        return values;
    }
 
    /***
     * 從指定的JSonArray中尋找指定名稱的子json數組
     * */
    public  static List<JSONArray> findTargetJSonArray(JSONArray array,
String targetName){
        List<JSONArray> arrays = new ArrayList<JSONArray>();
        for(Iterator iter = array.iterator(); iter.hasNext();){//遍歷數組中的JSONObject
            JSONObject jsonObject = (JSONObject)iter.next();
            if( jsonObject == null || jsonObject.isNullObject() ){
                 continue;
            }
            for( Iterator entries = jsonObject.names().iterator();
             entries.hasNext(); ){
                 String name = (String) entries.next();
                 Object value = jsonObject.get(name);
                 if(value instanceof JSONArray){//屬性爲數組
                     //先判斷是否目標數組
                     if(name.equals(targetName)){
                         arrays.add((JSONArray) value);
                     }
                     //遞歸查找
                     arrays.addAll(findTargetJSonArray((JSONArray) value,
targetName));
                 }
            }
        }
        return arrays;
 
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章