用java发送Http请求,并对chunked解码的介绍

在阅读后面的代码之前,建议您先阅读这篇文章,了解一下chunked编码:

http://blog.csdn.net/whatday/article/details/7571451


简单介绍:

chunked的编码是吧整个压缩包分段传输,其实有点像我们把压缩包压缩时分成若干个压缩文件一样,解压的时候,必须把全部文件放到一个目录下解压缩。

这个编码也是如此,传过来的是一个一个块,最后需要把这些块都拼接起来才是完整的数据,所以,只要一次把这些块取出来拼到一块就可以了。


如何取:

chunked编码在压缩块前面都会有一个标识压缩块大小的16进制字符串,我们每次读取压缩块之前,需要先获得这个大小,以便告诉程序接下来该读取多少数据,下面一段代码就是获取这个值。

    /**
     * 获取压缩包块的大小
     * 
     * @param is
     * @return
     * @throws IOException
     */
	private static int getChunkSize(InputStream is) throws IOException {
		String sLength = readLine(is).trim();
		if (isBlank(sLength)) {  // 字符串前面有可能会是一个回车换行。
			// 读了一个空行,继续往下读取一行。
			sLength = readLine(is).trim();
		}
        if (sLength.length() < 4) {
        	sLength = 0 + sLength;
        }
        // 把16进制字符串转化为Int类型
        int length = Integer.valueOf(sLength, 16);
        return length;
	}

有了这个大小以后,就很容易获取后面的数据了,下面这段代码是读取块的数据,并进行递归:

	/**
	 * 读取gzip压缩的消息体
	 * 
	 * @param is
	 * @return
	 * @throws IOException
	 */
    private static List<Byte> readGzipBody(InputStream is) throws IOException {
    	// 压缩块的大小,由于chunked编码块的前面是一个标识压缩块大小的16进制字符串,在开始读取前,需要获取这个大小
    	int chunk = getChunkSize(is);
    	List<Byte> bodyByteList = new ArrayList<Byte>();
        byte readByte = 0;
        int count = 0;
        
        while (count < chunk) {  // 读取消息体,最多读取chunk个byte
            readByte = (byte) is.read();  
            bodyByteList.add(Byte.valueOf(readByte));
            count ++;
        }
        if (chunk > 0) { // chunk为读取到最后,如果没有读取到最后,那么接着往下读取。
        	List<Byte> tmpList = readGzipBody(is);
        	bodyByteList.addAll(tmpList);
        }
        return bodyByteList;
    }
	

取出来后,把Byte数组转换为字符串就可以了,代码如下:

	/**
	 * 获取没有压缩的消息体
	 * 
	 * @param is
	 * @param contentLe
	 * @return
	 */
	private static String readBody(InputStream is, int contentLe) {
		List<Byte> lineByteList = new ArrayList<Byte>();  
        byte readByte;  
        int total = 0; 
        try {
			do {  
				readByte = (byte) is.read();
	            lineByteList.add(Byte.valueOf(readByte));  
	            total++;  
	        } while (total < contentLe);
		} catch (IOException e) {
			e.printStackTrace();
		}  
        
        byte[] tmpByteArr = new byte[lineByteList.size()];  
        for (int i = 0; i < lineByteList.size(); i++) {  
            tmpByteArr[i] = ((Byte) lineByteList.get(i)).byteValue();  
        }  
        lineByteList.clear();  
  
        String line = "";
		try {
			line = new String(tmpByteArr, encoding);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		return line;
	}


主要的就这几个方法。

完整的代码可以到csdn里下载,见下面连接:

http://download.csdn.net/detail/lhj_5460/9069945

供大家参考,或者不是最好的方案,希望对大家有帮助。

写这段代码废了老大劲,java的代码没有找到有,大多数都是c,获取c++的代码比较多。


HTTP chunked编码是HTTP协议传输数据的一种方式,其本质上是将数据分成若干个小块进行传输,每个小块包含一定量的数据,以及用于表示数据块长度的十六进制数字。 Java提供了一些类和方法来解码HTTP chunked消息。在Java中,可以使用HttpURLConnection类中的getResponseCode()方法来获取HTTP响应的状态码。如果响应状态码为200,则可以使用getInputStream()方法来获取响应内容。此时,需要创建一个新的GZIPInputStream对象,并将getInputStream()的返回值作为参数传入。如果HTTP响应使用了chunked编码,则需要使用ChunkedInputStream类进行解码。此类继承了FilterInputStream类,并在read()方法中自动处理chunked格式。 在Java中,可以使用Apache HTTP Components库进行HTTP chunked编码的解码。具体来说,可以使用ChunkedInputStream类或者ChunkedEntity类来对chunked编码的HTTP响应消息进行解码。可以通过调用ChunkedInputStream类的read()方法来读取数据并将其解码。这个类可以处理chunked编码格式的消息,并自动进行解码。另外,ChunkedEntity类也可以实现HTTP chunked编码的解码,它可以将HTTP实体转换为一个正常的输入流。如果要使用该类进行解码,则需要创建一个HttpEntity对象,并将其作为参数传入ChunkedEntity类的构造函数中。 总之,使用Java进行HTTP chunked编码的解码相对比较简单,开发人员只需要了解Java中提供的类和方法,并说明消息所采用的编码格式,就可以比较轻松地实现解码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值