간단한 bean에서 json의 클래스로 변환-hibernate에 의존

주된 성능은 오픈 소스 도구보다 향상되었고, JSON에서 BEAN으로의 전환은 없었다.

public class SimpleJson {
	private static final Logger logger = LoggerFactory
			.getLogger(SimpleJson.class);
	private static final Map<String, Map<String, Getter>> CLASS_MAP = new HashMap<String, Map<String, Getter>>();
	public static final SimpleDateFormat SDF = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	private SimpleJson() {}

	public static Map<String, Getter> describe(Class<?> beanClass) {
		String className = beanClass.getName();
		Map<String, Getter> map = CLASS_MAP.get(className);
		map = map == null ? new HashMap<String, Getter>() : map;
		if (map.isEmpty()) {
			Class<?> clazz = beanClass;
			while (clazz != null && !clazz.getClass().equals(Object.class)) {
				for (Field field : clazz.getDeclaredFields()) {
					int mod = field.getModifiers();
					if (Modifier.isStatic(mod) || Modifier.isFinal(mod)
						|| Modifier.isNative(mod) || Modifier.isStrict(mod)
						|| Modifier.isSynchronized(mod)
						|| Modifier.isTransient(mod)) {
						continue;
					}
					try {
						Getter getter = ReflectHelper
								.getGetter(beanClass, field.getName());
						map.put(field.getName(), getter);
					} catch (Exception e) {}
				}
				clazz = clazz.getSuperclass();
			}
			CLASS_MAP.put(className, map);
		}
		return map;
	}

	public static Object getValue(String fieldName, Object bean) {
		Map<String, Getter> gettes = describe(bean.getClass());
		Getter get = gettes.get(fieldName);
		return get == null ? null : get.get(bean);
	}

	public static String toJSONString(Object value) {
		StringBuilder sb = new StringBuilder(1024);
		HashMap<Object, Boolean> cache = new HashMap<Object, Boolean>();
		toJSONString(value, sb, cache);
		String string = sb.toString();
		sb = null;
		cache.clear();
		cache = null;
		return string;
	}

	private static void toJSONString(Object value, StringBuilder sb,
			Map<Object, Boolean> cache) {
		if (value == null) {
			sb.append("null");
		} else if (value instanceof Map) {
			toJSONString((Map) value, sb, cache);
		} else if (value instanceof List) {
			toJSONString((List) value, sb, cache);
		} else if (value instanceof String) {
			sb.append("\"");
			escape((String) value, sb);
			sb.append("\"");
		} else if (value instanceof Character) {
			sb.append("\"");
			escape(value == null ? "" : value.toString(), sb);
			sb.append("\"");
		} else if (value instanceof Double) {
			Double d = (Double) value;
			sb.append((d.isInfinite() || d.isNaN()) ? "null" : d.toString());
		} else if (value instanceof Float) {
			Float f = (Float) value;
			sb.append((f.isInfinite() || f.isNaN()) ? "null" : f.toString());
		} else if (value instanceof Number) {
			sb.append(value.toString());
		} else if (value instanceof Boolean) {
			sb.append(value.toString());
		} else if (value instanceof Date) {
			sb.append("\"").append(SDF.format((Date) value)).append("\"");
		} else if (value.getClass().isEnum()) {
			sb.append("\"").append(((Enum) value).toString()).append("\"");
		} else {
			Map<String, Getter> getters = describe(value.getClass());
			if (cache.get(value) != null) {
				Getter get = getters.get("id");
				if (get != null) {
					Object v = get.get(value);
					sb.append("{");
					toJSONString("id", v, sb, cache);
					sb.append("}");
				}
				return;
			} else {
				cache.put(value, Boolean.TRUE);
			}
			boolean first = true;
			Iterator<Entry<String, Getter>> iter = getters.entrySet()
					.iterator();
			sb.append('{');
			while (iter.hasNext()) {
				Entry<String, Getter> entry = iter.next();
				String key = entry.getKey();
				Object v = entry.getValue().get(value);
				if (key == null || v == null) {
					continue;
				}
				if (first) {
					first = false;
				} else {
					sb.append(',');
				}
				toJSONString(entry.getKey(), v, sb, cache);
			}
			sb.append('}');
		}
	}

