`
征途2010
  • 浏览: 246569 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

dubbo序列化问题(一)浮点数问题

阅读更多

dubbo是一个分布式服务框架,在国内比较常用,在开发过程中遇到一个浮点数反序列化问题。

问题描述,当参数是float类型的3.7,反序列化却得到了一个double类型的值:3.700000047683716。

然后,我写了个测试程序:

 

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;


import com.alibaba.com.caucho.hessian.io.Hessian2Input;
import com.alibaba.com.caucho.hessian.io.Hessian2Output;


public class TestHessionLite {


	public static void main(String[] args) throws IOException {
		HashMap<String,Float> map=new HashMap<String,Float>();
		Float loat=new Float(3.7);
		map.put("3.7", loat);
		
		byte[] aa=TestHessionLite.serialize(map);
		Object mm=TestHessionLite.deserialize(aa);
		System.out.println(mm.toString());
		
	}
	
	public static byte[] serialize(Object obj) throws IOException{  
		 ByteArrayOutputStream os = new ByteArrayOutputStream(); 
		 Hessian2Output ho = new Hessian2Output(os);  
		 byte[] cc = null;
		try {
			if(obj==null) throw new NullPointerException();  
		    ho.writeObject(obj);
		    ho.flushBuffer();
		    cc=os.toByteArray();  
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			ho.close();
		}
		return cc;  
	    
	} 
	
	public static Object deserialize(byte[] by) throws IOException{ 
		try {
			if(by==null) throw new NullPointerException();  
			ByteArrayInputStream is = new ByteArrayInputStream(by);
		    Hessian2Input hi = new Hessian2Input(is);  
		    return hi.readObject();  
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	    
	}  
}

 

 

输出结果为

 

{3.7=3.700000047683716}

 

 

然后由分别使用3.5、3.6进行测试

 

{3.6=3.5999999046325684}
{3.5=3.5}

 

 

经过测试,并不是所有小数都有问题,部分小数会出现序列化问题。

我的dubbo服务序列化使用的是dubbo默认的hession2,而使用hessian2协议,也就是传输对象序列化,它是二进制的RPC协议。

经过分析,问题应该是出在了十进制浮点数转二进制。

后面又查看了相关资料,以及写了十进制和二进制互转的测试程序发现,就是不分小数在float单精度下是无法表示出来的。具体原因可以见下面资料http://blog.csdn.net/zcczcw/article/details/7362473。

 

如果将float,改成double,就不存在刚才精度问题了,因为double是双精度,可以保存64位二进制;

但是当小数点超过8位时,double也会被截取。

 

而是用kryo进行序列化则不会出现上面问题,因为kryo不是通过二进制存储,是通过字节数组来进行存储,这样可以保证数据不用进行转化。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;

import org.apache.commons.codec.binary.Base64;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.JavaSerializer;

public class TestKryo {

	public static void main(String[] args) {

		HashMap<String,Float> map=new HashMap<String,Float>();
		Float loat=new Float(3.7);
		map.put("value", loat);
		
		String aa=TestKryo.serialize(map);
		Object mm=TestKryo.deserialize(aa,HashMap.class);
		System.out.println(mm.toString());
	}
	private static <T extends Serializable> String serialize(T obj) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.register(obj.getClass(), new JavaSerializer());
 
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Output output = new Output(baos);
        kryo.writeClassAndObject(output, obj);
        output.flush();
        output.close();
 
        byte[] b = baos.toByteArray();
        try {
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        return new String(new Base64().encode(b));
    }
 
    @SuppressWarnings("unchecked")
    private static <T extends Serializable> T deserialize(String obj,
            Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.register(clazz, new JavaSerializer());
 
        ByteArrayInputStream bais = new ByteArrayInputStream(
                new Base64().decode(obj));
        Input input = new Input(bais);
        return (T) kryo.readClassAndObject(input);
    }
}

 

 

分享到:
评论

相关推荐

    Dubbo 序列化协议 5 连问,你接得住不.PDF

    默认就是⾛ dubbo 协议,单⼀⻓连接,进⾏的是 NIO 异步通信,基于 hessian 作为序列化协议。使⽤的场景是:传输数据量⼩ (每次请求在 100kb 以内),但是并发量很⾼。 为了要⽀持⾼并发场景,⼀般是服务提供者就⼏...

    Dubbo序列化协议5连问,你接得住不?.docx

    在Dubbo中,序列化协议是实现RPC通信的关键部分,因为它涉及到数据的转换和网络传输。 1. **Dubbo支持的通信协议**: - **Dubbo协议**:默认协议,采用单个长连接和NIO异步通信,基于Hessian进行序列化。适用于大...

    dubbo注意的问题,注入问题,接口中的bo应该实现序列化,否则服务注册失败

    当服务接口中的BO(Business Object,业务对象)未实现序列化时,服务注册时可能会遇到问题,因为Dubbo在传输过程中通常需要将对象转换为字节流,这就涉及到了对象的序列化。 对象序列化是Java中一个重要的概念,它...

    dubbo admin dubbo可视化工具

    dubbo可视化工具

    dubbo-serialization-avro:适用于avro的dubbo序列化扩展

    双重序列化-avro 适用于dubbo的avro序列化工具。1.从src编译我们使用maven来构建和管理依赖项。 下载src git clone https://github.com/dubbo/dubbo-serialization-avro.git 从src构建,然后安装到本地maven存储库。...

    34_dubbo都支持哪些通信协议以及序列化协议?.zip

    标题 "34_dubbo都支持哪些通信协议以及序列化协议?" 暗示了我们即将探讨的是关于Dubbo框架在网络通信和数据序列化方面的内容。Dubbo是阿里巴巴开源的一个高性能、轻量级的Java服务治理框架,它为分布式应用提供了...

    dubbo自动化测试

    在IT行业中,Dubbo是一款非常知名的高性能、轻量级的Java RPC框架,它极大地促进了服务化时代的进程。本文将深入探讨“dubbo自动化测试”的主题,帮助开发者理解如何有效地进行Dubbo服务的自动化测试,提高代码质量...

    dubbo.xsd 文件 解决dubbo标签识别问题

    在Java企业级开发中,Dubbo是一个非常流行的高性能、轻量级的服务治理框架,它由阿里巴巴开源并维护。本文将详细解析"标题"和"描述"中提到的"Dubbo.xsd"文件及其在解决Dubbo标签识别问题中的作用。 首先,我们需要...

    dubbo-exp:Dubbo反序列化一键快速攻击测试工具,支持dubbo协议和http协议,支持hessian反序列化和java原生反序列化

    a --args gadget入参,多个参数使用多次该命令传入,例-a -a Calc-p --protocol [dubbo|http] 通讯协议名称,默认缺省dubbo-s --serialization [hessian|java] 序列化类型,默认缺省hessian-t --target 目标,例:...

    [Timeline Sec] - CVE-2020-1948:Dubbo Provider默认反序列化复现1

    然而,2020年,腾讯安全团队发现了一个重要的安全漏洞,即CVE-2020-1948,这是一个Dubbo Provider默认反序列化远程代码执行漏洞。攻击者可以构造恶意请求,导致任意代码被执行。 **漏洞细节** 在受影响的Dubbo版本...

    dubbo-admin可视化管理平台工具包.rar

    【标题】"dubbo-admin可视化管理平台工具包.rar" 提供的是Dubbo管理工具的可视化版本,这使得Dubbo服务的监控与管理变得更加直观和便捷。Dubbo是阿里巴巴开源的一款高性能、轻量级的Java服务治理框架,它专注于服务...

    dubbo捕获自定义异常_dubbo异常捕获_dubbo异常_自定义异常_捕捉异常_

    Dubbo 默认支持 Java 的序列化,但为了性能和安全性,可以考虑使用更轻量级的序列化库,如 Protobuf 或 JSON。 7. **错误码和异常信息** 在自定义异常类中定义错误码和错误信息,可以提供更清晰的错误上下文。这有...

    sacla编写的dubbo自动化部署工具

    【标题】"saca编写的dubbo自动化部署工具"是一个基于Scala编程语言开发的实用工具,主要用于简化Dubbo服务的部署流程。Scala是一种强大的、面向对象的编程语言,它结合了函数式编程的特性,使得代码更加简洁和可维护...

    scala编写的dubbo自动化部署工具

    Scala编写的Dubbo自动化部署工具是一款高效且便捷的软件,旨在简化Dubbo服务的部署流程。这个工具利用了Scala的强大功能和灵活性,结合了Dubbo的微服务框架,为开发人员提供了一种自动化的方式来管理他们的服务部署...

    Dubbo空指针问题测试代码.zip

    由于Dubbo是基于接口的RPC框架,因此服务提供者和服务消费者之间的交互是基于接口的实例,如果接口的实现类为null,或者某个关键字段未初始化,都可能导致NPE。 在测试代码中,我们通常会设计不同的场景来模拟各种...

    dubbo 视频下载

    6. **协议与序列化**:Dubbo支持多种通信协议,如HTTP、RMI、Hessian、Dubbo等,以及多种序列化方式,如Java序列化、FastJson、Kryo等。选择合适的协议和序列化方式对服务性能有很大影响。 7. **负载均衡策略**:...

    dubbo-zookeeper springSpringMVC 一个生产者,多消费者 例子

    1.dubbo-zookeeper springSpringMVC 一个生产者,多消费者 例子 2. ssm-dubbo 源码 ssm-tomcat 里放的是 warbao ,程序包 zookeeper-3.4.9 zookeeper 免安装包 设置都是默认的 zookeeper 端口 2181 dubbo-...

    一个最简单的 dubbo开发实例

    同时,Dubbo还支持多种序列化方式,如Java自带的序列化、Hessian2、FastJSON等,用于在网络间传输对象。 7. **服务治理(Service Governance)** Dubbo提供了丰富的服务治理功能,包括负载均衡、容错机制(如...

    dubbo+zookeeper透明化远程调用实战案例下载

    通过以上步骤,你就可以构建一个基于Dubbo和Zookeeper的透明化远程调用系统。这个实战案例能让你深入理解Dubbo的服务治理机制和Zookeeper的服务发现功能,对于分布式系统的建设和运维有着重要的实践价值。在实际开发...

Global site tag (gtag.js) - Google Analytics