java net 请求发送demo

本文介绍了如何使用Java原生方式发送HTTP请求,以调用京东万象天气预报API为例,展示了设置请求参数、获取响应的过程。通过分析代码,揭示了在使用HttpURLConnection时可能出现的"重复连接错误"问题及其原因。
摘要由CSDN通过智能技术生成

java net 请求发送

我们日常对接第三方接口会有很多的便利的方式,如httpclient,等等的工具,不过底层的通过java原生的形式还是需要记录一下的。

环境介绍:

京东万象:京东旗下的一个服务接口集合有很多的服务:https://wx.jdcloud.com/api

在这里插入图片描述

这里的都是提供了API,通过请求API可以获得信息。

我们这里选择全国天气预报看到接口为:

在这里插入图片描述

​ 我们分析一下接口,这里面提供了url要我们提供自己账号的appkey,这样才能提供服务。参数里面有三个不过可以任选其一。我们这里就查询西安和青岛的天气。

我们先查询一下青岛获得响应:

Response:
Status Code: 200
Time:166ms
Date:Fri 18 Jun 2021 12:12:48 GMT
Body:
{
    "code": "10000",
    "charge": false,
    "msg": "查询成功",
    "result": {
        "status": 0,
        "msg": "ok",
        "result": {
            "city": "青岛",
            "cityid": 283,
            "citycode": "101120201",
            "date": "2021-06-18",
            "week": "星期五",
            "weather": "晴",
            "temp": "23",
            "temphigh": "28",
            "templow": "21",
            "img": "0",
            "humidity": "70",
            "pressure": "992",
            "windspeed": "4.1",
            "winddirect": "南风",
            "windpower": "2级",
            "updatetime": "2021-06-18 19:50:00",
            "index": [
                {
                    "iname": "空调指数",
                    "ivalue": "较少开启",
                    "detail": "您将感到很舒适,一般不需要开启空调。"
                },
                。。。
            ],
            "aqi": {
                "so2": "8",
                "so224": "8",
                "no2": "38",
                "no224": "40",
                "co": "0.720",
                "co24": "0.660",
                "o3": "149",
                "o38": "154",
                "o324": "154",
                "pm10": "81",
                "pm1024": "47",
                "pm2_5": "37",
                "pm2_524": "25",
                "iso2": "3",
                "ino2": "20",
                "ico": "8",
                "io3": "51",
                "io38": "96",
                "ipm10": "62",
                "ipm2_5": "51",
                "aqi": "96",
                "primarypollutant": "O3",
                "quality": "良",
                "timepoint": "2021-06-18 19:00:00",
                "aqiinfo": {
                    "level": "二级",
                    "color": "#FFFF00",
                    "affect": "空气质量可接受,但某些污染物可能对极少数异常敏感人群健康有较弱影响",
                    "measure": "极少数异常敏感人群应减少户外活动"
                }
            },
            "daily": [
                {
                    "date": "2021-06-18",
                    "week": "星期五",
                    "sunrise": "04:41",
                    "sunset": "19:18",
                    "night": {
                        "weather": "晴",
                        "templow": "21",
                        "img": "0",
                        "winddirect": "西南风",
                        "windpower": "3-5级"
                    },
                    "day": {
                        "weather": "晴",
                        "temphigh": "28",
                        "img": "0",
                        "winddirect": "北风",
                        "windpower": "3-5级"
                    }
                },
                {
                    "date": "2021-06-19",
                    "week": "星期六",
                    "sunrise": "04:41",
                    "sunset": "19:18",
                    "night": {
                        "weather": "晴",
                        "templow": "21",
                        "img": "0",
                        "winddirect": "西南风",
                        "windpower": "3-5级"
                    },
                    "day": {
                        "weather": "晴",
                        "temphigh": "29",
                        "img": "0",
                        "winddirect": "西南风",
                        "windpower": "3-5级"
                    }
                }。。。
            ],
            "hourly": [
                {
                    "time": "19:00",
                    "weather": "晴",
                    "temp": "25",
                    "img": "0"
                },
               。。。。
               
            ]
        }
    },
    "requestId": "dc199bef986d43229d422e4bb0468bf3"
}

这些东西和我们日常看的天气信息无异。

ps通过citycode我们可以知道,这里可以获得城市和编号的表,如果有牵扯到地方的业务使用这个统一的表会方面一些。

    private  static final String APPKEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    private  static final String URL="http://way.jd.com/jisuapi/weather";
    private  static final String PARAMETER_CITY="city";

    public static void main(String[] args) throws Exception {

        // 地址转为url
        java.net.URL url = new URL(URL);
        // 建立连接
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();

        // 这里是设置属性 即 设置了头部并不是参数
        //connection.addRequestProperty("city","青岛");
        //connection.addRequestProperty("appkey",APPKEY);

        //String s1 = StreamUtils.copyToString(connection.getInputStream(), Charset.forName("UTF-8"));
        //System.out.println(s1);

        connection.setDoOutput(true);
        connection.setRequestMethod("GET");

        // 加入参数信息
        StringBuffer stringBuffer = new StringBuffer();
        StringBuffer parameter = stringBuffer.append("city=").append("青岛").append("&appkey=").append(APPKEY);
        //参数加入连接还是通过流的形式
        connection.getOutputStream().write(parameter.toString().getBytes());
        
        //connection.connect(); 发现这一行注销掉依然可以请求请求
        String s = StreamUtils.copyToString(connection.getInputStream(), Charset.forName("UTF-8"));
        System.out.println(s);

    }

对于java net发送的总结

1.URL建立连接,只是获取了连接的对象并不是真正的连接,http是无状态的短连接,如果在连接以后设置发送参数如方法等会报错:重复连接错误
在这里插入图片描述

对应的源码为:

public void setDoOutput(boolean dooutput) {
        if (connected)
            throw new IllegalStateException("Already connected");
        doOutput = dooutput;
    }

这个connected是URLConnection的属性默认为false

 /**
     * If {@code false}, this connection object has not created a
     * communications link to the specified URL. If {@code true},
     * the communications link has been established.
     */
    protected boolean connected = false;

2.明明没有连接为什么执行某一些方法的时候显示已经连接了?

我们测试getContentLength()方法,这个方法是获取相应的长度的。

这里打出长度为117,紧接着就出现了重复连接的问题。结合上面的connected,应该是某一些牵扯到响应参数的时候进行了发送。

在这里插入图片描述

跟踪源码我们发现HttpURLConnection(URLConnection的子类)的getInputStream()getOutputStream()connect(),三个方法都会修改connected的状态造成第重复连接。

getContentLength()的第一句就是调用了getInputStream();

public int getContentLength() {
        try {
            this.getInputStream();
        } catch (Exception var4) {
            return -1;
        }...
}
--------------------------------
    public synchronized InputStream getInputStream() throws IOException {
        this.connecting = true;
    

这也就说明了在使用这几个参数的时候会修改URLConnection的状态。在通过debug深挖下去能看到发送的connect方法。

同时在调用某些方法的时候会检测这个标示为是否为true 如果是就出现我们看到的哪个异常了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值