import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import ognl.OgnlOps;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import com.opensymphony.xwork.util.OgnlUtil;
/**
* java对象与json字符串互转的工具类
*
*/
public class JsonUtil {
/**
* 将json字符串转成javabean
* @param jsonStr 要转换的json字符串
* @param toClass 要转化到的类型
* @param childMap 该类型中集合字段的字段名和集合元素类型map
* @return Object
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@SuppressWarnings("unchecked")
public static Object json2Bean(Class toClass,String jsonValue,Map<String,Class> childMap) throws Exception{
if( toClass == null || StringUtils.isBlank(jsonValue)) {
return null;
}
try{
jsonValue = URLDecoder.decode(jsonValue, "utf-8");
}catch(Exception e){
throw new Exception("编码格式错误!");
}
JSONObject object = null;
try{
object= new JSONObject(jsonValue);
}catch(Exception e){
throw new Exception("json格式错误!");
}
Object obj = toClass.newInstance();
Map<String,Object> sourceMap = toMap(object);
PropertyDescriptor[] props = OgnlUtil.getPropertyDescriptors(obj);
Map<String,Object> map = new HashMap<String,Object>();
//参数不区分大小写
for (PropertyDescriptor desc : props) {
Set entrys = sourceMap.entrySet();
boolean contains = false;
for(Iterator i = entrys.iterator();i.hasNext();){
Entry entry = (Entry) i.next();
if(((String)entry.getKey()).equalsIgnoreCase(desc.getName())){
map.put(desc.getName(), entry.getValue());
contains = true;
break;
}
}
if( contains ) {
Object value = null;
// 处理日期型
// "yyyy-MM-dd'T'HH:mm:ss'Z'"此格式是由json2.js转换后的Date格式
if(java.util.Date.class.isAssignableFrom(desc.getPropertyType())) {
String date = (String) map.get(desc.getName());
if(!validateDate(date)){
throw new Exception(desc.getName()+"日期格式错误!");
}
value = new SimpleDateFormat("yyyy-MM-dd").parse(date.trim());
} else if(java.sql.Date.class.isAssignableFrom(desc.getPropertyType())) {
String date = (String) map.get(desc.getName());
if(!validateDate(date)){
throw new Exception(desc.getName()+"日期格式错误!");
}
value = new java.sql.Date(new SimpleDateFormat("yyyy-MM-dd").parse(
date.trim()).getTime());
}
else if(Collection.class.isAssignableFrom(desc.getPropertyType()))
{
Class clz = childMap.get(desc.getName());
if(clz.isPrimitive() || CharSequence.class.isAssignableFrom(clz) || Number.class.isAssignableFrom(clz))
value = convertFromStringListSimple(map.get(desc.getName()).toString(),clz);
else value = convertFromStringListComplex(map.get(desc.getName()).toString(),clz);
}
else {
if(desc.getPropertyType().isPrimitive() || CharSequence.class.isAssignableFrom(desc.getPropertyType())
|| Number.class.isAssignableFrom(desc.getPropertyType())){
try{
value = OgnlOps.convertValue(map.get(desc.getName()),
desc.getPropertyType());
}catch(NumberFormatException e){
Class clz = desc.getPropertyType();
if(clz == Integer.TYPE||clz == Short.TYPE||clz == Long.TYPE||clz == BigInteger.class)
throw new Exception(desc.getName()+"应为整数!");
else if(clz == Double.TYPE||clz == Float.TYPE||clz == BigDecimal.class)
throw new Exception(desc.getName()+"应为数字!");
}
}
else {
value = json2Bean(desc.getPropertyType(),map.get(desc.getName()).toString(),null);
}
}
desc.getWriteMethod().invoke(obj, new Object[] { value });
}
}
return obj;
}
/**
* 将json字符串转成javabean 日期格式默认为yyyy-MM-dd HH:mm:ss
* @param jsonStr 要转换的json字符串
* @param toClass 要转化到的类型
* @param childMap 该类型中集合字段的字段名和集合元素类型map
* @param DateStyle 日期时间格式
* @return Object
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws ParseException
*/
@SuppressWarnings("unchecked")
public static Object json2Bean(Class toClass,String jsonValue,Map<String,Class> childMap,String DateStyle) throws Exception{
if(StringUtils.isBlank(DateStyle)){
DateStyle = DateUtil.DEFAULT_DATETIME_FORMAT;
}
if( toClass == null) {
return null;
}
try{
jsonValue = URLDecoder.decode(jsonValue, "utf-8");
}catch(Exception e){
throw new Exception("编码格式错误!");
}
JSONObject object = null;
try{
object= new JSONObject(jsonValue);
}catch(Exception e){
throw new Exception("json格式错误!");
}
Object obj = toClass.newInstance();
Map<String,Object> sourceMap = toMap(object);
PropertyDescriptor[] props = OgnlUtil.getPropertyDescriptors(obj);
Map<String,Object> map = new HashMap<String,Object>();
//参数不区分大小写
for (PropertyDescriptor desc : props) {
Set entrys = sourceMap.entrySet();
boolean contains = false;
for(Iterator i = entrys.iterator();i.hasNext();){
Entry entry = (Entry) i.next();
if(((String)entry.getKey()).equalsIgnoreCase(desc.getName())){
map.put(desc.getName(), entry.getValue());
contains = true;
break;
}
}
if( contains ) {
Object value = null;
// 处理日期型
// "yyyy-MM-dd'T'HH:mm:ss'Z'"此格式是由json2.js转换后的Date格式
if(java.util.Date.class.isAssignableFrom(desc.getPropertyType())) {
String date = (String) map.get(desc.getName());
try{
value = new SimpleDateFormat(DateStyle).parse(date.trim());
}catch(ParseException e3){
throw new Exception(desc.getName()+"="+date+";日期格式错误!");
}
} else if(java.sql.Date.class.isAssignableFrom(desc.getPropertyType())) {
String date = (String) map.get(desc.getName());
try{
value = new java.sql.Date(new SimpleDateFormat(DateStyle).parse(
date.trim()).getTime());
}catch(ParseException e3){
throw new Exception(desc.getName()+"="+date+";日期格式错误!");
}
}
else if(Collection.class.isAssignableFrom(desc.getPropertyType()))
{
Class clz = childMap.get(desc.getName());
if(clz.isPrimitive() || CharSequence.class.isAssignableFrom(clz) || Number.class.isAssignableFrom(clz))
value = convertFromStringListSimple(map.get(desc.getName()).toString(),clz);
else value = convertFromStringListComplex(map.get(desc.getName()).toString(),clz);
}
else {
if(desc.getPropertyType().isPrimitive() || CharSequence.class.isAssignableFrom(desc.getPropertyType())
|| Number.class.isAssignableFrom(desc.getPropertyType())){
try{
value = OgnlOps.convertValue(map.get(desc.getName()),
desc.getPropertyType());
}catch(NumberFormatException e){
Class clz = desc.getPropertyType();
if(clz == Integer.TYPE||clz == Short.TYPE||clz == Long.TYPE||clz == BigInteger.class)
throw new Exception(desc.getName()+"应为整数!");
else if(clz == Double.TYPE||clz == Float.TYPE||clz == BigDecimal.class)
throw new Exception(desc.getName()+"应为数字!");
}
}
else {
value = json2Bean(desc.getPropertyType(),map.get(desc.getName()).toString(),null);
}
}
desc.getWriteMethod().invoke(obj, new Object[] { value });
}
}
return obj;
}
public static Map<String,Object> json2Map(String jsonValue) throws Exception{
if (StringUtils.isBlank(jsonValue)) {
return null;
}
try {
jsonValue = URLDecoder.decode(jsonValue, "utf-8");
} catch (Exception e) {
throw new Exception("编码格式错误!");
}
JSONObject object = null;
try {
object = new JSONObject(jsonValue);
} catch (Exception e) {
throw new Exception("json格式错误!");
}
return toMap(object);
}
@SuppressWarnings("unchecked")
public static List<Map<String,String>> json2List(String jsonValue) throws Exception{
if (StringUtils.isBlank(jsonValue)) {
return null;
}
try {
jsonValue = URLDecoder.decode(jsonValue, "utf-8");
} catch (Exception e) {
throw new Exception("编码格式错误!");
}
JSONArray array = new JSONArray(jsonValue);
List<Map<String,String>> jsonList = new ArrayList<Map<String,String>>();
for(int i=0;i<array.length();i++){
Map jsonMap = toMap(array.getJSONObject(i));
jsonList.add(jsonMap);
}
return jsonList;
}
public static boolean validateDate(String date)
{
if(date == null ||date.trim().length() != 10)
return false;
else
{
date = date.trim();
String[] param = date.split("-");
if(param[0].length() != 4)
return false;
int month = Integer.parseInt(param[1]);
if(month < 1 || month > 12)
return false;
int day = Integer.parseInt(param[2]);
if(day < 1 || day > 31)
return false;
}
return true;
}
@SuppressWarnings("unchecked")
private static Object convertFromStringListSimple (String jsonValue,Class toClass) throws Exception
{
if( toClass == null) {
return null;
}
ArrayList<Object> list = new ArrayList<Object>();
JSONArray array = new JSONArray(jsonValue);
int i;
Object value = null;
for(i = 0; i < array.length(); i++)
{
Object property = array.get(i);
if(java.util.Date.class.isAssignableFrom(toClass))
{
String date = (String)property;
if(!validateDate(date)){
throw new Exception("日期格式错误!");
}
value = new SimpleDateFormat("yyyy-MM-dd").parse(date.trim());
}
else if(java.sql.Date.class.isAssignableFrom(toClass)){
String date = (String)property;
if(!validateDate(date)){
throw new Exception("日期格式错误!");
}
value = new java.sql.Date(new SimpleDateFormat("yyyy-MM-dd").parse(
date.trim()).getTime());
}
else value = OgnlOps.convertValue(property, toClass);
list.add(value);
}
return list;
}
@SuppressWarnings("unchecked")
private static Object convertFromStringListComplex( String jsonValue, Class toClass) throws Exception{
if( toClass == null) {
return null;
}
ArrayList<Object> list = new ArrayList<Object>();
JSONArray array = new JSONArray(jsonValue);
for (int i = 0; i < array.length(); i++) {
Object obj = toClass.newInstance();
Map map = toMap(array.getJSONObject(i));
PropertyDescriptor[] props = OgnlUtil.getPropertyDescriptors(obj);
for (PropertyDescriptor desc : props) {
if( map.containsKey(desc.getName()) ) {
Object value = null;
// 处理日期型
// "yyyy-MM-dd'T'HH:mm:ss'Z'"此格式是由json2.js转换后的Date格式
if(java.util.Date.class.isAssignableFrom(desc.getPropertyType())) {
String date = (String) map.get(desc.getName());
if(!validateDate(date)){
throw new Exception(desc.getName()+"日期格式错误!");
}
value = new SimpleDateFormat("yyyy-MM-dd").parse(date.trim());
} else if(java.sql.Date.class.isAssignableFrom(desc.getPropertyType())) {
String date = (String) map.get(desc.getName());
if(!validateDate(date)){
throw new Exception(desc.getName()+"日期格式错误!");
}
value = new java.sql.Date(new SimpleDateFormat("yyyy-MM-dd").parse(
date.trim()).getTime());
} else {
try{
value = OgnlOps.convertValue(map.get(desc.getName()),
desc.getPropertyType());
}catch(NumberFormatException e){
Class clz = desc.getPropertyType();
if(clz == Integer.class||clz == Short.class||clz == Long.class||clz == BigInteger.class)
throw new Exception(desc.getName()+"应为整数!");
else if(clz == Double.class||clz == Float.class||clz == BigDecimal.class)
throw new Exception(desc.getName()+"应为数字!");
}
}
desc.getWriteMethod().invoke(obj, new Object[] { value });
}
}
list.add(obj);
}
return list;
}
@SuppressWarnings("unchecked")
private static Map<String,Object> toMap(JSONObject object) throws Exception {
HashMap<String, Object> map = new HashMap<String, Object>();
Iterator iter = object.keys();
while (iter.hasNext()) {
String key = (String) iter.next();
Object val = object.get(key);
if(val != null && !val.toString().trim().equals(""))
map.put(key,val);
}
return map;
}
/**
* 将javabean转成json字符串
* @param cls 要转的javabean类型
* @param value 要转的javabean
* @return String
*
*/
public static String bean2Json(Class<?> cls, Object value) {
try {
return transToJSONObject(cls, value).toString();
} catch (Exception e) {
log.error("转换jsonObject失败",e);
return null;
}
}
// 将value转换成JSONObject
@SuppressWarnings("unchecked")
private static Object transToJSONObject(Class<?> cls, Object value) throws Exception {
Object json = null;
if (value != null) {
if (Collection.class.isAssignableFrom(cls)) {
// 列表s
Iterator iter = ((Collection) value).iterator();
JSONArray array = new JSONArray();
while (iter.hasNext()) {
Object element = iter.next();
if( element != null ) {
array.put(transToJSONObject(element.getClass(), element));
}
}
json = array;
} else if (cls.isArray()) {
// 数组
JSONArray array = new JSONArray();
int length = Array.getLength(value);
for (int i = 0; i < length; i++) {
Object element = Array.get(value, i);
if( element != null ) {
array.put(transToJSONObject(element.getClass(), element));
}
}
json = array;
} else if (Map.class.isAssignableFrom(cls)) {
// 映射
Iterator iter = ((Map) value).entrySet().iterator();
JSONObject object = new JSONObject();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object v = entry.getValue();
if( v != null ) {
object.put(entry.getKey().toString(), transToJSONObject(v.getClass(), v));
}
}
json = object;
} else if (cls.isPrimitive() || CharSequence.class.isAssignableFrom(cls) || Number.class.isAssignableFrom(cls)) {
// 基本类型、数值或字符串
if (cls == Boolean.TYPE
|| cls == Integer.TYPE
|| cls == Float.TYPE
|| cls == Double.TYPE
|| cls == Long.TYPE
|| cls == Short.TYPE
|| cls == Byte.TYPE
|| cls.isAssignableFrom(Number.class)) {
json = value;
} else {
json = value.toString();
}
} else if (java.util.Date.class.isAssignableFrom(cls) || java.sql.Date.class.isAssignableFrom(cls)) {
json = value.toString();
} else {
// 对象
Map map = OgnlUtil.getBeanMap(value);
JSONObject object = new JSONObject();
if ( map != null ) {
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry element = (Map.Entry) iter.next();
Object v = element.getValue();
if( v != null ) {
object.put((String)element.getKey(), transToJSONObject(v.getClass(), v));
}else{
object.put((String)element.getKey(), "null");
}
}
json = object;
}
}
}
return json == null ? "" : json;
}
@SuppressWarnings("unchecked")
public static void main(String args[]) throws Exception{
String str = "[\"1\",\"2\",\"3\",\"4\"]";
ArrayList list = (ArrayList)JsonUtil.json2Bean(ArrayList.class, str, null);
System.out.println(list.get(0));
}
private static Log log = LogFactory.getLog(JsonUtil.class);
}