	private static void toJSONString(Map map, StringBuilder sb,
			Map<Object, Boolean> cache) {
		if (map == null) {
			sb.append("null");
		}
		boolean first = true;
		Iterator iter = map.entrySet().iterator();
		sb.append('{');
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			Object key = entry.getKey();
			Object v = entry.getValue();
			if (key == null || v == null) {
				continue;
			}
			if (first) {
				first = false;
			} else {
				sb.append(',');
			}
			toJSONString(String.valueOf(key), v, sb, cache);
		}
		sb.append('}');
	}

	private static void toJSONString(List list, StringBuilder sb,
			Map<Object, Boolean> cache) {
		if (list == null) {
			sb.append("null");
		}
		boolean first = true;
		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;
			}
			toJSONString(value, sb, cache);
		}
		sb.append(']');
	}

	private static void toJSONString(String key, Object value,
			StringBuilder sb, Map<Object, Boolean> cache) {
		sb.append('\"');
		if (key == null) {
			sb.append("null");
		} else {
			escape(key, sb);
		}
		sb.append('\"').append(':');
		toJSONString(value, sb, cache);
	}

	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 '\b':
				sb.append("\\b");
				break;
			case '\f':
				sb.append("\\f");
				break;
			case '
': sb.append("\
"); break; case '\r': sb.append("\\r"); break; case '\t': sb.append("\\t"); break; case '/': sb.append("\\/"); break; default: //Reference: http://www.unicode.org/versions/Unicode5.1.0/ if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) { String ss = Integer.toHexString(ch); sb.append("\\u"); for (int k = 0; k < 4 - ss.length(); k++) { sb.append('0'); } sb.append(ss.toUpperCase()); } else { sb.append(ch); } } }//for } }

No Hibernate

import java.beans.Introspector;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class SimpleJson {
	private static final Map<String, Map<String, Getter>> CLASS_MAP = new HashMap<String, Map<String, Getter>>();
	public static final SimpleDateFormat SDF = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	private SimpleJson() {
	}

	public static Map<String, Getter> describe(Class<?> beanClass) {
		String className = beanClass.getName();
		Map<String, Getter> map = CLASS_MAP.get(className);
		map = map == null ? new HashMap<String, Getter>() : map;
		if (map.isEmpty()) {
			Class<?> clazz = beanClass;
			while (clazz != null && !clazz.getClass().equals(Object.class)) {
				for (Field field : clazz.getDeclaredFields()) {
					int mod = field.getModifiers();
					if (Modifier.isStatic(mod) || Modifier.isFinal(mod)
							|| Modifier.isNative(mod) || Modifier.isStrict(mod)
							|| Modifier.isSynchronized(mod)
							|| Modifier.isTransient(mod)) {
						continue;
					}
					try {
						Getter getter = Getter.getGetterOrNull(beanClass, field
								.getName());
						map.put(field.getName(), getter);
					} catch (Exception e) {
					}
				}
				clazz = clazz.getSuperclass();
			}
			CLASS_MAP.put(className, map);
		}
		return map;
	}

	public static Object getValue(String fieldName, Object bean) {
		Map<String, Getter> gettes = describe(bean.getClass());
		Getter get = gettes.get(fieldName);
		return get == null ? null : get.get(bean);
	}

	public static String toJSONString(Object value) {
		StringBuilder sb = new StringBuilder(1024);
		HashMap<Object, Boolean> cache = new HashMap<Object, Boolean>();
		toJSONString(value, sb, cache);
		String string = sb.toString();
		sb = null;
		cache.clear();
		cache = null;
		return string;
	}

	private static void toJSONString(Object value, StringBuilder sb,
			Map<Object, Boolean> cache) {
		if (value == null) {
			sb.append("null");
		} else if (value instanceof Map) {
			toJSONString((Map) value, sb, cache);
		} else if (value instanceof List) {
			toJSONString((List) value, sb, cache);
		} else if (value instanceof String) {
			sb.append("\"");
			escape((String) value, sb);
			sb.append("\"");
		} else if (value instanceof Character) {
			sb.append("\"");
			escape(value == null ? "" : value.toString(), sb);
			sb.append("\"");
		} else if (value instanceof Double) {
			Double d = (Double) value;
			sb.append((d.isInfinite() || d.isNaN()) ? "null" : d.toString());
		} else if (value instanceof Float) {
			Float f = (Float) value;
			sb.append((f.isInfinite() || f.isNaN()) ? "null" : f.toString());
		} else if (value instanceof Number) {
			sb.append(value.toString());
		} else if (value instanceof Boolean) {
			sb.append(value.toString());
		} else if (value instanceof Date) {
			sb.append("\"").append(SDF.format((Date) value)).append("\"");
		} else if (value.getClass().isEnum()) {
			sb.append("\"").append(((Enum) value).toString()).append("\"");
		} else {
			Map<String, Getter> getters = describe(value.getClass());
			if (cache.get(value) != null) {
				Getter get = getters.get("id");
				if (get != null) {
					Object v = get.get(value);
					sb.append("{");
					toJSONString("id", v, sb, cache);
					sb.append("}");
				}
				return;
			} else {
				cache.put(value, Boolean.TRUE);
			}
			boolean first = true;
			Iterator<Entry<String, Getter>> iter = getters.entrySet()
					.iterator();
			sb.append('{');
			while (iter.hasNext()) {
				Entry<String, Getter> entry = iter.next();
				String key = entry.getKey();
				Object v = entry.getValue().get(value);
				if (key == null || v == null) {
					continue;
				}
				if (first) {
					first = false;
				} else {
					sb.append(',');
				}
				toJSONString(entry.getKey(), v, sb, cache);
			}
			sb.append('}');
		}
	}

	private static void toJSONString(Map map, StringBuilder sb,
			Map<Object, Boolean> cache) {
		if (map == null) {
			sb.append("null");
		}
		boolean first = true;
		Iterator iter = map.entrySet().iterator();
		sb.append('{');
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			Object key = entry.getKey();
			Object v = entry.getValue();
			if (key == null || v == null) {
				continue;
			}
			if (first) {
				first = false;
			} else {
				sb.append(',');
			}
			toJSONString(String.valueOf(key), v, sb, cache);
		}
		sb.append('}');
	}

	private static void toJSONString(List list, StringBuilder sb,
			Map<Object, Boolean> cache) {
		if (list == null) {
			sb.append("null");
		}
		boolean first = true;
		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;
			}
			toJSONString(value, sb, cache);
		}
		sb.append(']');
	}

	private static void toJSONString(String key, Object value,
			StringBuilder sb, Map<Object, Boolean> cache) {
		sb.append('\"');
		if (key == null) {
			sb.append("null");
		} else {
			escape(key, sb);
		}
		sb.append('\"').append(':');
		toJSONString(value, sb, cache);
	}

	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 '\b':
				sb.append("\\b");
				break;
			case '\f':
				sb.append("\\f");
				break;
			case '
