原创声明:本文为作者原创,未经允许不得转载,经授权转载需注明作者和出处
me.setJsonFactory(new SevenJsonFactory());
package com.jfinal.app.common.json;
import com.jfinal.json.Json;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.CPI;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* description: SevenJson
* date: 2020/4/10 21:34
* author: 小徐同学
*/
public class SevenJson extends Json {
private static int defaultConvertDepth = 16;
protected int convertDepth;
protected String timestampPattern;
public SevenJson() {
this.convertDepth = defaultConvertDepth;
this.timestampPattern = "yyyy-MM-dd HH:mm:ss";
}
public static void setDefaultConvertDepth(int defaultConvertDepth) {
if (defaultConvertDepth < 2) {
throw new IllegalArgumentException("defaultConvertDepth depth can not less than 2.");
} else {
defaultConvertDepth = defaultConvertDepth;
}
}
public SevenJson setConvertDepth(int convertDepth) {
if (convertDepth < 2) {
throw new IllegalArgumentException("convert depth can not less than 2.");
} else {
this.convertDepth = convertDepth;
return this;
}
}
public SevenJson setTimestampPattern(String timestampPattern) {
if (StrKit.isBlank(timestampPattern)) {
throw new IllegalArgumentException("timestampPattern can not be blank.");
} else {
this.timestampPattern = timestampPattern;
return this;
}
}
@Override
public Json setDatePattern(String datePattern) {
if (StrKit.isBlank(datePattern)) {
throw new IllegalArgumentException("datePattern can not be blank.");
} else {
this.datePattern = datePattern;
return this;
}
}
public static SevenJson getJson() {
return new SevenJson();
}
protected String mapToJson(Map map, int depth) {
if (map == null) {
return "null";
} else {
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();
this.toKeyValue(String.valueOf(entry.getKey()), entry.getValue(), sb, depth);
}
sb.append('}');
return sb.toString();
}
}
protected void toKeyValue(String key, Object value, StringBuilder sb, int depth) {
sb.append('"');
if (key == null) {
sb.append("null");
} else {
this.escape(toCamelCase(key), sb);
}
sb.append('"').append(':');
sb.append(this.toJson(value, depth));
}
protected String iteratorToJson(Iterator iter, int depth) {
boolean first = true;
StringBuilder sb = new StringBuilder();
sb.append('[');
while (iter.hasNext()) {
if (first) {
first = false;
} else {
sb.append(',');
}
Object value = iter.next();
if (value == null) {
sb.append("null");
} else {
sb.append(this.toJson(value, depth));
}
}
sb.append(']');
return sb.toString();
}
protected String escape(String s) {
if (s == null) {
return null;
} else {
StringBuilder sb = new StringBuilder();
this.escape(s, sb);
return sb.toString();
}
}
protected void escape(String s, StringBuilder sb) {
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
switch (ch) {
case '\b':
sb.append("\\b");
continue;
case '\t':
sb.append("\\t");
continue;
case '\n':
sb.append("\\n");
continue;
case '\f':
sb.append("\\f");
continue;
case '\r':
sb.append("\\r");
continue;
case '"':
sb.append("\\\"");
continue;
case '\\':
sb.append("\\\\");
continue;
}
if (ch >= 0 && ch <= 31 || ch >= 127 && ch <= 159 || ch >= 8192 && ch <= 8447) {
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);
}
}
}
@Override
public String toJson(Object object) {
return this.toJson(object, this.convertDepth);
}
protected String toJson(Object value, int depth) {
if (value != null && depth-- >= 0) {
if (value instanceof String) {
return "\"" + this.escape((String) value) + "\"";
} else if (value instanceof Double) {
return !((Double) value).isInfinite() && !((Double) value).isNaN() ? value.toString() : "null";
} else if (value instanceof Float) {
return !((Float) value).isInfinite() && !((Float) value).isNaN() ? value.toString() : "null";
} else if (value instanceof Number) {
return value.toString();
} else if (value instanceof Boolean) {
return value.toString();
} else {
String result;
if (value instanceof Date) {
if (value instanceof Timestamp) {
return "\"" + (new SimpleDateFormat(this.timestampPattern)).format(value) + "\"";
} else if (value instanceof Time) {
return "\"" + value.toString() + "\"";
} else {
result = this.datePattern != null ? this.datePattern : this.getDefaultDatePattern();
return result != null ? "\"" + (new SimpleDateFormat(result)).format(value) + "\"" : "" + ((Date) value).getTime();
}
} else if (value instanceof Collection) {
return this.iteratorToJson(((Collection) value).iterator(), depth);
} else if (value instanceof Map) {
return this.mapToJson((Map) value, depth);
} else {
result = this.otherToJson(value, depth);
return result != null ? result : "\"" + this.escape(value.toString()) + "\"";
}
}
} else {
return "null";
}
}
protected String otherToJson(Object value, int depth) {
if (value instanceof Character) {
return "\"" + this.escape(value.toString()) + "\"";
} else {
Map map;
if (value instanceof Model) {
map = CPI.getAttrs((Model) value);
return this.mapToJson(map, depth);
} else if (value instanceof Record) {
map = ((Record) value).getColumns();
return this.mapToJson(map, depth);
} else if (!value.getClass().isArray()) {
if (value instanceof Iterator) {
return this.iteratorToJson((Iterator) value, depth);
} else if (value instanceof Enumeration) {
ArrayList<?> list = Collections.list((Enumeration) value);
return this.iteratorToJson(list.iterator(), depth);
} else {
return value instanceof Enum ? "\"" + ((Enum) value).toString() + "\"" : this.beanToJson(value, depth);
}
} else {
int len = Array.getLength(value);
List<Object> list = new ArrayList(len);
for (int i = 0; i < len; ++i) {
list.add(Array.get(value, i));
}
return this.iteratorToJson(list.iterator(), depth);
}
}
}
protected String beanToJson(Object model, int depth) {
Map map = new HashMap();
Method[] methods = model.getClass().getMethods();
Method[] var5 = methods;
int var6 = methods.length;
for (int var7 = 0; var7 < var6; ++var7) {
Method m = var5[var7];
String methodName = m.getName();
int indexOfGet = methodName.indexOf("get");
if (indexOfGet == 0 && methodName.length() > 3) {
String attrName = methodName.substring(3);
if (!attrName.equals("Class")) {
Class<?>[] types = m.getParameterTypes();
if (types.length == 0) {
try {
Object value = m.invoke(model);
map.put(StrKit.firstCharToLowerCase(attrName), value);
} catch (Exception var15) {
throw new RuntimeException(var15.getMessage(), var15);
}
}
}
} 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 var16) {
throw new RuntimeException(var16.getMessage(), var16);
}
}
}
}
}
return this.mapToJson(map, depth);
}
@Override
public <T> T parse(String jsonString, Class<T> type) {
throw new RuntimeException("jfinal 3.6默认 com.renzhi.core.common.json 实现暂不支持 com.renzhi.core.common.json 到 object 的转换,建议使用 active recrord 的 Generator 生成 base model,再通过 me.setJsonFactory(new MixedJsonFactory()) 来支持");
}
private static String toCamelCase(String stringWithUnderline) {
if (stringWithUnderline.indexOf(95) == -1) {
char[] fromArray = stringWithUnderline.toCharArray();
boolean isHaveLowerCase = false;
boolean isHaveUperCase = false;
for (int i = 0; i < fromArray.length; ++i) {
if (Character.isUpperCase(fromArray[i])) {
isHaveUperCase = true;
} else if (Character.isLowerCase(fromArray[i])) {
isHaveLowerCase = true;
}
if (isHaveLowerCase && isHaveUperCase){
return stringWithUnderline;
}
}
return stringWithUnderline.toLowerCase();
} else {
stringWithUnderline = stringWithUnderline.toLowerCase();
char[] fromArray = stringWithUnderline.toCharArray();
char[] toArray = new char[fromArray.length];
int j = 0;
for (int i = 0; i < fromArray.length; ++i) {
if (fromArray[i] == '_') {
++i;
if (i < fromArray.length) {
toArray[j++] = Character.toUpperCase(fromArray[i]);
}
} else {
toArray[j++] = fromArray[i];
}
}
return new String(toArray, 0, j);
}
}
}
package com.jfinal.app.common.json;
import com.jfinal.json.Json;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.CPI;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* description: SevenJson
* date: 2020/4/10 21:34
* author: 小徐同学
*/
public class SevenJson extends Json {
private static int defaultConvertDepth = 16;
protected int convertDepth;
protected String timestampPattern;
public SevenJson() {
this.convertDepth = defaultConvertDepth;
this.timestampPattern = "yyyy-MM-dd HH:mm:ss";
}
public static void setDefaultConvertDepth(int defaultConvertDepth) {
if (defaultConvertDepth < 2) {
throw new IllegalArgumentException("defaultConvertDepth depth can not less than 2.");
} else {
defaultConvertDepth = defaultConvertDepth;
}
}
public SevenJson setConvertDepth(int convertDepth) {
if (convertDepth < 2) {
throw new IllegalArgumentException("convert depth can not less than 2.");
} else {
this.convertDepth = convertDepth;
return this;
}
}
public SevenJson setTimestampPattern(String timestampPattern) {
if (StrKit.isBlank(timestampPattern)) {
throw new IllegalArgumentException("timestampPattern can not be blank.");
} else {
this.timestampPattern = timestampPattern;
return this;
}
}
@Override
public Json setDatePattern(String datePattern) {
if (StrKit.isBlank(datePattern)) {
throw new IllegalArgumentException("datePattern can not be blank.");
} else {
this.datePattern = datePattern;
return this;
}
}
public static SevenJson getJson() {
return new SevenJson();
}
protected String mapToJson(Map map, int depth) {
if (map == null) {
return "null";
} else {
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();
this.toKeyValue(String.valueOf(entry.getKey()), entry.getValue(), sb, depth);
}
sb.append('}');
return sb.toString();
}
}
protected void toKeyValue(String key, Object value, StringBuilder sb, int depth) {
sb.append('"');
if (key == null) {
sb.append("null");
} else {
this.escape(toCamelCase(key), sb);
}
sb.append('"').append(':');
sb.append(this.toJson(value, depth));
}
protected String iteratorToJson(Iterator iter, int depth) {
boolean first = true;
StringBuilder sb = new StringBuilder();
sb.append('[');
while (iter.hasNext()) {
if (first) {
first = false;
} else {
sb.append(',');
}
Object value = iter.next();
if (value == null) {
sb.append("null");
} else {
sb.append(this.toJson(value, depth));
}
}
sb.append(']');
return sb.toString();
}
protected String escape(String s) {
if (s == null) {
return null;
} else {
StringBuilder sb = new StringBuilder();
this.escape(s, sb);
return sb.toString();
}
}
protected void escape(String s, StringBuilder sb) {
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
switch (ch) {
case '\b':
sb.append("\\b");
continue;
case '\t':
sb.append("\\t");
continue;
case '\n':
sb.append("\\n");
continue;
case '\f':
sb.append("\\f");
continue;
case '\r':
sb.append("\\r");
continue;
case '"':
sb.append("\\\"");
continue;
case '\\':
sb.append("\\\\");
continue;
}
if (ch >= 0 && ch <= 31 || ch >= 127 && ch <= 159 || ch >= 8192 && ch <= 8447) {
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);
}
}
}
@Override
public String toJson(Object object) {
return this.toJson(object, this.convertDepth);
}
protected String toJson(Object value, int depth) {
if (value != null && depth-- >= 0) {
if (value instanceof String) {
return "\"" + this.escape((String) value) + "\"";
} else if (value instanceof Double) {
return !((Double) value).isInfinite() && !((Double) value).isNaN() ? value.toString() : "null";
} else if (value instanceof Float) {
return !((Float) value).isInfinite() && !((Float) value).isNaN() ? value.toString() : "null";
} else if (value instanceof Number) {
return value.toString();
} else if (value instanceof Boolean) {
return value.toString();
} else {
String result;
if (value instanceof Date) {
if (value instanceof Timestamp) {
return "\"" + (new SimpleDateFormat(this.timestampPattern)).format(value) + "\"";
} else if (value instanceof Time) {
return "\"" + value.toString() + "\"";
} else {
result = this.datePattern != null ? this.datePattern : this.getDefaultDatePattern();
return result != null ? "\"" + (new SimpleDateFormat(result)).format(value) + "\"" : "" + ((Date) value).getTime();
}
} else if (value instanceof Collection) {
return this.iteratorToJson(((Collection) value).iterator(), depth);
} else if (value instanceof Map) {
return this.mapToJson((Map) value, depth);
} else {
result = this.otherToJson(value, depth);
return result != null ? result : "\"" + this.escape(value.toString()) + "\"";
}
}
} else {
return "null";
}
}
protected String otherToJson(Object value, int depth) {
if (value instanceof Character) {
return "\"" + this.escape(value.toString()) + "\"";
} else {
Map map;
if (value instanceof Model) {
map = CPI.getAttrs((Model) value);
return this.mapToJson(map, depth);
} else if (value instanceof Record) {
map = ((Record) value).getColumns();
return this.mapToJson(map, depth);
} else if (!value.getClass().isArray()) {
if (value instanceof Iterator) {
return this.iteratorToJson((Iterator) value, depth);
} else if (value instanceof Enumeration) {
ArrayList<?> list = Collections.list((Enumeration) value);
return this.iteratorToJson(list.iterator(), depth);
} else {
return value instanceof Enum ? "\"" + ((Enum) value).toString() + "\"" : this.beanToJson(value, depth);
}
} else {
int len = Array.getLength(value);
List<Object> list = new ArrayList(len);
for (int i = 0; i < len; ++i) {
list.add(Array.get(value, i));
}
return this.iteratorToJson(list.iterator(), depth);
}
}
}
protected String beanToJson(Object model, int depth) {
Map map = new HashMap();
Method[] methods = model.getClass().getMethods();
Method[] var5 = methods;
int var6 = methods.length;
for (int var7 = 0; var7 < var6; ++var7) {
Method m = var5[var7];
String methodName = m.getName();
int indexOfGet = methodName.indexOf("get");
if (indexOfGet == 0 && methodName.length() > 3) {
String attrName = methodName.substring(3);
if (!attrName.equals("Class")) {
Class<?>[] types = m.getParameterTypes();
if (types.length == 0) {
try {
Object value = m.invoke(model);
map.put(StrKit.firstCharToLowerCase(attrName), value);
} catch (Exception var15) {
throw new RuntimeException(var15.getMessage(), var15);
}
}
}
} 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 var16) {
throw new RuntimeException(var16.getMessage(), var16);
}
}
}
}
}
return this.mapToJson(map, depth);
}
@Override
public <T> T parse(String jsonString, Class<T> type) {
throw new RuntimeException("jfinal 3.6默认 com.renzhi.core.common.json 实现暂不支持 com.renzhi.core.common.json 到 object 的转换,建议使用 active recrord 的 Generator 生成 base model,再通过 me.setJsonFactory(new MixedJsonFactory()) 来支持");
}
private static String toCamelCase(String stringWithUnderline) {
if (stringWithUnderline.indexOf(95) == -1) {
char[] fromArray = stringWithUnderline.toCharArray();
boolean isHaveLowerCase = false;
boolean isHaveUperCase = false;
for (int i = 0; i < fromArray.length; ++i) {
if (Character.isUpperCase(fromArray[i])) {
isHaveUperCase = true;
} else if (Character.isLowerCase(fromArray[i])) {
isHaveLowerCase = true;
}
if (isHaveLowerCase && isHaveUperCase){
return stringWithUnderline;
}
}
return stringWithUnderline.toLowerCase();
} else {
stringWithUnderline = stringWithUnderline.toLowerCase();
char[] fromArray = stringWithUnderline.toCharArray();
char[] toArray = new char[fromArray.length];
int j = 0;
for (int i = 0; i < fromArray.length; ++i) {
if (fromArray[i] == '_') {
++i;
if (i < fromArray.length) {
toArray[j++] = Character.toUpperCase(fromArray[i]);
}
} else {
toArray[j++] = fromArray[i];
}
}
return new String(toArray, 0, j);
}
}
}