首先,这个需要一点HTTP基础,可以先看个书了解下,我看的《http权威指南》的前4章,后面道行不够看不下去。
然后我们的是java.net的接口:
几个类的API:
package com.http; import java.net.URI; import java.net.URISyntaxException; /** * Created by zhen on 2017-06-25. * 表示一个统一标志符(URI)引用 */ public class URITest { /** public final class URI extends Objectimplements Comparable<URI>, Serializable 最高级别上,字符串形式的URI引用:[scheme:]scheme-specific-part[#fragment] 不透明的URI为绝对URI,其方案部分不是以"/"开始。不透明URI无法进行进一步解析。如: mailto:java-net@java.sun.com 分成URI以"/"开始,如: http://java.sun.com/j2se/1.3 分层URI还要按照下面的语法进行下一步的解析: [scheme:][//authority][path][?query][#fragment] 针对URI实例的运算: 规范化、解析、相对化运算。 规范化 是将分层URI路径组成中的不必要的"."和“..”移除的过程。每个“.”部分将被移除。".."部分也被移除,除非它前面有一个非".."部分 解析 是根据另一个基于URI解析某个URI的过程。例如docs/guide/collections/designfaq.html根据基本URI http://java.sun.com/j2se/1.3 解析结果为URI: http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html 相对化 是解析的逆过程:对于任何两个规范的URI u和v,u.relativize(u.resolve(v)).equals(v)和u.resolve(u.relativize(v)).equals(v) 标识 对于任何URI u,下面的标识有效: new URI(u.toString()).equals(u) 对于不包含冗余语法的任何URI u,比如在一个空授权前面有两根斜线(如:file///tmp/)和主机名后面跟这一个冒号但没有端口 (如:http://java.sun.com),以及除必须引用的字符之外不对字符编码的情况下,下面标识也有效: new URI(u.getScheme()、 u.getSchemeSpecificPart()、 u.getFragment()) .equals(u) 在所有情况下,以下标识有效 new URI(u.getScheme()、 u.getUserInfo()、 u.getAuthority()、 u.getPath()、 u.getQuery()、 u.getFragment()) .equals(u) 如果 u 为分层的,则以下标识有效 new URI(u.getScheme()、 u.getUserInfo()、 u.getHost()、 u.getPort()、 u.getPath()、 u.getQuery()、 u.getFragment()) .equals(u) 方法: 静态方法: static URI create(String str) 通过解析给定的字符串创建 URI。 构造: URI(String str) URI(String scheme, String ssp, String fragment) URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment) URI(String scheme, String host, String path, String fragment) URI(String scheme, String authority, String path, String query, String fragment) 其他方法: int compareTo(URI that) 将此 URI 与另一个对象(也必须是 URI)进行比较。 boolean equals(Object ob) 测试此 URI 与另一对象的相等性。 String getAuthority() 返回此 URI 的已解码的授权组成部分。 String getFragment() 返回此 URI 的已解码的片段组成部分。 String getHost() 返回此 URI 的主机组成部分。 String getPath() 返回此 URI 的已解码的路径组成部分。 int getPort() 返回此 URI 的端口号。 String getQuery() 返回此 URI 的已解码的查询组成部分。 String getRawAuthority() 返回此 URI 的原始授权组成部分。 String getRawFragment() 返回此 URI 的原始片段组成部分。 String getRawPath() 返回此 URI 的原始路径组成部分。 String getRawQuery() 返回此 URI 的原始查询组成部分。 String getRawSchemeSpecificPart() 返回此 URI 原始的、特定于方案的部分。 String getRawUserInfo() 返回此 URI 的原始用户信息组成部分。 String getScheme() 返回此 URI 的方案组成部分。 String getSchemeSpecificPart() 返回此 URI 的特定于方案的解码部分。 String getUserInfo() 返回此 URI 的已解码的用户信息组成部分。 int hashCode() 返回此 URI 的哈希码值。 boolean isAbsolute() 判断此 URI 是否为绝对的。 boolean isOpaque() 判断此 URI 是否为不透明的。 URI parseServerAuthority() 尝试将此 URI 的授权组成部分(如果已定义)解析为用户信息、主机和端口组成部分。 String toASCIIString() 以 US-ASCII 字符串形式返回此 URI 的内容。 String toString() 以字符串形式返回此 URI 的内容。 URL toURL() 根据此 URI 构造一个 URL。 规范化、相对化、解析: URI normalize() 规范化此 URI 的路径。 URI relativize(URI uri) 根据此 URI 将给定 URI 相对化。 URI resolve(String str) 解析给定的字符串,然后在此 URI 的基础上构造一个新的 URI。 URI resolve(URI uri) 根据此 URI 解析给定的 URI。 */ public static void main(String[] args){ // try{ // URI uri = new URI("http://www.baidu.com"); // URI uri = new URI("https", "www.baidu.com", null); // URI uri = new URI("http", "guozhen", "www.baidu.com", 80, "/index.html", "id=2", null); // URI uri = new URI("http", "127.0.0.1", "/index.html",null); // URI uri = URI.create("http://127.0.0.1:2001"); // System.out.println(uri.toString()); // }catch(URISyntaxException ex){ // ex.printStackTrace(); // } // System.out.println("规范化: " + uri.normalize().toString()); // System.out.println("相对化http://127.0.0.1:2001/book/query?id=12: " + uri.relativize(URI.create("http://127.0.0.1:2001/book/query?id=12"))); // System.out.println("解析/book/query?id=12: " + uri.resolve("/book/query?id=12")); URI uri = URI.create("http://127.0.0.1:2001/book/query?id=12"); System.out.println("方案: " + uri.getScheme()); System.out.println("主机: " + uri.getHost()); System.out.println("端口: " + uri.getPort()); System.out.println("路径: " + uri.getPath()); System.out.println("查询: " + uri.getQuery()); } } package com.http; /** * Created by zhen on 2017-06-25. * 类 URL 代表一个统一资源定位符 */ public class URLTest { /** URL类本身并不会根据RFC2396中定义的转义机制编码或者解码任何URL部分。由调用方对任何需要调用URL前进行转义的字段进行编码,并对从URL返回的任何经过转义的字段进行解码。 例如,针对这两个URL,被视为互不相等: http://foo.com/hello world/ 和 http://foo.com/hello%20world 注意,URI 类在某些特定情况下对其组成字段执行转义。建议使用 URI 管理 URL 的编码和解码,并使用 toURI() 和 URI.toURL() 实现这两个类之间的转换。 也可以使用 URLEncoder 和 URLDecoder 类,但是只适用于 HTML 形式的编码,它与 RFC2396 中定义的编码机制不同。 方法: 构造: URL(String spec) URL(String protocol, String host, int port, String file) URL(String protocol, String host, int port, String file, URLStreamHandler handler) URL(String protocol, String host, String file) URL(URL context, String spec) URL(URL context, String spec, URLStreamHandler handler) 获取URLConnection和流: URLConnection openConnection() 返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。 URLConnection openConnection(Proxy proxy) 与 openConnection() 类似,所不同是连接通过指定的代理建立;不支持代理方式的协议处理程序将忽略该代理参数并建立正常的连接。 InputStream openStream() 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。 其他方法: boolean equals(Object obj) 比较此 URL 是否等于另一个对象。 String getAuthority() 获取此 URL 的授权部分。 Object getContent() 获取此 URL 的内容。 Object getContent(Class[] classes) 获取此 URL 的内容。 int getDefaultPort() 获取与此 URL 关联协议的默认端口号。 String getFile() 获取此 URL 的文件名。 String getHost() 获取此 URL 的主机名(如果适用)。 String getPath() 获取此 URL 的路径部分。 int getPort() 获取此 URL 的端口号。 String getProtocol() 获取此 URL 的协议名称。 String getQuery() 获取此 URL 的查询部分。 String getRef() 获取此 URL 的锚点(也称为“引用”)。 String getUserInfo() 获取此 URL 的 userInfo 部分。 int hashCode() 创建一个适合哈希表索引的整数。 boolean sameFile(URL other) 比较两个 URL,不包括片段部分。 protected void set(String protocol, String host, int port, String file, String ref) 设置 URL 的字段。 protected void set(String protocol, String host, int port, String authority, String userInfo, String path, String query, String ref) 设置 URL 的指定的 8 个字段。 static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) 设置应用程序的 URLStreamHandlerFactory。 String toExternalForm() 构造此 URL 的字符串表示形式。 String toString() 构造此 URL 的字符串表示形式。 URI toURI() 返回与此 URL 等效的 URI。 */ } package com.http; /** * Created by zhen on 2017-06-25. * 抽象类URLConnection是所有类的超类,它代表应用程序和URL之间的通信链接。此类的实体可用于读取和写入此URL引用的资源。 * 通常,创建一个到URL的连接需要几个步骤: * 1、通过在URL上调用openConnection方法创建连接对象 * 2、处理设置参数和一般请求属性 * 3、使用connect方法建立到远程对象的实际连接 * 4、远程对象变为可用。远程对象的头字段和内容变为可访问。 * 使用以下方法修改设置参数: * 1、setAllowUserInteraction * 2、setDoInput * 3、setDoOutput * 4、setIfModifiedSince * 5、setUseCaches * 使用以下方法修改一般属性: * setRequestProperty * 使用setDefaultAllowUserInteraction和setDefaultUseCache可设置AllowUserInteraction和UseCache参数的默认值 * 上面每个set方法都有一个用于获取参数值或一般请求属性值的对应get方法。适用的具体参数和一般请求属性取决于协议。 * 在建立到远程对象的连接之后,以下方法用于访问头字段和内容: * getContent * getHeaderField * getInputStream * getOutputStream * 一些头字段需要经常访问。以下方法: * getContentEncoding * getContentLength * getContentType * getDate * getExpiraction * getLastModifed * 提供这些对象的便捷访问。getContent方法适用getContentType方法以确定远程对象类型。子类重写getContentType方法很容易 * 一般情况下,所有的预连接参数和一般请求属性都可忽略:预连接参数和一般请求属性默认为敏感词。对于此接口的大多数客户端而言,只有两个需要的方法:getInputStream和getContent,它们通过便捷方法镜像到URL类中。 * 有关fileNameMap的注意事项:在JDK1.6以前的版本中,URLConnection的fileNameMap字段是公共的。在JDK1.1.6以及后面的版本中,fileNameMap字段是私有的;对其添加了accessor方法和mutaor方法getFieldNameMap以及 * setFieldNameMap以便访问。完成请求后,在一个URLConnection的InputStream或OutputStream上调用close()方法可以释放与此实例相关的网络资源,除非特定的协议规范为其制定了其他行为。 字段: protected boolean allowUserInteraction 如果为 true,则在允许用户交互(例如弹出一个验证对话框)的上下文中对此 URL 进行检查。 protected boolean connected 如果为 false,则此连接对象尚未创建到指定 URL 的通信链接。 protected boolean doInput 此变量由 setDoInput 方法设置。 protected boolean doOutput 此变量由 setDoOutput 方法设置。 protected long ifModifiedSince 有些协议支持跳过对象获取,除非该对象在某个特定时间点之后又进行了修改。 protected URL url URL 表示此连接要在互联网上打开的远程对象。 protected boolean useCaches 如果为 true,则只要有条件就允许协议使用缓存。 构造: protected URLConnection(URL url) 构造一个到指定 URL 的 URL 连接。 方法: void addRequestProperty(String key, String value) 添加由键值对指定的一般请求属性。 abstract void connect() 打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)。 boolean getAllowUserInteraction() 返回此对象的 allowUserInteraction 字段的值。 int getConnectTimeout() 返回连接超时设置。 Object getContent() 获取此 URL 连接的内容。 Object getContent(Class[] classes) 获取此 URL 连接的内容。 String getContentEncoding() 返回 content-encoding 头字段的值。 int getContentLength() 返回 content-length 头字段的值。 String getContentType() 返回 content-type 头字段的值。 long getDate() 返回 date 头字段的值。 static boolean getDefaultAllowUserInteraction() 返回 allowUserInteraction 字段的默认值。 static String getDefaultRequestProperty(String key) 已过时。 应在获得 URLConnection 的适当实例后使用特定 getRequestProperty 方法的实例。 boolean getDefaultUseCaches() 返回 URLConnection 的 useCaches 标志的默认值。 boolean getDoInput() 返回此 URLConnection 的 doInput 标志的值。 boolean getDoOutput() 返回此 URLConnection 的 doOutput 标志的值。 long getExpiration() 返回 expires 头字段的值。 static FileNameMap getFileNameMap() 从数据文件加载文件名映射(一个 mimetable)。 String getHeaderField(int n) 返回第 n 个头字段的值。 String getHeaderField(String name) 返回指定的头字段的值。 long getHeaderFieldDate(String name, long Default) 返回解析为日期的指定字段的值。 int getHeaderFieldInt(String name, int Default) 返回解析为数字的指定字段的值。 String getHeaderFieldKey(int n) 返回第 n 个头字段的键。 Map<String,List<String>> getHeaderFields() 返回头字段的不可修改的 Map。 long getIfModifiedSince() 返回此对象的 ifModifiedSince 字段的值。 InputStream getInputStream() 返回从此打开的连接读取的输入流。 long getLastModified() 返回 last-modified 头字段的值。 OutputStream getOutputStream() 返回写入到此连接的输出流。 Permission getPermission() 返回一个权限对象,其代表建立此对象表示的连接所需的权限。 int getReadTimeout() 返回读入超时设置。 Map<String,List<String>> getRequestProperties() 返回一个由此连接的一般请求属性构成的不可修改的 Map。 String getRequestProperty(String key) 返回此连接指定的一般请求属性值。 URL getURL() 返回此 URLConnection 的 URL 字段的值。 boolean getUseCaches() 返回此 URLConnection 的 useCaches 字段的值。 static String guessContentTypeFromName(String fname) 根据 URL 的指定 "file" 部分尝试确定对象的内容类型。 static String guessContentTypeFromStream(InputStream is) 根据输入流的开始字符尝试确定输入流的类型。 void setAllowUserInteraction(boolean allowuserinteraction) 设置此 URLConnection 的 allowUserInteraction 字段的值。 void setConnectTimeout(int timeout) 设置一个指定的超时值(以毫秒为单位),该值将在打开到此 URLConnection 引用的资源的通信链接时使用。 static void setContentHandlerFactory(ContentHandlerFactory fac) 设置应用程序的 ContentHandlerFactory。 static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction) 将未来的所有 URLConnection 对象的 allowUserInteraction 字段的默认值设置为指定的值。 static void setDefaultRequestProperty(String key, String value) 已过时。 应在获得 URLConnection 的适当实例后使用特定 setRequestProperty 方法的实例。调用此方法没有任何作用。 void setDefaultUseCaches(boolean defaultusecaches) 将 useCaches 字段的默认值设置为指定的值。 void setDoInput(boolean doinput) 将此 URLConnection 的 doInput 字段的值设置为指定的值。 void setDoOutput(boolean dooutput) 将此 URLConnection 的 doOutput 字段的值设置为指定的值。 static void setFileNameMap(FileNameMap map) 设置 FileNameMap。 void setIfModifiedSince(long ifmodifiedsince) 将此 URLConnection 的 ifModifiedSince 字段的值设置为指定的值。 void setReadTimeout(int timeout) 将读超时设置为指定的超时值,以毫秒为单位。 void setRequestProperty(String key, String value) 设置一般请求属性。 void setUseCaches(boolean usecaches) 将此 URLConnection 的 useCaches 字段的值设置为指定的值。 String toString() 返回此 URL 连接的 String 表示形式。 */ public class URLConnectionTest { }
ok,现在开始学习使用发送请求了,这个我主要是敲了一遍这位大哥的代码:
http://www.cnblogs.com/nick-huang/p/3859353.html
代码贴出来:
package com.http; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; /** * Created by zhen on 2017-06-26. */ public class TestHttp { public static void main(String[] args){ String result = null; try { // result = doGet(); result = doPost(); } catch (Exception e) { e.printStackTrace(); } System.out.println(result); } public static String doGet() throws Exception{ URL localUrl = new URL("http://localhost:8080/"); URLConnection connection = localUrl.openConnection(); HttpURLConnection httpURLConnection = (HttpURLConnection) connection; httpURLConnection.setRequestProperty("Accept-Charset", "UTF-8"); httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader reader = null; StringBuffer resultBuffer = new StringBuffer(); String tempLine = null; if(httpURLConnection.getResponseCode() >=300){ throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode()); } try{ inputStream = httpURLConnection.getInputStream(); inputStreamReader = new InputStreamReader(inputStream); reader = new BufferedReader(inputStreamReader); while((tempLine = reader.readLine()) != null){ resultBuffer.append(tempLine); } }finally { if(reader != null){ reader.close(); } if(inputStreamReader != null){ inputStreamReader.close(); } if(inputStream != null){ inputStream.close(); } } return resultBuffer.toString(); } public static String doPost() throws Exception{ String parameterData = "username=nicekuangg&blog=http://www.cnblogs.com/nick-kuang/"; URL localUrl = new URL("http://localhost:8080/loginServlet"); URLConnection connection = localUrl.openConnection(); HttpURLConnection httpURLConnection = (HttpURLConnection) connection; httpURLConnection.setDoOutput(true); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setRequestProperty("Accept-Charset", "UTF-8"); httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); httpURLConnection.setRequestProperty("Content-Length", String.valueOf(parameterData.length())); OutputStream outputStream = null; OutputStreamWriter outputStreamWriter = null; InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader reader = null; StringBuffer resultBuffer = new StringBuffer(); String tempLine = null; try{ outputStream = httpURLConnection.getOutputStream(); outputStreamWriter = new OutputStreamWriter(outputStream); outputStreamWriter.write(parameterData.toString()); outputStreamWriter.flush(); if(httpURLConnection.getResponseCode() >=300){ throw new Exception("HTTP Response is not sucess, Response code is " + httpURLConnection.getResponseCode()); } inputStream = httpURLConnection.getInputStream(); inputStreamReader = new InputStreamReader(inputStream); reader = new BufferedReader(inputStreamReader); while((tempLine = reader.readLine()) != null){ resultBuffer.append(tempLine); } }finally{ if(outputStreamWriter != null){ outputStreamWriter.close(); } if(outputStream != null){ outputStream.close(); } if(reader != null){ reader .close(); } if(inputStreamReader != null){ inputStreamReader.close(); } if(inputStream != null){ inputStream.close(); } } return resultBuffer.toString(); } }
package com.http; import java.io.*; import java.net.*; import java.util.Map; /** * Created by zhen on 2017-06-26. */ public class HttpRequestor { private String charset = "UTF-8"; private Integer connectionTimeout = null; private Integer socketTimeout = null; private String proxyHost = null; private Integer proxyPort = null; public String doGet(String url) throws Exception{ URL localUrl = new URL(url); URLConnection connection = openConnection(localUrl); HttpURLConnection httpURLConnection = (HttpURLConnection) connection; httpURLConnection.setRequestProperty("Accept-Charset", charset); httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader reader = null; StringBuffer resultBuffer = new StringBuffer(); String tempLine = null; if(httpURLConnection.getResponseCode() >= 300){ throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode()); } try{ inputStream = httpURLConnection.getInputStream(); inputStreamReader = new InputStreamReader(inputStream); reader = new BufferedReader(inputStreamReader); while((tempLine = reader.readLine()) != null){ resultBuffer.append(tempLine); } }finally{ if(reader != null){ reader.close(); } if(inputStreamReader != null){ inputStreamReader.close(); } if(inputStream != null){ inputStream.close(); } } return resultBuffer.toString(); } public String doPost(String url, Map parameterMap) throws Exception{ StringBuffer parameterData = new StringBuffer(); if(parameterMap != null){ for(Object key : parameterMap.keySet()){ parameterData = parameterData.append(key).append("=").append(parameterMap.get(key)).append("&"); } parameterData = parameterData.deleteCharAt(parameterData.length() - 1); } URL localUrl = new URL(url); URLConnection connection = openConnection(localUrl); HttpURLConnection httpURLConnection = (HttpURLConnection) connection; renderRequest(httpURLConnection); httpURLConnection.setDoOutput(true); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setRequestProperty("Accept-Charset", "UTF-8"); httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); httpURLConnection.setRequestProperty("Content-Length", String.valueOf(parameterData.length())); OutputStream outputStream = null; OutputStreamWriter outputStreamWriter = null; InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader reader = null; StringBuffer resultBuffer = new StringBuffer(); String tempLine = null; try{ outputStream = httpURLConnection.getOutputStream(); outputStreamWriter = new OutputStreamWriter(outputStream); outputStreamWriter.write(parameterData.toString()); outputStreamWriter.flush(); inputStream = httpURLConnection.getInputStream(); inputStreamReader = new InputStreamReader(inputStream); reader = new BufferedReader(inputStreamReader); while((tempLine = reader.readLine()) != null){ resultBuffer.append(tempLine); } }finally{ if(outputStreamWriter != null){ outputStreamWriter.close(); } if(outputStream != null){ outputStream.close(); } if(reader != null){ reader.close(); } if(inputStreamReader != null){ inputStreamReader.close(); } if(inputStream != null){ inputStream.close(); } } return resultBuffer.toString(); } private URLConnection openConnection(URL localUrl) throws IOException{ URLConnection connection; if(proxyHost != null && proxyPort != null){ Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)); connection = localUrl.openConnection(proxy); }else{ connection = localUrl.openConnection(); } return connection; } private void renderRequest(URLConnection connection){ if(connectionTimeout != null){ connection.setConnectTimeout(connectionTimeout); } if(socketTimeout != null){ connection.setReadTimeout(socketTimeout); } } public String getCharset() { return charset; } public void setCharset(String charset) { this.charset = charset; } public Integer getConnectionTimeout() { return connectionTimeout; } public void setConnectionTimeout(Integer connectionTimeout) { this.connectionTimeout = connectionTimeout; } public Integer getSocketTimeout() { return socketTimeout; } public void setSocketTimeout(Integer socketTimeout) { this.socketTimeout = socketTimeout; } public String getProxyHost() { return proxyHost; } public void setProxyHost(String proxyHost) { this.proxyHost = proxyHost; } public Integer getProxyPort() { return proxyPort; } public void setProxyPort(Integer proxyPort) { this.proxyPort = proxyPort; } } package com.http; import java.util.HashMap; import java.util.Map; /** * Created by zhen on 2017-06-26. */ public class HttpRequestorTest { public static void main(String[] args){ HttpRequestor httpRequestor = new HttpRequestor(); String doGetResult = null; String doPostResult = null; Map parameterMap = new HashMap<String, String>(); parameterMap.put("username", "nicekuang"); parameterMap.put("blog", "http://www.cnblogs.com/nice-kuang/"); try { doGetResult = httpRequestor.doGet("http://localhost:8080/loginServlet"); doPostResult = httpRequestor.doPost("http://localhost:8080/loginServlet", parameterMap); } catch (Exception e) { e.printStackTrace(); } System.out.println(doGetResult); System.out.println(doPostResult); } }