文章目录
什么是URL
URL(Uniform Resource Locator)中文名为统一资源定位符,有时也被俗称为网页地址。表示为互联网上的资源,如网页或者FTP地址。
URL语法
protocol://host:port/path?query#fragment
protocol(协议)位置处可以是 HTTP、HTTPS、FTP 和 File,port 为端口号,path为文件路径及文件名
解析
- http://www.baidu.com/index.html?language=cn#j2se
协议为(protocol):http
主机为(host):www.runoob.com
端口号为(port): 80 ,以上URL实例并未指定端口,因为 HTTP 协议默认的端口号为 80。
文件路径为(path):/index.html
请求参数(query):language=cn
定位位置(fragment):j2se,定位到网页中 id 属性为 j2se 的 HTML 元素位置 。
URL类
构造方法
- 在
java.net包中定义了URL类用来处理URL
| 方法 | 说明 |
|---|---|
| public URL(String protocol, String host, int port, String file) | 通过指定(协议、主机名、端口号、文件名)创建URL 对象 |
| public URL(String protocol, String host, String file) | 通过指定(协议、主机名、文件名)创建URL对象,端口使用协议的默认端口 |
| public URL(String url) | 通过指定的URL地址创建URL对象 |
| public URL(URL context, String url) | 使用基本路径URL对象和相对URL地址创建URL对象 |
常用方法
- URL类中下有很多用于
访问URL的各个部分
| 方法 | 说明 |
|---|---|
| public String getPath() | 返回URL路径部分 |
| public String getQuery() | 返回URL查询部分 |
| public String getAuthority() | 获取此 URL 的授权部分 |
| public int getPort() | 返回URL端口部分 |
| public int getDefaultPort() | 返回协议的默认端口号 |
| public String getProtocol() | 返回URL的协议 |
| public String getHost() | 返回URL的主机 |
| public String getFile() | 返回URL文件名部分 |
| public String getRef() | 获取此 URL 的锚点(也称为"引用") |
| public URLConnection openConnection() | 打开一个URL连接,并运行客户端访问资源。例如:1.如果连接的是HTTP协议的URL, openConnection() 方法返回 HttpURLConnection 对象。2.如果连接的URL为 JAR 文件, openConnection() 方法将返回 JarURLConnection 对象。 |
| public final InputStream openStream() | 获取当前URL请求的响应流 |
@Test
public void testUrl() {
//描述: URL(Uniform Resource Locator)中文名为统一资源定位符,有时也被俗称为网页地址。表示为互联网上的资源,如网页或者FTP地址。
//语法: protocol://host:port/path?query#fragment
//protocol(协议)可以是 HTTP、HTTPS、FTP 和 File,port 为端口号,path为文件路径及文件名。
try {
URL url = new URL("http://www.baidu.com/index.html?language=cn#j2se");//必须用完整的域名(例,http://www.baidu.com/),不能(例,www.baidu.com/)这样会报错!
System.out.println("URL 为:" + url.toString());// http://www.baidu.com/index.html?language=cn#j2se
System.out.println("协议为:" + url.getProtocol());// http
System.out.println("验证信息:" + url.getAuthority());// www.baidu.com
System.out.println("文件名及请求参数:" + url.getFile());/// index.html?language=cn
System.out.println("主机名:" + url.getHost());// www.baidu.com
System.out.println("路径:" + url.getPath());// /index.html
System.out.println("端口:" + url.getPort());// -1 因为创建URL实例的时候没有指定端口号
System.out.println("默认端口:" + url.getDefaultPort());//80
System.out.println("请求参数:" + url.getQuery());// language=cn
System.out.println("定位位置:" + url.getRef()); //j2se
//获取当前URL响应流,并输出
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(), "GBK"));
while (br.readLine() != null) {
System.out.println(br.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
测试结果
发起请求
-
方式1:利用URL类的openStream()方法
1.构造一个URL对象;
2.调用这个URL对象的openStream()获取该URL响应流;
3.解析openStream()返回的响应流
4.关闭连接;@Test public void testURL() { InputStream is = null;//得到字节输入流 try { URL url = new URL("https://blog.csdn.net/qq877728715/article/details/103858729"); is = url.openStream(); BufferedReader bread = new BufferedReader(new InputStreamReader(is, "UTF-8"));//将字节输入流转换为字符输入流,将字符输入流添加到缓存中 while (bread.readLine() != null) { System.out.println(bread.readLine()); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } }执行结果:

URLConnection类
- 通过URL的openConnection() 返回一个URLConnection对象
- URLConnection 类是一个抽象类,代表应用程序和URL之间的通信连接,此类的实例可用于读取和写入此URL引用的资源。
- URLConnection 允许使用GET,POST或者其他HTTP方法请求方式将请求数据发送到服务器。
常用方法
| 方法 | 说明 |
|---|---|
| long getDate() | 返回响应时间 |
| Object getContent() | 获取响应内容=>该方法实质上与URL类的getContent()方法相同。使用该方法JVM需要识别和理解该内容类型。该方法只用于支持类似HTTP的协议,协议需要对MIME内容类型有较清楚的了解。若内容未知,或协议无法理解内容类型,getContent()会抛出一个UnknowServiceException异常。 |
| Object getContent(Class[] classes) | 获取响应内容并转换成指定对象=>该方法可以选择将内容转换为哪个类对象,以提供数据的不同对象表示。该方法尝试以classes数组中某个类的形式返回内容。优先顺序就是数组的顺序。若任何一种请求类型都不可用,此方法会返回null。 |
| String getContentEncoding() | 返回响应头部 content-encoding 字段值 |
| int getContentLength() | 返回响应头部 content-length字段值 =>返回响应内容中字节数。如果没有Content-Length首部,getContentLength()就返回-1 |
| long getContentLengthLong() | java7新增,返回响应头部 content-length字段值 =>返回响应内容中字节数。如果没有Content-Length首部,getContentLength()就返回-1, 返回类型变为long |
| String getContentType() | 返回响应头部 content-type 字段值 =>返回响应主体的MIME内容类型。如果没有提供内容类型,它不会抛出异常,而是返回null; |
| int getLastModified() | 返回响应头部 last-modified 字段值=>返回响应文档的最后修改日期。 |
| long getExpiration() | 返回响应头部 expires 字段值=>有些文档有基于服务器的过期日期,指示应当何时从缓存中删除文档,并从服务器重新下载。如果HTTP首部没有包括Expiration字段,getExpiration()就返回0,这表示文档不会过期,将永远保留在缓存中 |
| long getIfModifiedSince() | 返回对象的 ifModifiedSince 字段值。 |
| public void setDoInput(boolean input) | URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输入,则将 DoInput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 true。 |
| public void setDoOutput(boolean output) | URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false。 |
| public InputStream getInputStream() | 返回URL的输入流,用于读取资源 |
| 返回URL的输出流, 用于写入资源 | 返回URL的输出流, 用于写入资源。 |
| public URL getURL() | 返回 URLConnection 对象连接的URL |
| public String getHeaderField(int n) | 获取第 n 个头字段的值 |
| public String getHeaderField(String name) | 获取指定的头字段的值 |
| public Map getHeaderFields() | 返回所有url响应头信息 |
读取服务器
- 方式二:使用openConnection()方法创建一个URLConnection类的对象。
1.构造一个URL对象;
2.调用这个URL对象的openConnection()方法,获取对应该该URL的URLConnection对象;
3.调用这个URLConnection的getInputStream()方法;
4.使用通常的流API读取输入流;
5.关闭连接
执行结果:@Test public void testOpenConnection() { BufferedReader br = null; try { URL url = new URL("https://blog.csdn.net/qq877728715/article/details/103305194"); URLConnection conn=url.openConnection(); br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));//将字节输入流转换为字符输入流,将字符输入流添加到缓存中 while (br.readLine() != null) { System.out.println(br.readLine()); } conn.getInputStream().close(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) { br.close(); } } catch (IOException e) { e.printStackTrace(); } } }
向服务器写入数据
获取首部
获取响应头
String getContentType()
返回 Content-type 头字段的值。即数据的MIME内容类型。若类型不可用,则返回null。
除了HTTP协议,极少协议会使用MIME首部。若内容类型是文本。则Content-type首部可能会包含一个标识内容编码方式的字符集。
例:Content-type:text/html; charset=UTF-8
int getContentLength()
返回 Content-length 头字段的值。该方法获取内容的字节数。许多服务器只有在传输二进制文件才发送Content-length首部,在传输文本文件时并不发送。若没有该首部,则返回-1。
若需要知道读取的具体字节数,或需要预先知道创建足够大的缓冲区来保存数据时,可以使用该方法。
String getContentEncoding()
返回 Content-encoding 头字段的值。获取内容的编码方式。若内容无编码,则该方法返回null。
注意:Content-encoding(内容编码)与字符编码不同。字符编码方式由Content-type首部或稳定内容的信息确定,它指出如何使用字节指定字符。内容编码方式则指出字节如何编码其他字节。
例:若编码格式为x-gzip,则可以使用java.util.zip.GZipInputStream来解码。
long getDate()
返回 date 头字段的值。获取请求的发送时间。即自1900年1月1日子夜后过去的毫秒数。
注意:这是从服务器的角度看到的发送时间。可能与本地时间不一致。若首部不包括Date字段,则返回0。
long getExpiration()
返回 expires 头字段的值。获取Expires的值。若无该字段,则返回0。0即表示不过期,永远缓存。
注意:该值是自1970年1月1日上午12:00后的毫秒数。
long getLastModified()
返回 last-modified 头字段的值。该值是自1900年1月1日子夜后过去的毫秒数。若无该字段,则返回0。

获取任意首部字段
String getHeaderField(String name)
返回指定的头字段的值。
Map<String,List<String>> getHeaderFields()
返回头字段的不可修改的 Map。
String getHeaderFieldKey(int n)
返回第 n 个头字段的键。
String getHeaderField(int n)
返回第 n 个头字段的值。
long getHeaderFieldDate(String name, long Default)
返回解析为日期的指定字段的值。
int getHeaderFieldInt(String name, int Default)
返回解析为数字的指定字段的值。
配置首部
- 客户端向服务器发送请求,不仅会发送请求行,还发送首部。
- 通过在
客户端请求和服务器响应的首部中放置不同的字段,Web服务器可以根据此信息向不同客户端提供不同的页面,获取和设置cookie,通过口令设置用户等等。 - 每个URLConnection的具体子类都在首部中设置一些默认的键值对(实际上只有HttpURLConnection这样做,
因为HTTP是唯一以这种方式使用首部的主要协议。) 只能在连接打开之前使用。如果连接已经打开,它将抛出一个IllegalArgumentException异常;
//设置请求属性值
void setRequestProperty(String key, String value)
此方法只在连接打开之前打开,将会抛出IllegalStateException异常。但该方法仅支持对一个首部设置一个值。
//使用如下方法为首部增加值:
//HTTP允许一个属性有多个值。各个值之间用逗号隔开。
//例:cookie:username=sjq; session=hdfu23asdjf901j;
该方法用于添加某个指定首部字段的值。
void addRequestProperty(String key, String value)
//获取请求属性值
根据请求属性名获取指定首部字段:
String getRequestProperty(String key)
以获得连接的所有请求属性并作为一个Map返回
Map<String,List<String>> getRequestProperties()
//以上方法用于获取URLConneciton所拥有HTTP首部。
配置连接
URLConnection类的protected成员变量如下:
protected URL url
该字段指定URLConnection连接的URL。构造函数会在创建URLConnection时设置,此后就不能再改变。
protected boolean connected
当连接打开时,该字段为true。若连接关闭,则为false。没有直接读取或改变connected值的方法。任何导致URLConnection连接的方法都会将此变量设为true,包括connect(),getInputStream(),和getOutputStream()。
任何导致URLConnection断开的方法都会将此字段设为false。
java.net.URLConnection没有断开方法,但一些子类,如java.net.HttpURLConnection
中存在这样的方法。
protected boolean allowUserInteraction
该字段表示是否允许与用户交互。默认为false,即不允许交互。该值只能在URLConnection连接前设置。
例:Web浏览器可能需要访问用户名和口令。
protected boolean doInput
该字段在URLConnection可用于输入时为true,否则为false。默认为true。
protected boolean doOutput
该字段在URLConnection可用于输出时为true,否则为false。默认为false。
protected long ifModifiedSince
该字段指示了将放置If-Modified-Since首部字段中的日期(格林威治标准时间1970年1月1日子夜后的毫秒数)。
protected boolean useCaches
该字段指定了是否可以在缓存可用时使用缓存。默认为true,表示缓存将被使用;false表示缓存不被使用。
- 以上字段定义了
客户端如何向服务器作出请求。这些字段只能在URLConnection连接前修改。否则抛出IllegalStateException异常。
每个字段都有一些相应的方法。
URL getURL()
void setDoInput(boolean doinput)
boolean getDoInput()
void setDoOutput(boolean dooutput)
boolean getDoOutput()
void setUseCaches(boolean usecaches)
boolean getUseCaches()
void setAllowUserInteraction(boolean allowuserinteraction)
boolean getAllowUserInteraction()
void setIfModifiedSince(long ifmodifiedsince)
long getIfModifiedSince()
还有一些方法,这些方法用于定义和获取URLConnection对象的默认行为:
static boolean getDefaultAllowUserInteraction()
boolean getDefaultUseCaches()
void setDefaultUseCaches(boolean defaultusecaches)
static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)
static void setFileNameMap(FileNameMap map)
static FileNameMap getFileNameMap()
设置响应超时时间
Java1.5新增4个方法用来获取和修改连接的超时值。也就是说,底层socket等待远程服务器的响应时,等待多长时间后会抛出SocketTimeoutException异常
设置获取读取的超时值,单位为毫秒。(控制socket等待建立连接的时间)
int getReadTimeout()
void setReadTimeout(int timeout)
设置获取连接的超时值,单位为毫秒。(控制输入流等待数据到达的时间)
int getConnectTimeout()
void setConnectTimeout(int timeout)
- 这四个方法设置
0表示为永不超时。如果超时值为负数。两个设置方法都会抛出IllegalArgumentException异常。
使用URLConnection与服务器交互
InputStream getInputStream()
返回从此打开的连接读取的输入流。
OutputStream getOutputStream()
返回写入到此连接的输出流。
-
若只是向服务器请求数据,则为HTTP请求方法为GET。
-
若需要向服务器提交数据,必须在先调用
setDoOutput(true)。当doOutput属性为true时,请求方法将由GET变为POST。
获取内容
Object getContent()
该方法实质上与URL类的getContent()方法相同。使用该方法JVM需要识别和理解该内容类型。
该方法只用于支持类似HTTP的协议,协议需要对MIME内容类型有较清楚的了解。
若内容未知,或协议无法理解内容类型,getContent()会抛出一个UnknowServiceException异常。
Object getContent(Class[] classes)
该方法可以选择将内容转换为哪个类对象,以提供数据的不同对象表示。
该方法尝试以classes数组中某个类的形式返回内容。优先顺序就是数组的顺序。
若任何一种请求类型都不可用,此方法会返回null。
URLConnection的安全
建立网络连接、读写文件等等存在一些安全限制,URLConnection对象会受到这些安全限制的约束。
Permission getPermission()
该方法返回Permission对象,指出连接此URL所需的许可权。
如果没有所需的许可权(即没有适当的安全管理器),它就会返回null。
ContentHandlerFactory
URLConnection类包括一个静态的ContentHandler。即内容处理器。通过以下方法设置内容处理器工厂。
static void setContentHandlerFactory(ContentHandlerFactory fac)
HttpURLConnection
-
java.net.HttpURLConnection类是URLConnection的抽象子类,它提供了一些有助于专门操作http请求的额外方法。 -
sun.net.www.protocol.http包中也提供了一个HttpURLConnection类。该类实现了抽象的connect()方法。但一般很少直接访问该类。
URL实例的openConnection()会根据连接的不同,返回不同的Connection对象
- 如果你连接HTTP协议的URL, openConnection() 方法返回 HttpURLConnection 对象。
- 如果你连接的URL为一个 JAR 文件, openConnection() 方法将返回 JarURLConnection 对象。
@Test
public void testURLConnection() {
BufferedReader in = null;
try {
URL url = new URL("https://blog.csdn.net/qq877728715/article/details/103858729");
URLConnection urlConnection = url.openConnection();
HttpURLConnection connection = null;
if (urlConnection instanceof HttpURLConnection) {
connection = (HttpURLConnection) urlConnection;
} else {
System.out.println("请输入 URL 地址");
return;
}
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String content = null;
while ((content = in.readLine()) != null) {
System.out.println(content);
}
connection.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
猜测MIME内容类型
static String guessContentTypeFromName(String fname)
根据 URL 的指定 "file" 部分尝试确定对象的内容类型。
static String guessContentTypeFromStream(InputStream is)
根据输入流的开始字符尝试确定输入流的类型。
设置获取请求类型
HTTP协议提供了7中请求方法:
- GET
- POST
- HEAD
- PUT
- OPTIONS
- DELETE
- TRACE
通过以下方法设置请求方法:
若请求类型不是上面7个方法的字符串,则会抛出java.net.ProtocolException异常。
一般只设置请求方法是不够的,还需要调整HTTP首部,还要提供消息体。
void setRequestMethod(String method)
获取HTTP请求方法
String getRequestMethod()
断开与服务器的连接
-
HTTP1.1支持持久连接,允许通过一个TCP socket发送多个请求和响应。
-
HTTP的Keep-Alive对Web连接的性能有所提升,允许多个请求和响应通过一个TCP连接连续发送。 -
客户端通过HTTP请求首部包含
Connection字段及Keep-Alive,表示客户端愿意使用Keep-Alive:Connection: Keep-Alive -
当使用
Keep-Alive时,服务器不再因为向客户端发送最后一个字节数据就关闭连接。毕竟客户端还可能发送另一个请求。因此客户端需要负责关闭连接。Java提供如下方法关闭连接,实际上很少使用该方法: abstract void disconnect() //如果这个连接上还有打开的流,disconnect()将关闭这些流。 //不过,反过来并不成立。关闭一个持久连接上的流时,并不会关闭这个socket并断开连接;
获取错误响应
- 如果HTTP响应状态为
4xx(客户端错误)或者5xx(服务器错误),你可以通过HttpUrlConnection.getErrorStream()来查看服务器发送过来的信息。
InputStream getErrorStream()
//例:InputStream error = ((HttpURLConnection) connection).getErrorStream();
- 如果
HTTP响应状态为-1,就是出现了连接错误。HttpURLConnection会保持连接一直可用,如果你想关闭这个特性,需要把http.keepAlive设置为false:System.setProperty("http.keepAlive", "false");
Http响应码
- HTTP响应的第一行被称为消息响应。该信息
不会被URLConnection的getHeaderFiled()方法读取。String getResponseMessage() 返回消息响应。如:HTTP/1.1 404 Not Found int getResponseCode() 返回消息响应码。如:404。
HttpURLConnection类提供了常见响应码常量。具体请参考JDK文档。
重定向
-
默认情况下,HttpURLConnection类会跟踪重定向。但HttpURLConnection有两个静态方法,可以确定是否跟随重定向。
static void setFollowRedirects(boolean set) static boolean getFollowRedirects() 若跟随,则为true,否则为false。这两个是静态方法,它们会改变该方法后构造的所有HttpURLConnection对象的行为。
若安全管理器不允许其改变,则会抛出SecurityException异常。 -
也可以对某个HttpURLConnection实例设置是否重定向。
void setInstanceFollowRedirects(boolean followRedirects) boolean getInstanceFollowRedirects()
代理
- HttpURLConnection可以得知请求是否通过了代理服务器。
abstract boolean usingProxy()
流模式
-
每个发送给HTTP服务器的请求都有HTTP首部。首部中有一个Content-type字段;即请求体中的字节数。首部位于主体的前面。为了写入首部,需要知道主体的长度,而
在写首部的时候可能还不知道主题的长度。 -
一般情况下Java的解决办法是,
对于从HttpURLConnection获取的OutputStream,缓存写入到此OutputStream中的所有内容,直到流被关闭。到这时,它就知道了主体中有多少字节, -
在请求发送之前,HttpURLConnetion会把所有需要发送的数据放到缓冲区里,不管你是否使用
connection.setRequestProperty("Content-Length", contentLength);设置了contentLength,当你并行发送大量的POST请求时,这可能会引起OutOfMemoryExceptions异常,为了避免这个问题,需要使用如下方法:void setFixedLengthStreamingMode(int contentLength) 此方法用于在预先已知内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。 //例:httpConnection.setFixedLengthStreamingMode(contentLength); -
但是
如果不能事先知道内容的长度,可以使用HttpURLConnection.setChunkedStreamingMode()方法设置为块状流模式。在块状流模式的情况下,放在块里的内容将会被强行发送出去。下边的例子将会把发送的内容按照每块1KB的大小发送出去。void setChunkedStreamingMode(int chunklen) 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。 //例:httpConnection.setChunkedStreamingMode(1024);
URL和URLConnection区别
- URLConnection提供了对HTTP请求头(首部)的访问;
- URLConnection可以配置发送给服务器的请求参数;
- URLConnection除了读取服务器数据外,还可以向服务器写入数据;
注意: URL必须用完整的域名(http://www.baidu.com/),不能(www.baidu.com/)这样会报错!
使用HttpURLConnection进去get/post请求
在进行参数传递时,如果出现有中文参数,需要对参数进行编码处理,即 URLEncoder.encode( param,"UTF-8")
public class HttpClientUtil {
/**
* 向指定URL发送GET方法的请求
*
* @param requestUrl 发送请求的URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL所代表远程资源的响应结果
*/
public String get(String requestUrl, String param) {
HttpURLConnection connection = null;
InputStream is = null;
BufferedReader br = null;
String result = null;
try {
/** 创建远程url连接对象 */
URL url = new URL(requestUrl + "?" + param);
/** 通过远程url对象打开一个连接,强制转换为HttpUrlConnection类型 */
connection = (HttpURLConnection) url.openConnection();
/** 设置连接方式:GET */
connection.setRequestMethod("GET");
/** 设置连接主机服务器超时时间:15000毫秒 */
connection.setConnectTimeout(15000);
/** 设置读取远程返回的数据时间:60000毫秒 */
connection.setReadTimeout(60000);
/** 设置通用的请求属性 */
connection.setRequestProperty("accept", "*/*");//此处为暴力方法设置接受所有类型,以此来防范返回415;
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
/** 发送GET方式请求,使用connet方法建立和远程资源之间的实际连接即可 */
connection.connect();
/*-------------------------->*/
/** 获取所有相应头字段 */
Map<String, List<String>> map = connection.getHeaderFields();
/** 遍历响应头字段 */
for (String key : map.keySet()) {
System.out.println(key + "---------->" + map.get(key));
}
/* <-------------------------- */
/** 请求成功:返回码为200 */
if (connection.getResponseCode() == 200) {
/** 通过connection连接,获取输入流 */
is = connection.getInputStream();
/** 封装输入流is,并指定字符集 */
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
/** 存放数据 */
StringBuffer sbf = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
sbf.append(line);
sbf.append("\r\n");
}
result = sbf.toString();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
/** 关闭资源 */
try {
if (null != br) {
br.close();
}
if (null != is) {
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
/** 关闭远程连接 */
// 断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
// 固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些
connection.disconnect();
System.out.println("--------->>> GET request end <<<----------");
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param requestUrl 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public String post(String requestUrl, String param) {
HttpURLConnection connection = null;
InputStream is = null;
OutputStream os = null;
BufferedReader br = null;
String result = null;
try {
/** 创建远程url连接对象 */
URL url = new URL(requestUrl);
/** 通过远程url对象打开一个连接,强制转换为HttpUrlConnection类型 */
connection = (HttpURLConnection) url.openConnection();
/** 设置连接方式:POST */
connection.setRequestMethod("POST");
/** 设置连接主机服务器超时时间:15000毫秒 */
connection.setConnectTimeout(15000);
/** 设置读取远程返回的数据时间:60000毫秒 */
connection.setReadTimeout(60000);
/** 设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个 */
// 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
connection.setDoOutput(true);
// 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
connection.setDoInput(true);
/** 设置通用的请求属性 */
connection.setRequestProperty("accept", "*/*");//此处为暴力方法设置接受所有类型,以此来防范返回415;
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
/** Content-Type = application/json =>设置传入参数的格式:请求参数应该是JSON字符串的形式,后台使用@RequestBody接受*/
/** 设置Content-Type = application/json*/
//connection.setRequestProperty("Content-Type","application/json;charset=UTF-8");
// Content-Type = application/x-www-form-urlencoded =>设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
/** 通过连接对象获取一个输出流 */
os = connection.getOutputStream();
/** 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的 */
// 若使用os.print(param);则需要释放缓存:os.flush();即使用字符流输出需要释放缓存,字节流则不需要
if (param != null && param.length() > 0) {
os.write(param.getBytes());
}
os.flush();
/** 请求成功:返回码为200 */
if (connection.getResponseCode() == 200) {
/** 通过连接对象获取一个输入流,向远程读取 */
is = connection.getInputStream();
/** 封装输入流is,并指定字符集 */
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
/** 存放数据 */
StringBuffer sbf = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
sbf.append(line);
sbf.append("\r\n");
}
result = sbf.toString();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
/** 关闭资源 */
try {
if (null != br) {
br.close();}
if (null != is) {is.close();
}
if (null != os) {os.close();}
} catch (Exception e) {
e.printStackTrace();
}
/** 关闭远程连接 */
// 断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
// 固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些
connection.disconnect();
System.out.println("--------->>> POST request end <<<----------");
}
return result;
}
}
//如何发起请求,接受参数
// 1.Content-Type = application/json =>前台传JSON字符串,后台使用Map或者@RequestBody修饰对象
//doJsonPost("http://localhost:10086/slot/egosKnowledge/list",JSON.stringify("js对象"));
//2.Content-Type = application/x-www-form-urlencoded =>设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式,后台直接使用对象就可以接受,不需要@RequestBody修饰对象
//doJsonPost("http://localhost:10086/slot/egosKnowledge/list","flowId=4&_token_iben=b905d0d6-b5e8-4da6-b3a6-1fabb6956cf9&user=yige001");
Spring框架接收GET/POST方式提交的请求参数
-
Content-type=application/x-www-form-urlencoded:
@RequestBody不是必须加的 -
Content-type=mutipart/form-data:
@RequestBody不能处理这种格式 -
Content-type=其他格式,比如
application/json,application/xml等,必须使用@RequestBody来处理
以上1和3的场景都是必须使用@RequestBody来处理的,2场景也是不支持的
前台提交JSON数据必须将JS对象使用JSON.stringify()转为JSON字符串再传递,否则后台接收不到值
来源:CSDN
作者:oollXianluo
链接:https://blog.csdn.net/qq877728715/article/details/104032500

