使用的序列化工具类为jackson,
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import org.codehaus.jackson.type.TypeReference;
/**
* Json转换的工具类 2013-03-26
*/
@SuppressWarnings({ "unchecked", "deprecation" })
public class JsonUtil {
private final static Log LOG = LogFactory.getLog(JsonUtil.class);
private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); // 新版 simleFactory 二进制,高性能
/**
* 空参数构造器
*/
private JsonUtil() {
}
/**
* 静态块初始化
*/
static {
// 设置输出包含的属性
OBJECT_MAPPER.getSerializationConfig().setSerializationInclusion(Inclusion.NON_NULL);
// 设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
OBJECT_MAPPER.getDeserializationConfig().set(org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
OBJECT_MAPPER.getSerializationConfig().setDateFormat(df);
OBJECT_MAPPER.getDeserializationConfig().setDateFormat(df);
}
/**
* 如果JSON字符串为Null或"null"字符串,返回Null. 如果JSON字符串为"[]",返回空集合.
*
* @param jsonString
* @param clazz
*/
public static <T> T fromJson(String jsonString, Class<T> clazz) {
if (StringUtils.isBlank(jsonString)) {
return null;
}
try {
return (T) OBJECT_MAPPER.readValue(jsonString, clazz);
} catch (IOException e) {
LOG.error("parse json string error:" + jsonString, e);
}
return null;
}
/**
* 读取集合如List/Map,且不是List<String>时.
*
* @param jsonString
* @param typeReference
* @return
*/
public static <T> T fromJson(String jsonString, TypeReference<T> typeReference) {
if (StringUtils.isBlank(jsonString)) {
return null;
}
try {
return (T) OBJECT_MAPPER.readValue(jsonString, typeReference);
} catch (IOException e) {
LOG.error("parse json string error:" + jsonString, e);
}
return null;
}
/**
* 如果对象为Null,返回"null". 如果集合为空集合,返回"[]".
*/
public static String toJson(Object object) {
try {
return OBJECT_MAPPER.writeValueAsString(object);
} catch (IOException e) {
LOG.warn("write to json string error:" + object, e);
}
return null;
}
/**
* 取出Mapper做进一步的设置或使用其他序列化API.
*/
public static ObjectMapper getMapper() {
return OBJECT_MAPPER;
}
public static void main(String[] args) {
Date tim = new Date();
System.out.println(tim);
String timStr = tim.toString();
System.out.println(timStr);
Date dat = fromJson(timStr, Date.class);
System.out.println(dat);
System.out.println(toJson(tim));
JsonUtil j = new JsonUtil();
timTest t = j.new timTest();
t.setName("123");
t.setTime(new Date());
System.out.println(toJson(t));
String js = "{\"name\":\"123\",\"time\":\"2015-07-20 18:06:16\"}";
String jso = "{\"name\":\"123\",\"time\":\"Mon Jul 20 18:06:16 GMT+08:00 2015\"}";
timTest rigth = fromJson(js, timTest.class);
timTest wrong = fromJson(jso, timTest.class);
System.out.println(rigth.getTime());
System.out.println(wrong.getTime());
}
class timTest {
private String name;
private Date time;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}
}
1. 遇到的问题,反序列化时间时报异常:
java.text.ParseException: Unparseable date: "Mon Jul 20 15:34:58 GMT+08:00 2015"
2. 问题分析:
2.1 程序中使用的时间格式化为:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2.2 需要反序列化的内容为:
{ "_id" : "15", "contentAbstract" : "第一个话题测试", "belongSubjectId" : "1", "yn" : "1", "creatTime" : "Mon Jul 20 15:34:58 GMT+08:00 2015" }
其中的时间格式为:Mon Jul 20 15:34:58 GMT+08:00 2015
2.3 问题定位:
反序列化的时间格式和预期的格式不一致导致出现异常。预期的格式为:yyyy-MM-dd HH:mm:ss;实际的格式为:Mon Jul 20 15:34:58 GMT+08:00 2015
3. 解决问题:
3.1 问题的解决关键点:
将格式调整为一致的格式,即可。
3.2 解决步骤:
方法一:将数据库中的内容的时间格式,进行调整。这个需要注意:写入数据库的程序也要调整,在写库前对时间进行格式化(这个可以在程序中将时间转化为String
也可以使用封装好的工具如:ibatis,这些工具会根据数据库定义语言的时间格式,将程序的中的时间转为对应的格式)
方法二:修改jsonutil的时间格式。不推荐,会引起其他副作用;因为使用jsonutil的地方很多,会引入更多bug
3.3 注意事项:
在对时间序列化时,如果存入的字符串也用jsonutil进行序列化,那么json会自动把时间格式化为设置的格式yyyy-MM-dd HH:mm:ss;取出字符串进行反序列化就没有问题了。
尽量避免在写入时使用一套格式时间的方式,取出数据时使用另外一种格式化方式。