關於Java和.NET之間的通信問題(JSON)


前言:

  最近項目在某XX領導的所謂指引下,非要轉型Java,轉就轉吧,在轉的過程前期是個痛苦期,特別.NET舊有項目和Java新項目需要通信時。

 

  

  進入主題,Java和.NET之間需要通信,這時媒介很多,協議很多。其中json應該是比較常用的。而json一開始看過去,覺得這個問題實在簡單要弱智,沒什么好深究的。但是你實際做的過程中卻不是這樣。

 

  比如Java序列化/反序列化時區默認不是取服務器上的時區,比如.NET默認序列化DateTime格式是微軟自家定義的,到了Java那邊自然轉不了,報錯。

  廢話到此為止,先出點會報錯的代碼看看:

  

                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類型轉換失敗。比如以下錯誤信息:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.util.Date from String value '

 

  .NET那邊如果是Java序列化的數據呢?平常我一般都是用Newtonsoft序列化進去,也不用管太多其他。確實,不考慮Java方面,確實兩個語言上json沒什么好糾結的。但是如果現在還是和以前一樣過來的數據,.NET bool類型會轉換true/false,這時候Java是不能識別的。我們需要加一個轉換器,下面看看怎么搞才能全局上支持:

  

 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。

     再看看時間格式方面,你也需要做些時區以及格式上的設置:

  .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);

 

 

好了。

1、現在都在北京時間頻道下,現在都是iso標准格式。

2、bool類型全部用0,1

 

 

其他廢話,

1、spring附帶了jackson,所以沒考慮用其他json,為了統一。

2、這類格式和類型問題可以做一個通用的攔截器,全局幫大伙做了。好了,去做全局轉換攔截器了。

 

      

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM