HttpURLConnection是Java提供用于支持HTTP协议的网络访问,用它访问一个URL的内容很方便。但是最近遇到一个问题,就是用它发送POST请求的时候总是返回502错误:Bad Gateway;但是同样的代码,同样的IDE,同样的JDK,同样的系统环境,用Apache的开源HttpClient发出同样的POST请求却是正常返回200;更诡异的是使用JDK1.6.0-14版本一切正常,返回200,但用JDK1.6.0-20/24的时候却返回了502。起初怀疑JDK出了bug,不过后来事实证明,只要你怀疑一个大的系统出了问题的时候,十有八九问题都是出在自身,只有很少的概率才出现那种状况。
除了怀疑JDK的问题以外,还觉得是HttpURLConnection类使用不当。Google了好久,现在整理一个HttpURLConnection的使用方法如下:
对于http的POST和PUT请求,发出HTTP请求应该遵循的步骤:
- 生成HttpURLConnection实例,并设置http请求参数或者属性;
- 调用getOutputStream方法获得OutputStream并且输出数据到输出流。不管你有没有数据需要发送到服务器端,至少你要调用一下getOutputStream()方法之后忽略数据的写入;
- 调用getInputStream方法发出真实的http请求,并且等待服务器的响应。不管你需不需要服务器的反馈,这个必须调用。
对于http的除了POST和PUT的其他请求(如GET,HEAD,DELETE,TRACE,OPTIONS),发出HTTP请求应该遵循的步骤:
- 生成HttpURLConnection实例,并设置http请求参数或者属性;
- 调用getInputStream方法发出真实的http请求,并且等待服务器的响应。
我们不能假定调用getOutputStream()获得OutputStream,写入数据,然后调用输出流的flush()/close()方法就把真实的http请求发送到服务器端了。事实上,调用HttpURLConnection的getInputStream()方法是唯一的发出真实请求的方法,而调用getOutputStream()方法并没有发送真实的Http请求。
除此之外,使用HttpURLConnection的时候一定要根据请求的类型(POST,GET等)去遵循上面描述的执行顺序,比如说你已经调用共getInputStream()方法了,你在调用getOutputStream()方法的时候就抛异常了,HttpURLConnection说这是不合法的。
我遇到的诡异的问题就是发出POST请求的时候没有调用getOutputStream()方法,省略了POST/PUT请求执行顺序中的第2步导致的。同样的,如果在GET请求中调用的getOutputStream(),JDK的代码显示这个请求就自动变成POST请求了,为了向后兼容的原因也不告诉你,不抛异常。而非POST或PUT请求则直接抛异常了。从代码中也可以看出使用POST或者PUT,或者在GET请求中调用getOutputStream()是一定要设置setDOOutput(true);
- public synchronized OutputStream getOutputStream() throws IOException {
- if (!doOutput) {
- throw new ProtocolException(
- "cannot write to a URLConnection" + " if doOutput=false - call setDoOutput(true)");
- }
- if (method.equals("GET")) {
- method = "POST"; // Backward compatibility
- }
- if (!"POST".equals(method) && !"PUT".equals(method) && "http".equals(url.getProtocol())) {
- throw new ProtocolException("HTTP method " + method
- + " doesn't support output");
- }
- }
- //.......
- }
这时候我们可以看出Java那些个以提高可读性为目的的冗长的方法名,变量名这时候变成了一种误导。还有一个问题就是JDK 1.6.0不同版本之间的行为不一致的问题,原因还是未知。
相关推荐
Java网络编程主要涉及以下几个方面的内容: 网络基础知识:了解网络通信的基本原理,包括IP地址、端口号、协议等。 Socket编程:Socket是Java中实现网络通信的基础类。通过Socket类,可以实现基于TCP和UDP协议的网络...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
Java网络编程是指使用Java编程语言进行网络通信和相关操作的技术。通过Java的网络编程能力,开发人员可以创建客户端-服务器应用程序、实现数据传输、远程调用等功能。 Java的网络编程通常涉及以下几个方面: ...
java网络及通信、httpClient、socket通信、HttpURLConnection、java 中常用的几种网络通信方式。在此总结、希望对需要的同仁有所帮助。
CUrl类是以命令行工具CUrl为参考,使用标准Java的HttpURLConnection实现的Http工具类
网页抓取:使用Java的网络编程库(如HttpURLConnection、Apache HttpClient等)来发送HTTP请求,获取网页的HTML内容。 网页解析:利用Java的HTML解析库(如Jsoup、HtmlCleaner等)来解析网页的HTML结构,提取出所需...
Android 网络编程方法,掌握数据解析方法。 【实验要求】 1、 练习使用 HttpClient 建立网络连接,访问网络数据 2、 练习 XML 数据解析方法 3、 完成实验报告 二、实验内容 1、 电脑连接网络; 2、 新建 Android 应用...