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

          

  • 相关阅读:
    【RabbitMQ】10 深入部分P3 死信队列(交换机)
    【RabbitMQ】09 深入部分P2 消费限流 & TTL
    【RabbitMQ】08 深入部分P1 可靠性投递
    【RabbitMQ】06 Spring整合RabbitMQ
    【RabbitMQ】07 SpringBoot整合RabbitMQ
    【RabbitMQ】05 通配符模式
    【RabbitMQ】04 路由模式
    【RabbitMQ】03 订阅模式
    【RabbitMQ】02 工作队列模式
    【RabbitMQ】01 简单模式
  • 原文地址:https://www.cnblogs.com/javen_lin/p/5465679.html
Copyright © 2020-2023  润新知