前言:java
最近项目在某XX领导的所谓指引下,非要转型Java,转就转吧,在转的过程前期是个痛苦期,特别.NET旧有项目和Java新项目须要通讯时。spring
进入主题,Java和.NET之间须要通讯,这时媒介不少,协议不少。其中json应该是比较经常使用的。而json一开始看过去,以为这个问题实在简单要弱智,没什么好深究的。可是你实际作的过程当中却不是这样。json
好比Java序列化/反序列化时区默认不是取服务器上的时区,好比.NET默认序列化DateTime格式是微软自家定义的,到了Java那边天然转不了,报错。服务器
废话到此为止,先出点会报错的代码看看:app
ObjectMapper mapper = new ObjectMapper(); JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, Message.class); List<Message> olds = mapper.readValue(sv,javaType);
通常而言,转换一个列表Java使用spring集成的jackson语法如上,若是是Java本身序列化的数据呢,是反序列化回来是问题的,可是.NET那边序列化的数据呢?很差意思,时间格式转换失败,很差意思,bool类型转换失败。好比如下错误信息:ide
com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.util.Date from String value 'spa
.NET那边若是是Java序列化的数据呢?日常我通常都是用Newtonsoft序列化进去,也不用管太多其余。确实,不考虑Java方面,确实两个语言上json没什么好纠结的。可是若是如今仍是和之前同样过来的数据,.NET bool类型会转换true/false,这时候Java是不能识别的。咱们须要加一个转换器,下面看看怎么搞才能全局上支持:.net
public class BoolConverter : JsonConverter { public override bool CanConvert(Type objectType) { return true; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { try { if (reader.TokenType == JsonToken.Integer) { //数值 return Convert.ToInt32(reader.Value) == 1; } } catch (Exception ex) { throw new Exception(string.Format("Error converting value {0} to type '{1}'", reader.Value, objectType)); } throw new Exception(string.Format("Unexpected token {0} when parsing enum", reader.TokenType)); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value == null) { writer.WriteNull(); return; } //bool.TryParse() bool bValue = (bool)value; if (bValue) writer.WriteValue(1); else writer.WriteValue(0); } }
加了转换器,这时候确实能够解决bool类型转换时多语言问题,通用的通常都是0,1。code
再看看时间格式方面,你也须要作些时区以及格式上的设置:orm
.net:
var serializerSettings = new JsonSerializerSettings(); serializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat; serializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; return JsonConvert.SerializeObject(o, serializerSettings);
java:
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); df.setTimeZone(TimeZone.getTimeZone("GMT+8")); mapper.getDeserializationConfig().with(df); mapper.setDateFormat(df);
好了。
一、如今都在北京时间频道下,如今都是iso标准格式。
二、bool类型所有用0,1
其余废话,
一、spring附带了jackson,因此没考虑用其余json,为了统一。
二、这类格式和类型问题能够作一个通用的拦截器,全局帮大伙作了。好了,去作全局转换拦截器了。