JsonUtils & json转换

package com.ynet.ci.utils;

import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.type.TypeFactory;


/**
* JSON 转换相关的工具类 注意,Map的Key只能为简单类型 ,不可采用复杂类型.
* @author moping
*/


@SuppressWarnings(“unchecked”)
public final class JsonUtils {

private static final TypeFactory TYPE_FACTORY = TypeFactory.defaultInstance();
private static final long LONG_JS_MAX_VLAUE = 1L << 53;
private static final Pattern NUMBER_PATTERN = Pattern.compile("^\\d*$");
private static final Pattern DATE_1_PATTERN = Pattern.compile("^19\\d{12}$");
private static final Pattern DATE_2_PATTERN = Pattern.compile("^20\\d{12}$");
private static final Pattern DATE_3_PATTERN = Pattern.compile("^\\d{4}[-]\\d{2}$");
private static final Pattern DATE_4_PATTERN = Pattern.compile("^\\d{4}[-]\\d{2}[-]\\d{2}$");
private static final Pattern DATE_5_PATTERN = Pattern.compile("^\\d{4}[-]\\d{2}[-]\\d{2} \\d{2}[:]\\d{2}[:]\\d{2}$");
private static final Pattern DATE_6_PATTERN = Pattern.compile("^\\d{4}[-]\\d{2}[-]\\d{2} \\d{2}[:]\\d{2}[:]\\d{2}[.]\\d{3}$");

private static final ObjectMapper MAPPER;

static {
    MAPPER = new ObjectMapper();
    MAPPER.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    MAPPER.enable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
    MAPPER.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    // Long
    SimpleModule module = new SimpleModule();
    JsonSerializer<Long> longSerializer = new JsonSerializer<Long>() {
        public void serialize(Long value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
                JsonProcessingException {
            if (value >= LONG_JS_MAX_VLAUE) {
                jgen.writeString(value.toString());
            } else {
                jgen.writeNumber(value);
            }
        }

    };
    JsonDeserializer<? extends Long> longDeserializer = new JsonDeserializer<Long>() {
        public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
                JsonProcessingException {
            return Long.valueOf(jp.getValueAsString());
        }
    };
    // BIGINTEGER
    JsonSerializer<BigInteger> bigIntSerializer = new JsonSerializer<BigInteger>() {
        public void serialize(BigInteger value, JsonGenerator jgen, SerializerProvider provider)
                throws IOException, JsonProcessingException {
            if (value.longValue() >= LONG_JS_MAX_VLAUE) {
                jgen.writeString(value.toString());
            } else {
                jgen.writeNumber(value);
            }
        }
    };
    // BIGDECIMAL
    JsonSerializer<BigDecimal> bigDecSerializer = new JsonSerializer<BigDecimal>() {
        public void serialize(BigDecimal value, JsonGenerator jgen, SerializerProvider provider)
                throws IOException, JsonProcessingException {
            jgen.writeString(String.valueOf(value));
        }
    };
    // DATE
    JsonDeserializer<Date> dateDeserializer = new JsonDeserializer<Date>() {
        public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
                JsonProcessingException {
            String text = jp.getValueAsString();
            if (StringUtils.isEmpty(text)) {
                return null;
            } 
            if(NUMBER_PATTERN.matcher(text).matches()) {
                if(DATE_2_PATTERN.matcher(text).matches() || DATE_1_PATTERN.matcher(text).matches()) {
                    return string2Date(text, "yyyyMMddHHmmss");
                }
                // MS
                return new Date(Long.valueOf(text));
            }
            if(DATE_3_PATTERN.matcher(text).matches()) {
                return string2Date(text, "yyyy-MM");
            }
            if(DATE_4_PATTERN.matcher(text).matches()) {
                return string2Date(text, "yyyy-MM-dd");
            }
            if(DATE_5_PATTERN.matcher(text).matches()) {
                return string2Date(text, "yyyy-MM-dd HH:mm:ss");
            }
            if(DATE_6_PATTERN.matcher(text).matches()) {
                return string2Date(text, "yyyy-MM-dd HH:mm:ss.SSS");
            }
            throw new RuntimeException("日期数据格式不符 - " + text);
        }
    };
    module.addSerializer(long.class, longSerializer);
    module.addSerializer(Long.class, longSerializer);
    module.addSerializer(BigInteger.class, bigIntSerializer);
    module.addSerializer(BigDecimal.class, bigDecSerializer);

    module.addDeserializer(long.class, longDeserializer);
    module.addDeserializer(Long.class, longDeserializer);
    module.addDeserializer(Date.class, dateDeserializer);
    MAPPER.registerModule(module);
}

private JsonUtils() {
    throw new IllegalAccessError("该类不允许实例化");
}

/**
 * 将对象转换为 JSON 的字符串格式
 * @param obj 被转换的对象
 * @return 当参数为空时会返回null

public static String object2String(Object obj) {
    if (obj == null) {
        return null;
    }
    StringWriter writer = new StringWriter();
    try {
        MAPPER.writeValue(writer, obj);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将对象[{}]转换为JSON字符串时发生异常", obj, e);
        throw new RuntimeException(message.getMessage(), e);
    }
    return writer.toString();
}

/**
 * 将 JSON 格式的字符串转换为 map
 * @param json JSON,允许为空
 * @return json为null时会返回空的Map实例
 */

public static Map<String, Object> string2Map(String json) {
    try {
        if (StringUtils.isBlank(json)) {
            return HashMap.class.newInstance();
        }
        JavaType type = TYPE_FACTORY.constructMapType(HashMap.class, String.class, Object.class);
        return MAPPER.readValue(json, type);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为Map时出现异常", json);
        throw new RuntimeException(message.getMessage(), e);
    }
}

/**
 * 将 JSON 格式的字符串转换为数组
 * @param <T>
 * @param json 字符串
 * @param clz 数组类型
 * @return json为null时会返回null
 */

public static <T> T[] string2Array(String json, Class<T> clz) {
    try {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        JavaType type = TYPE_FACTORY.constructArrayType(clz);
        return (T[]) MAPPER.readValue(json, type);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为数组时出现异常", json, e);
        throw new RuntimeException(message.getMessage(), e);
    }
}

/**
 * 将 JSON 格式的字符串转换为对象
 * @param <T>
 * @param json 字符串
 * @param clz 对象类型
 * @return json为null时会返回null

public static <T> T string2Obj(String json, Class<T> clz) {
    try {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        JavaType type = TYPE_FACTORY.constructType(clz);
        return (T) MAPPER.readValue(json, type);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为对象[{}]时出现异常",
                new Object[] { json, clz.getSimpleName(), e });
        throw new RuntimeException(message.getMessage(), e);
    }
}

/**
 * 将 JSON 格式的字符串转换为对象
 * @param <T>
 * @param json 字符串
 * @param type 对象类型
 * @return json为null时会返回null
 */

public static <T> T string2Obj(String json, Type type) {
    try {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        JavaType t = TYPE_FACTORY.constructType(type);
        return (T) MAPPER.readValue(json, t);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为对象[{}]时出现异常", new Object[] { json, type, e });
        throw new RuntimeException(message.getMessage(), e);
    }
}

/***
 * json 泛型转换
 * @param tr 示例 new TypeReference<List<Long>>(){}
 **/ 

public static <T> T string2GenericObject(String json, TypeReference<T> tr) {
    if (StringUtils.isBlank(json)) {
        return null;
    } else {
        try {
            return (T) MAPPER.readValue(json, tr);
        } catch (Exception e) {
            FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为[{}]时出现异常", new Object[] { json, tr });
            throw new RuntimeException(message.getMessage(), e);
        }
    }
}

/**
 * 将 JSON 格式的字符串转换为对象
 * @param <T>
 * @param json 字符串
 * @param type 对象类型
 * @return json为null时会返回null
 */ 

public static <T> T bytes2Object(byte[] json, Type type) {
    try {
        if (json == null || json.length == 0) {
            return null;
        }
        JavaType t = TYPE_FACTORY.constructType(type);
        return (T) MAPPER.readValue(json, t);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为对象[{}]时出现异常", new Object[] { json, type, e });
        throw new RuntimeException(message.getMessage(), e);
    }
}

/***
 * json数组泛型转换
 * @param tr 示例 new TypeReference<List<Long>>(){}
 **/ 

public static <T> T bytes2GenericObject(byte[] json, TypeReference<T> tr) {
    if (json == null || json.length == 0) {
        return null;
    } else {
        try {
            return (T) MAPPER.readValue(json, tr);
        } catch (Exception e) {
            FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为[{}]时出现异常", new Object[] { json, tr });
            throw new RuntimeException(message.getMessage(), e);
        }
    }
}

/**
 * 将 JSON 格式的字符串转换为集合
 * @param <T>
 * @param json 字符串
 * @param collectionType 集合类型
 * @param elementType 元素类型
 * @return json为null时会返回空的集合实例
 */ 

public static <C extends Collection<E>, E> C string2Collection(String json, Class<C> collectionType,
        Class<E> elementType) {
    try {
        if (StringUtils.isBlank(json)) {
            return collectionType.newInstance();
        }
        JavaType type = TYPE_FACTORY.constructCollectionType(collectionType, elementType);
        return MAPPER.readValue(json, type);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为集合[{}]时出现异常", new Object[] { json,
            collectionType.getSimpleName(), e });
        throw new RuntimeException(message.getMessage(), e);
    }
}

