关于Invalid Http response解决的一次记录

本文讲述了作者在使用Java通过URLConnection发送HTTP请求时遇到的错误,涉及不标准HTTP响应处理。作者通过自定义HttpURLConnection类并重写getResponseCode方法,解决了问题并分享了具体步骤。
摘要由CSDN通过智能技术生成

有个需求,要用http请求控制和获取一个设备,我使用浏览器直接发送请求和使用ajax都是正常的,但是使用java代码发送http请求居然报错 java.io.IOException: Invalid Http response 我的代码是用的URLConnection

String result = "";
        BufferedReader in = null;
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
            connection.setRequestProperty("Accept-Encoding","gzip, deflate");
            connection.setRequestProperty("Accept-Language","zh-CN,zh;q=0.9");
            connection.setRequestProperty("Cache-Control","max-age=0");
            connection.setRequestProperty("Connection","keep-alive");
            connection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36");
            connection.setRequestProperty("Content-Type","text/plain");

            // 建立实际的连接
            connection.connect();
            // 定义 BufferedReader输入流来读取URL的响应
            InputStream inputStream=connection.getInputStream();
            in = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        } finally {// 使用finally块来关闭输入流
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

报错就在getInputStream那里,用了很多网上的方法,说是重复连接什么的,都没好使,后来我使用抓包工具 wireshark 发现这个设备给的返回值有问题
蓝色的那行是设备返回的数据
可以看到,其他的请求返回的都是符合http格式的,这个玩意返回的直接就是数据,不符合格式.

后来,我点到源码里取找到底哪里报的这个错,发现在 sun.net.www.protocol.http.HttpURLConnection 这个类是URLConnection的实现类,我去debug他的getInputStream方法,最后走的是getInputStream0方法,而抛出异常也在这个方法里
在这里插入图片描述
就是如果这个 getResponseCode 返回值为-1 那么就抛出这个异常,我想了一下,那么如果我继承这个类然后重写一下这个方法,是不是就好了

public class MyHttpURLConnection extends HttpURLConnection {
    protected MyHttpURLConnection(URL url, Handler handler) throws IOException {
        super(url, handler);
    }

    public MyHttpURLConnection(URL url, String s, int i) throws IOException {
        super(url, s, i);
    }

    public MyHttpURLConnection(URL url, Proxy proxy) throws IOException {
        super(url, proxy);
    }

    protected MyHttpURLConnection(URL url, Proxy proxy, Handler handler) throws IOException {
        super(url, proxy, handler);
    }
    
    public int getResponseCode() throws IOException {
        System.out.println("200 ok");
        return 200;
    }

}

然后,强制它返回200(这个因为我只在这一个地方用,而且也没细看其他的实现,只想获取他的输入流然后解析,所以就这么写了,大家如果有更好的方法可以评论一下),我找如何将我自己的类替换这个父类,然后去找URL的openConnection方法,发现是一个Handler类去生成的,这个handler是构造可以传入的,ok,继承,重写一条龙

public class MyHandler extends Handler {

    protected URLConnection openConnection(URL var1, Proxy var2) throws IOException {
        //这里返回自己的
        return new MyHttpURLConnection(var1, var2, this);
    }

}

继承的是sun.net.www.protocol.http.Handler,不要弄错
然后修改一开始的那个URL的new的方法就行了

			//URL realUrl = new URL(url);
			URL realUrl = new URL(null,url,new MyHandler());

然后测试执行打印 sendGet__result:<?xml version="1.0" encoding="utf-8"?>… ,ok了!
这个解决的方法可能比较粗暴,如果大家有更好的方法,欢迎讨论

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值