': sb.append("\
"); break; case '\r': sb.append("\\r"); break; case '\t': sb.append("\\t"); break; case '/': sb.append("\\/"); break; default: //Reference: http://www.unicode.org/versions/Unicode5.1.0/ if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) { String ss = Integer.toHexString(ch); sb.append("\\u"); for (int k = 0; k < 4 - ss.length(); k++) { sb.append('0'); } sb.append(ss.toUpperCase()); } else { sb.append(ch); } } }//for } public static final class Getter { private Class<?> clazz; private final transient Method method; private final String propertyName; private Getter(Class<?> clazz, Method method, String propertyName) { this.clazz = clazz; this.method = method; this.propertyName = propertyName; } public static boolean isPublic(Class<?> clazz, Member member) { return ((Modifier.isPublic(member.getModifiers())) && (Modifier .isPublic(clazz.getModifiers()))); } public static Getter getGetterOrNull(Class<?> theClass, String propertyName) { if ((theClass == Object.class) || (theClass == null)) { return null; } Method method = getterMethod(theClass, propertyName); if (method != null) { if (isPublic(theClass, method)) method.setAccessible(true); return new Getter(theClass, method, propertyName); } Getter getter = getGetterOrNull(theClass.getSuperclass(), propertyName); if (getter == null) { Class[] interfaces = theClass.getInterfaces(); for (int i = 0; (getter == null) && (i < interfaces.length); ++i) { getter = getGetterOrNull(interfaces[i], propertyName); } } return getter; } private static Method getterMethod(Class theClass, String propertyName) { Method[] methods = theClass.getDeclaredMethods(); for (int i = 0; i < methods.length; ++i) { if (methods[i].getParameterTypes().length == 0) { String methodName = methods[i].getName(); if (methodName.startsWith("get")) { String testStdMethod = Introspector .decapitalize(methodName.substring(3)); String testOldMethod = methodName.substring(3); if ((testStdMethod.equals(propertyName)) || (testOldMethod.equals(propertyName))) { return methods[i]; } } if (methodName.startsWith("is")) { String testStdMethod = Introspector .decapitalize(methodName.substring(2)); String testOldMethod = methodName.substring(2); if ((testStdMethod.equals(propertyName)) || (testOldMethod.equals(propertyName))) { return methods[i]; } } } } return null; } public Object get(Object target) { try { return this.method.invoke(target, null); } catch (Exception e) { throw new RuntimeException(e); } } public Object getForInsert(Object target, Map<?, ?> mergeMap) { return get(target); } public Class<?> getReturnType() { return this.method.getReturnType(); } public Member getMember() { return this.method; } public Method getMethod() { return this.method; } public String getMethodName() { return this.method.getName(); } public String toString() { return "Getter(" + this.clazz.getName() + '.' + this.propertyName + ')'; } } public static void main(String[] args) { List<Object> list = new ArrayList<Object>(); for (int i = 0; i < 3; i++) { Object o = new Object() { private String a = Math.random()+"aaa"; private String b = Math.random()+"bbb"; public String getA() { return a; } public void setA(String a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } }; list.add(o); } System.out.println(SimpleJson.toJSONString(list)); } }

좋은 웹페이지 즐겨찾기