/**
 * 将字符串转换为{@link HashMap}对象实例
 * @param json 被转换的字符串
 * @param keyType 键类型
 * @param valueType 值类型
 * @return json为null时会返回空的HashMap实例
 */ 

public static <K, V> Map<K, V> string2Map(String json, Class<K> keyType, Class<V> valueType) {
    try {
        if (StringUtils.isBlank(json)) {
            return HashMap.class.newInstance();
        }
        JavaType type = TYPE_FACTORY.constructMapType(HashMap.class, keyType, valueType);
        return (Map<K, V>) MAPPER.readValue(json, type);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为Map时出现异常", json);
        throw new RuntimeException(message.getMessage(), e);
    }
}

/**
 * 将字符串转换为特定的{@link Map}对象实例
 * @param json 被转换的字符串
 * @param keyType 键类型
 * @param valueType 值类型
 * @param mapType 指定的{@link Map}类型
 * @return json为空时会返回空的Map实例
 */ 

public static <M extends Map<K, V>, K, V> M string2Map(String json, Class<K> keyType, Class<V> valueType,
        Class<M> mapType) {
    try {
        if (StringUtils.isBlank(json)) {
            return mapType.newInstance();
        }
        JavaType type = TYPE_FACTORY.constructMapType(mapType, keyType, valueType);
        return MAPPER.readValue(json, type);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将字符串[{}]转换为Map时出现异常", json);
        throw new RuntimeException(message.getMessage(), e);
    }
}

