HTTP规范界说中最常用的请求类型就是Get和Post。当你在浏览器里输入肆意一个网址按回车,浏览器即已经在执行Get请求了;当你回覆了某条微博时,这时可能就执行了一次Post请求。简单的来说,Get就是向处事器发送索取数据的一种请求,不会影响资本的状况;Post是向处事器提交数据的一种请求,可能建树或更新处事器上的资本。
访谒处事器链接时,需要以链接地址为参数机关生成一个java.net.URL实例。URL由收集和谈、主机名、端口、信息路径、引用等组成统一资本定位符,它是指向互联网“资本”的指针。资本可所以简单的文件或目录,也可所以对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
URL的示例轨范代码如下文所示:
在上面的示例URL中,使用的和谈为HTTP超文本传输和谈;主机名为 www.devdiv.com;端口为80,端口值不是必需要求的,当未指定端口号时则使用和谈默认的端口;信息路径为"res/index.html";引用内容则是由"#"指示的"chapter1",暗示在检索到指定的资本后,轨范需要使用文档中附加有"chapter1"的标识表记标帜部门。
生成URL实例后,执行url.openConnection()体例可以获取HttpURLConnection对象。假如URL的和谈属于以下包或其子包之一的公共、专用URLConnection子类:java.lang、java.io、java.util、java.net,则返回的毗连将为该子类的类型。例如,对于HTTP,将返回HttpURLConnection,对于JAR,将返回JarURLConnection。轨范代码如下文所示:
经由过程轨范代码获取的HttpURLConnection默认是进行Get请求,数据只读不提交。要使用Post体例提交数据,应提前设置好各项参数,轨范代码如下文所示:
setDoInput(boolean)参数值为true抉择着当前链接可以进行数据读取,反之则不许可读取操作;setDoOutput(boolean)参数值为true时抉择着当前链接可以进行数据提交工作,反之则不许可。setRequestMethod("POST")将当前HTTP请求体例设置为"POST",并在最后执行setUseCaches(boolean)打消了用户缓存。以上所有的工作都必需在正式建树链接之前进行。
Post体例提交数据,需要用到数据输出流。当执行httpConn.connect()后,即可执行httpConn.getOutputStream()获取数据流从而进行数据写操作,为将数据提交各处事器作筹备。轨范代码如下文所示:
数据是以<Key,Value>形式提交的,为保证数据的切确性,当数据是英文字母、数字时,原样发送;假如是空格则转换为"+",假如涉及到中文或其它字符,则经由过程URLEncoder.encode()进行BASE 64尺度转码,得出"%XX"名目的加工数据,其中"X"为该符号以16进制暗示的ASCII码。
为连结数据的正当,本文所提交的内容虽皆为英文字符,但仍一致使用URLEncoder进行转码。当<Key,Value>数目不止一组时,组与组之间用"&"进行分隔。执行DataOutputStream.write(byte[])可以将所要提交的内容由输出流写入RAM缓冲区中,在封锁输出流之前,执行一次flush()刷新操作,强制将可能未输出的数据实时写入RAM缓冲区。
对于统一个HttpURLConnection实例,只有执行完Post请求后,才许可Get请求进行,否则以Get请求进行的任何动作都将直接导致未执行的Post操作失败。
从处事器上获取数据,同理,需要数据输入流,并轮回读取所稀有据后,方可加工出用户想要获取的信息。轨范代码如下文所示:
读取过程中使用了ByteArrayOutputStream作为字节数据的缓冲流。当InputStream.read()返回值为-1暗示数据已经全数读取完毕后,再将ByteArrayOutputStream中的缓冲数据由baos.toByteArray()一次性生成byte[],并按照一路头由httpConn.getContentEncoding()获取的字符编码类型,将byte[]机关成新的String。最后,所有的输入流、输出流都应该执行close()操作。
在读取数据之前,可以获取当前链接的返回值、返回数据长度等等信息。在纯挚的读取数据中,正常的返回值RespondCode等于HTTP_OK,需要链接跳转的返回值HTTP_MOVED_PERM/ HTTP_MOVED_TEMP,假如访谒资本不存在,则返回值HTTP_NOT_FOUND。轨范代码如下文所示:
以上为完整的Post/Get请求过程。
有时在简单的需求差遣下,处事器开发人员出于便捷性考虑,也会将Post请求体例交由Get请求体例替代实现。以同样需要向处事器发送两组<Key,Value>数据为需求,可以将此两组数据组合到url中,轨范代码如下文所示:
在完整的链接后,以"?"分隔url和传输数据,将<Key,Value>数据用"="组合成字符串后缀。然后依上面介绍的轨范向处事器倡议请求,亦可读取正确的数据。同理,<Key,Value>在使用"="组合成字符串之前,仍需使用URLEncoder进行转码以保证数据的切确性。
对于Post/Get所能发送的<Key,Value>的数据量巨细,HTTP 1.1中并没有具体的限制,在现实运行中与轨范运行情形及处事器部署设置有关。
以上介绍了Post/Get的根基使用体例,由此可看出,因为Post体例将请求的数据放置在HTTP请求的正文内,它的平安性要比Get请求的平安性要高。好比:经由过程Get发送数据,用户名和密码信息都将会呈此刻URL上,在设置了浏览器缓存的情形下会被记实导致泄露。所以在涉及到用户小我隐私的数据时,强烈举荐在将数据加密后使用Post体例提交至处事器。
访谒处事器链接时,需要以链接地址为参数机关生成一个java.net.URL实例。URL由收集和谈、主机名、端口、信息路径、引用等组成统一资本定位符,它是指向互联网“资本”的指针。资本可所以简单的文件或目录,也可所以对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
URL的示例轨范代码如下文所示:
1 | URL url = new URL("http://www.devdiv.com:80/res/index.html#chapter1"); |
在上面的示例URL中,使用的和谈为HTTP超文本传输和谈;主机名为 www.devdiv.com;端口为80,端口值不是必需要求的,当未指定端口号时则使用和谈默认的端口;信息路径为"res/index.html";引用内容则是由"#"指示的"chapter1",暗示在检索到指定的资本后,轨范需要使用文档中附加有"chapter1"的标识表记标帜部门。
生成URL实例后,执行url.openConnection()体例可以获取HttpURLConnection对象。假如URL的和谈属于以下包或其子包之一的公共、专用URLConnection子类:java.lang、java.io、java.util、java.net,则返回的毗连将为该子类的类型。例如,对于HTTP,将返回HttpURLConnection,对于JAR,将返回JarURLConnection。轨范代码如下文所示:
1 | HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); |
经由过程轨范代码获取的HttpURLConnection默认是进行Get请求,数据只读不提交。要使用Post体例提交数据,应提前设置好各项参数,轨范代码如下文所示:
1 | httpConn.setDoInput(true); |
2 | httpConn.setDoOutput(true); |
3 |
4 | // 此体例在正式链接之前设置才有用。 |
5 | httpConn.setRequestMethod("POST"); |
6 | httpConn.setUseCaches(false); |
7 | // 正式建树链接 |
8 | httpConn.connect(); |
setDoInput(boolean)参数值为true抉择着当前链接可以进行数据读取,反之则不许可读取操作;setDoOutput(boolean)参数值为true时抉择着当前链接可以进行数据提交工作,反之则不许可。setRequestMethod("POST")将当前HTTP请求体例设置为"POST",并在最后执行setUseCaches(boolean)打消了用户缓存。以上所有的工作都必需在正式建树链接之前进行。
Post体例提交数据,需要用到数据输出流。当执行httpConn.connect()后,即可执行httpConn.getOutputStream()获取数据流从而进行数据写操作,为将数据提交各处事器作筹备。轨范代码如下文所示:
1 | DataOutputStream dos = new DataOutputStream(httpConn.getOutputStream()); |
2 |
3 | String postContent = URLEncoder.encode("channel", "UTF-8") + "=" + URLEncoder.encode("Devdiv", "UTF-8") + "&" + URLEncoder.encode("author", "UTF-8") + "=" + URLEncoder.encode("Sodino", "UTF-8") ; |
4 |
5 | dos.write(postContent.getBytes()); |
6 | dos.flush(); |
7 | // 执行完dos.close()后,POST请求竣事 |
8 | dos.close(); |
数据是以<Key,Value>形式提交的,为保证数据的切确性,当数据是英文字母、数字时,原样发送;假如是空格则转换为"+",假如涉及到中文或其它字符,则经由过程URLEncoder.encode()进行BASE 64尺度转码,得出"%XX"名目的加工数据,其中"X"为该符号以16进制暗示的ASCII码。
为连结数据的正当,本文所提交的内容虽皆为英文字符,但仍一致使用URLEncoder进行转码。当<Key,Value>数目不止一组时,组与组之间用"&"进行分隔。执行DataOutputStream.write(byte[])可以将所要提交的内容由输出流写入RAM缓冲区中,在封锁输出流之前,执行一次flush()刷新操作,强制将可能未输出的数据实时写入RAM缓冲区。
对于统一个HttpURLConnection实例,只有执行完Post请求后,才许可Get请求进行,否则以Get请求进行的任何动作都将直接导致未执行的Post操作失败。
从处事器上获取数据,同理,需要数据输入流,并轮回读取所稀有据后,方可加工出用户想要获取的信息。轨范代码如下文所示:
01 | // 起头GET数据 |
02 | String encoding = httpConn.getContentEncoding(); |
03 | is = httpConn.getInputStream(); |
04 | int read = -1; |
05 | baos = new ByteArrayOutputStream(); |
06 | while ((read = is.read()) != -1) { |
07 | baos.write(read); |
08 | } |
09 | byte[] data = baos.toByteArray(); |
10 | baos.close(); |
11 |
12 | String content = null; |
13 | if (encoding != null) { |
14 | content = new String(data, encoding); |
15 | } else { |
16 | content = new String(data); |
17 | } |
读取过程中使用了ByteArrayOutputStream作为字节数据的缓冲流。当InputStream.read()返回值为-1暗示数据已经全数读取完毕后,再将ByteArrayOutputStream中的缓冲数据由baos.toByteArray()一次性生成byte[],并按照一路头由httpConn.getContentEncoding()获取的字符编码类型,将byte[]机关成新的String。最后,所有的输入流、输出流都应该执行close()操作。
在读取数据之前,可以获取当前链接的返回值、返回数据长度等等信息。在纯挚的读取数据中,正常的返回值RespondCode等于HTTP_OK,需要链接跳转的返回值HTTP_MOVED_PERM/ HTTP_MOVED_TEMP,假如访谒资本不存在,则返回值HTTP_NOT_FOUND。轨范代码如下文所示:
01 | // 获取轨范代码返回值 |
02 | int respondCode = httpConn.getResponseCode() |
03 | // 获取返回内容类型 |
04 | String type = httpConn.getContentType(); |
05 | // 获取返回内容的字符编码 |
06 | String encoding = httpConn.getContentEncoding(); |
07 | // 获取返回内容长度,单元字节 |
08 | int length = httpConn.getContentLength(); |
09 | // 获取头信息的Key |
10 | String key = httpConn.getHeaderField(idx); |
11 | // 获取完整的头信息Map |
12 | Map<String, List<String>> map = httpConn.getHeaderFields(); |
以上为完整的Post/Get请求过程。
有时在简单的需求差遣下,处事器开发人员出于便捷性考虑,也会将Post请求体例交由Get请求体例替代实现。以同样需要向处事器发送两组<Key,Value>数据为需求,可以将此两组数据组合到url中,轨范代码如下文所示:
1 | URL url = new URL("http://www.devdiv.com:80/res/index.html?channel=Devdiv&author=sodino"); |
在完整的链接后,以"?"分隔url和传输数据,将<Key,Value>数据用"="组合成字符串后缀。然后依上面介绍的轨范向处事器倡议请求,亦可读取正确的数据。同理,<Key,Value>在使用"="组合成字符串之前,仍需使用URLEncoder进行转码以保证数据的切确性。
对于Post/Get所能发送的<Key,Value>的数据量巨细,HTTP 1.1中并没有具体的限制,在现实运行中与轨范运行情形及处事器部署设置有关。
以上介绍了Post/Get的根基使用体例,由此可看出,因为Post体例将请求的数据放置在HTTP请求的正文内,它的平安性要比Get请求的平安性要高。好比:经由过程Get发送数据,用户名和密码信息都将会呈此刻URL上,在设置了浏览器缓存的情形下会被记实导致泄露。所以在涉及到用户小我隐私的数据时,强烈举荐在将数据加密后使用Post体例提交至处事器。