zoukankan      html  css  js  c++  java
  • 关于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、这类格式和类型问题可以做一个通用的拦截器,全局帮大伙做了。好了,去做全局转换拦截器了。

          

  • 相关阅读:
    78. Subsets
    93. Restore IP Addresses
    71. Simplify Path
    82. Remove Duplicates from Sorted List II
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
    312. Burst Balloons
    程序员社交平台
    APP Store开发指南
    iOS框架搭建(MVC,自定义TabBar)--微博搭建为例
  • 原文地址:https://www.cnblogs.com/javen_lin/p/5465679.html
Copyright © 2011-2022 走看看