/**
 * 将 JSON 对象类型转换
 * @param <T>
 * @param value 字符串
 * @param type 对象类型
 * @return json为null时会返回null
 */ 

public static <T> T convertObject(Object value, TypeReference<T> type) {
    try {
        if (value == null) {
            return null;
        }
        JavaType t = TYPE_FACTORY.constructType(type);
        return (T) MAPPER.convertValue(value, t);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将对象[{}]转换为类型[{}]时出现异常", new Object[] { value, type, e });
        throw new RuntimeException(message.getMessage(), e);
    }
}

/**
 * java map 转换对象
 * @param mapData 原始数据
 * @param tr 转换类型
 */ 

public static <T> T map2Object(Map<?, ?> mapData, TypeReference<T> tr) {
    try {
        JsonNode node = MAPPER.valueToTree(mapData);
        return MAPPER.readValue(node.traverse(), tr);
    } catch (Exception e) {
        FormattingTuple message = MessageFormatter.format("将MAP[{}]转换为[{}]时出现异常", new Object[] { mapData, tr });
        throw new RuntimeException(message.getMessage(), e);
    }
}

private static Date string2Date(String string,String pattern){
    try {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        Date date = format.parse(string);
        return date;
    } catch (ParseException e) {
        throw new IllegalArgumentException("无法将字符串:"+string+"转成日期");
    }
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值