大家好,我是烤鸭:
记一次 由 HttpsURLConnection 引起的返回值400的错误。

1.   场景复现


今天线上调用第三方接口的时候突然报错了。
严格来说也不是报错,就是发的请求不通了,http报400的错误。
问了下对接方,也没有改代码,我们这边也没什么大的改动。
奇了怪了。。。
这是请求原来的代码

HttpsURLConnection conn = (HttpsURLConnection) reqURL.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Accept", "*/*");
conn.setRequestProperty("User-Agent", "stargate");
conn.setRequestProperty("Content-Type", "application/json");
OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
osw.write(reqStr);
osw.flush();
osw.close();

这是改动的地方,加了句log。

OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
log.info("【返回值】"+conn.getResponseCode());
osw.write(reqStr);
osw.flush();
osw.close();

2.    寻找问题


把改动的地方逐步还原,最后发现是log的问题。
log是没有问题,问题在于 conn.getResponseCode()
conn.getOutputStream() 获取连接的输出流,准备向对方发送(写入)数据的时候,
调用 conn.getResponseCode() 报错。为什么呢。一步步看。

getInputStream方法中调用的是getInputStream0()。

public synchronized InputStream getInputStream() throws IOException {
        this.connecting = true;
        SocketPermission var1 = this.URLtoSocketPermission(this.url);
        if (var1 != null) {
            try {
                return (InputStream)AccessController.doPrivilegedWithCombiner(new PrivilegedExceptionAction<InputStream>() {
                    public InputStream run() throws IOException {
                        return HttpURLConnection.this.getInputStream0();
                }, (AccessControlContext)null, var1);
            } catch (PrivilegedActionException var3) {
                throw (IOException)var3.getException();
        } else {
            return this.getInputStream0();

   getInputStream0方法中 

    
    if setDoInput(true)
    if else 抛出rememberedException异常
    if else 输入流不为空
    else 输出的方式是否是流的形式
    往对应的服务器写一段文字,主要调用的是这个方法

    writeRequests,看是否正常响应,响应后关闭流。
    看到这大概就明白了。

3.    总结


    调用 conn.getOutputStream() 获取连接的输出流,等待内容写入。(连接是阻塞的,BIO)
    此时调用 conn.getResponseCode() 会向服务器写入其他的东西(一个8192byte的字符串),
    写入完成后,flush 再close。这时对接方的服务器发现获取到的东西并不是指定格式传输的内容,
    就报400了。

    关于400的说明—— HTTP 400 错误 - 请求无效 (Bad request);出现这个请求无效报错说明请求没有进入到后台服务里

    https://www.cnblogs.com/beppezhang/p/5824986.html
    不能忽略每一次小的改动。一句小小的log都可能导致问题,还有就是要多测试。

大家好,我是烤鸭:    记一次 由 HttpsURLConnection 引起的返回值400的错误。1.   场景复现     今天线上调用第三方接口的时候突然报错了。     严格来说也不是报错,就是发的请求不通了,http报400的错误。     问了下对接方,也没有改代码,我们这边也没什么大的改动。     奇了怪了。。。     这是请求原来的代码HttpsUR...
400 一般是前端代码的问题 找不到相应的网页 405 一般是前端请求的方式和后端接受请求的方式不一致。比如说springmvc项目中前端用get方式发起请求,后端Controller层用post方式来获取请求,就会报405错误 500 项目中java代码错误 200(OK):请求成功。一般用于GET与POST请求 更多详细的响应码见如下博客: https://blog.csdn.net/ddhsea/article/details/79405996
我们在日常上网找学习资料的时候,打开网页就会发现一些没有打开的网页显示着404这样显眼的数字,表明我们像浏览的网页内容浏览不到,被迫无奈就只能是找别的学习资料,今天就让大家记住一些常见的这种数字的表达含义,下次我们再撞见的时候就知道是因为什么原因学习资料找不到了。(当然,只能知道原因不能解决 )😃 2xx:成功状态码 3xx:重定向状态码 4xx(客户端错误状态码) 5xx(服务器错误状态码) 了解这些东西,回家和朋友寻找学习资料的时候看见了也是能小装一手13的。1、客户端发起HTTPS请求
问题: 在请求接口时报了400错误, 400错误是请求时传过去的数据参数或者格式发生错误导致的.传递过去的是一种类似数组结构的数据.后台需要通过特殊的编码方式才能解析。 1.解决: 请求接口传值的时候,通过encodeURLComponent函数将需要传过去的值进行编码.可把字符串作为 URI 组件进行编码. let arr = [{}, {}] encodeURLComponent(arr)
private static InputStream getInputStream(String filePath) { int HttpResult; // 服务器返回的状态 InputStream inputStream = null; //处理url空格 if(filePath.contains(" ")) filePath= filePath.replace("
java httpUrlConnection 调用远程接口报400 1.问题的出现: 线下开发时候使用httpUrlConnction测试调用远程接口一点问题都没有,但是打包后放到线上去后出现400的错误同样的参数在线下可以调试,放在线上就不行了。 一般报400说明接口接收到了错误的参数,由于是远程调用别人的服务器接口看不到那边的日志,我们这边只有一个400 ,信息提示说对面jso...
通过url链接获取文件流报400错误 在实际开发过程中,我遇到一个同一份代码,在本地测试和线上测试出现不同结果问题。其问题定位找到是因为通过HttpUrlConnection获取url文件流报错400。 通过在网上查找该方法报错400的解决办法,根据网上所说有的是因为url里包含空格,需要转换成%20 if(urlPath.contains(" ")){ urlPath = urlPath.replace(" ","%20"); 但是,我通过这种方式设置还是一样未解决问题。还有很多人说设置UR