java封装对象转json字符串

/**
 * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jfinal.kit;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;

/**
 * Convert object to json string.
 * 
 *  Json                 java
 * string            java.lang.String
 * number            java.lang.Number
 * true|false        java.lang.Boolean
 * null                null
 * array            java.util.List
 * object            java.util.Map
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class JsonKit {
    
    private static int convertDepth = 8;
    private static String timestampPattern = "yyyy-MM-dd HH:mm:ss";
    private static String datePattern = "yyyy-MM-dd";
    
    public static void setConvertDepth(int convertDepth) {
        if (convertDepth < 2)
            throw new IllegalArgumentException("convert depth can not less than 2.");
        JsonKit.convertDepth = convertDepth;
    }
    
    public static void setTimestampPattern(String timestampPattern) {
        if (timestampPattern == null || "".equals(timestampPattern.trim()))
            throw new IllegalArgumentException("timestampPattern can not be blank.");
        JsonKit.timestampPattern = timestampPattern;
    }
    
    public static void setDatePattern(String datePattern) {
        if (datePattern == null || "".equals(datePattern.trim()))
            throw new IllegalArgumentException("datePattern can not be blank.");
        JsonKit.datePattern = datePattern;
    }
    
    private static String mapToJson(Map map, int depth) {
        if(map == null)
            return "null";
        
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        Iterator iter = map.entrySet().iterator();
        
        sb.append('{');
        while(iter.hasNext()){
            if(first)
                first = false;
            else
                sb.append(',');
            
            Map.Entry entry = (Map.Entry)iter.next();
            toKeyValue(String.valueOf(entry.getKey()),entry.getValue(), sb, depth);
        }
        sb.append('}');
        return sb.toString();
    }
    
    private static String toKeyValue(String key, Object value, StringBuilder sb, int depth){
        sb.append('"');
        if(key == null)
            sb.append("null");
        else
            escape(key, sb);
        sb.append('"').append(':');
        
        sb.append(toJson(value, depth));
        
        return sb.toString();
    }
    
    private static String listToJson(List list, int depth) {
        if(list == null)
            return "null";
        
        boolean first = true;
        StringBuilder sb = new StringBuilder();
        Iterator iter = list.iterator();
        
        sb.append('[');
        while(iter.hasNext()){
            if(first)
                first = false;
            else
                sb.append(',');
            
            Object value = iter.next();
            if(value == null){
                sb.append("null");
                continue;
            }
            sb.append(toJson(value, depth));
        }
        sb.append(']');
        return sb.toString();
    }
    
    /**
     * Escape quotes, \, /, 
, 
, , f, 	 and other control characters (U+0000 through U+001F).
     */
    private static String escape(String s) {
        if(s == null)
            return null;
        StringBuilder sb = new StringBuilder();
        escape(s, sb);
        return sb.toString();
    }
    
    private static void escape(String s, StringBuilder sb) {
        for(int i=0; i<s.length(); i++){
            char ch = s.charAt(i);
            switch(ch){
            case '"':
                sb.append("\"");
                break;
            case '\':
                sb.append("\\");
                break;
            case '':
                sb.append("\b");
                break;
            case 'f':
                sb.append("\f");
                break;
            case '
':
                sb.append("\n");
                break;
            case '
':
                sb.append("\r");
                break;
            case '	':
                sb.append("\t");
                break;
            case '/':
                sb.append("\/");
                break;
            default:
                if((ch >= 'u0000' && ch <= 'u001F') || (ch >= 'u007F' && ch <= 'u009F') || (ch >= 'u2000' && ch <= 'u20FF')) {
                    String str = Integer.toHexString(ch);
                    sb.append("\u");
                    for(int k=0; k<4-str.length(); k++) {
                        sb.append('0');
                    }
                    sb.append(str.toUpperCase());
                }
                else{
                    sb.append(ch);
                }
            }
        }
    }
    
    public static String toJson(Object value) {
        return toJson(value, convertDepth);
    }
    
    public static String toJson(Object value, int depth) {
        if(value == null || (depth--) < 0)
            return "null";
        
        if(value instanceof String)
            return """ + escape((String)value) + """;
        
        if(value instanceof Double){
            if(((Double)value).isInfinite() || ((Double)value).isNaN())
                return "null";
            else
                return value.toString();
        }
        
        if(value instanceof Float){
            if(((Float)value).isInfinite() || ((Float)value).isNaN())
                return "null";
            else
                return value.toString();
        }
        
        if(value instanceof Number)
            return value.toString();
        
        if(value instanceof Boolean)
            return value.toString();
        
        if (value instanceof java.util.Date) {
            if (value instanceof java.sql.Timestamp)
                return """ + new SimpleDateFormat(timestampPattern).format(value) + """;
            if (value instanceof java.sql.Time)
                return """ + value.toString() + """;
            return """ + new SimpleDateFormat(datePattern).format(value) + """;
        }
        
        if(value instanceof Map) {
            return mapToJson((Map)value, depth);
        }
        
        if(value instanceof List) {
            return listToJson((List)value, depth);
        }
        
        String result = otherToJson(value, depth);
        if (result != null)
            return result;
        
        // 类型无法处理时当作字符串处理,否则ajax调用返回时js无法解析
        // return value.toString();
        return """ + escape(value.toString()) + """;
    }
    
    private static String otherToJson(Object value, int depth) {
        if (value instanceof Character) {
            return """ + escape(value.toString()) + """;
        }
        
        if (value instanceof Model) {
            Map map = com.jfinal.plugin.activerecord.CPI.getAttrs((Model)value);
            return mapToJson(map, depth);
        }
        if (value instanceof Record) {
            Map map = ((Record)value).getColumns();
            return mapToJson(map, depth);
        }
        if (value instanceof Object[]) {
            Object[] arr = (Object[])value;
            List list = new ArrayList(arr.length);
            for (int i=0; i<arr.length; i++)
                list.add(arr[i]);
            return listToJson(list, depth);
        }
        if (value instanceof Enum) {
            return """ + ((Enum)value).toString() + """;
        }
        
        return beanToJson(value, depth);
    }
    
    private static String beanToJson(Object model, int depth) {
        Map map = new HashMap();
        Method[] methods = model.getClass().getMethods();
        for (Method m : methods) {
            String methodName = m.getName();
            int indexOfGet = methodName.indexOf("get");
            if (indexOfGet == 0 && methodName.length() > 3) {    // Only getter
                String attrName = methodName.substring(3);
                if (!attrName.equals("Class")) {                // Ignore Object.getClass()
                    Class<?>[] types = m.getParameterTypes();
                    if (types.length == 0) {
                        try {
                            Object value = m.invoke(model);
                            map.put(StrKit.firstCharToLowerCase(attrName), value);
                        } catch (Exception e) {
                            throw new RuntimeException(e.getMessage(), e);
                        }
                    }
                }
            }
            else {
               int indexOfIs = methodName.indexOf("is");
               if (indexOfIs == 0 && methodName.length() > 2) {
                  String attrName = methodName.substring(2);
                  Class<?>[] types = m.getParameterTypes();
                  if (types.length == 0) {
                      try {
                          Object value = m.invoke(model);
                          map.put(StrKit.firstCharToLowerCase(attrName), value);
                      } catch (Exception e) {
                          throw new RuntimeException(e.getMessage(), e);
                      }
                  }
               }
            }
        }
        return mapToJson(map, depth);
    }
    
    /**
     * TODO
    public static Map jsonToMap(String jsonStr) {
        throw new RuntimeException("not finished");
    }
    */
}
原文地址:https://www.cnblogs.com/smile361/p/4286122.html