1. 概述
在这篇快速教程中,我们将使用Java内置类HttpUrlConnection来实现一个Http请求。
2. HttpUrlConnection
HttpUrlConnection类允许我们不用添加其他任何类库就能实现基本的Http请求。所有需要的类都包含在 java.net包内。缺点是,相比于其他http类库,该方法有点笨重,而且也没有提供一些高级特性的API,比如添加请求头,添加认证等。不过这些都不要紧。你完全可以将这个实现封装一下,添加一些高级特性也不是很复杂。
如果你只是想快速地进行些Http请求而不想添加一些类库的话,本文的这些代码就足够了。
另外,如果你对java的http请求基本实现不很了解,本文给出的代码也会有些帮助。
3. 创建请求
HttpUrlConnection类的创建是通过URL 类的openConnection()方法。这个方法只是创建一个连接对象,并不建立连接。
通过设置requestMethod属性,HttpUrlConnection类可以创建各种请求类型——包括GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE。
比如创建一个GET请求:
URL url = new URL("www.baidu.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
4. 添加请求参数
如果我们想要添加请求参数,我们需要设置doOutput 为true,然后将请求参数拼接成字符串,格式param1=value¶m2=value,以流的形式写入到HttpUrlConnection 实例的OutputStream中。示例代码如下:
Map<String, String> parameters = new HashMap<>();
parameters.put("param1", "val"); con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(ParameterStringBuilder.getParamsString(parameters));
out.flush();
out.close();
为方便转换字符串参数,我写了个工具类ParameterStringBuilder。类中包含一个静态方法getParamsString()将Map转换成对应格式的字符串:
public class ParameterStringBuilder {
public static String getParamsString(Map<String, String> params)
throws UnsupportedEncodingException{
StringBuilder result = new StringBuilder(); for (Map.Entry<String, String> entry : params.entrySet()) {
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
result.append("&");
} String resultString = result.toString();
return resultString.length() > 0
? resultString.substring(0, resultString.length() - 1)
: resultString;
}
}
5. 添加请求头
通过setRequestProperty() 方法可以添加请求头:
con.setRequestProperty("Content-Type", "application/json");
通过getHeaderField()方法可以读取响应头:
String contentType = con.getHeaderField("Content-Type");
6. 配置超时时间
类允许我们设置连接超时时间和读取超时时间。这些值决定了连接建立的最大等待时间间隔或读取到达数据的最大等待时间间隔。
设置超时时间,我们可以调用方法setConnectTimeout() 和方法setReadTimeout():
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
这个例子中我们将超时时间设为5秒。
7. 处理Cookies
java.net 包包含的类CookieManager,HttpCookie等能很便捷地处理Cookies.
首先,从响应中读取cookies,我们先获取相应头里的Set-Cookie值,然后解析成HttpCookie对象的List.
String cookiesHeader = con.getHeaderField("Set-Cookie");
List<HttpCookie> cookies = HttpCookie.parse(cookiesHeader);
接下来,我们将cookies存储起来:
cookies.forEach(cookie -> cookieManager.getCookieStore().add(null, cookie));
我们检查cookies中是否包含一个username属性,如果不包含,我们把一个叫zhangsan的username添加进去:
Optional<HttpCookie> usernameCookie = cookies.stream()
.findAny().filter(cookie -> cookie.getName().equals("username"));
if (usernameCookie == null) {
cookieManager.getCookieStore().add(null, new HttpCookie("username", "john"));
}
最后,将cookies添加到请求中去,我们需要在关闭连接和重新打开连接后,添加Cookie请求头 :
con.disconnect();
con = (HttpURLConnection) url.openConnection(); con.setRequestProperty("Cookie",
StringUtils.join(cookieManager.getCookieStore().getCookies(), ";"));
8. 处理重定向
我们可以通过调用方法setInstanceFollowRedirects(),设置为true或者false,来控制是否允许一个特定连接自动跟随重定向:
con.setInstanceFollowRedirects(false);
也可以全局设置所有的连接是否允许自动跟随重定向:
HttpUrlConnection.setFollowRedirects(false);
默认是允许自动跟随重定向的。
请求返回状态码301,302表示重定向,我们可以获取响应头的Location属性并用新的URL创建一个新的连接。
if (status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM) {
String location = con.getHeaderField("Location");
URL newUrl = new URL(location);
con = (HttpURLConnection) newUrl.openConnection();
}
9. 读取响应
通过读取HttpUrlConnection实例的InputStream流来读取响应。
读取响应常用方法有getResponseCode(), connect(), getInputStream() or getOutputStream() 。
比如,读取响应状态码:
int status = con.getResponseCode();
比如,读取响应头:
String contentType = con.getHeaderField("Content-Type");
比如,读取响应文本:
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
关闭连接:
con.disconnect();
结论
在这篇文章中,我们展示了如何通过HttpUrlConnection类来时间Http请求。以下代码可以直接拷贝使用。由于太简单,就不传github了。
package com.shlugood.utils; import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map; public class HttpUtil { private static String POST = "POST";
private static String GET = "GET";
private static String CONTENT_TYPE_URLENCODED = "application/x-www-form-urlencoded";
private static String CONTENT_TYPE_JSON = "application/json"; private static String httpRequest(String method, String contentType, String urlStr, HashMap<String,String> paras)
throws IOException {
URL url = new URL(urlStr);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); if(paras != null && !paras.isEmpty()){
con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(ParameterStringBuilder.getParamsString(paras));
out.flush();
out.close();
} BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
con.disconnect();
return content.toString();
} private static class ParameterStringBuilder {
public static String getParamsString(Map<String, String> params)
throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder(); for (Map.Entry<String, String> entry : params.entrySet()) {
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
result.append("&");
} String resultString = result.toString();
return resultString.length() > 0
? resultString.substring(0, resultString.length() - 1)
: resultString;
}
} public static String httpGetRequest(String url){
try {
return httpRequest(GET, CONTENT_TYPE_URLENCODED, url, null);
} catch (IOException e) {
e.printStackTrace();
}
return "";
} public static String httpPostRequest(String url, HashMap<String,String> paras){
try {
return httpRequest(POST, CONTENT_TYPE_URLENCODED, url, paras);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
Java中简单Http请求的更多相关文章
-
java中简单的反射
1.为什么会用到反射机制? 最近需要写定时服务,如果一个一个去写定时服务的话,后期维护是很烦人的,通过反射机制,我们就可以将定时服务的信息通过数据配置来实现,这样我们后期就可以将整个模块交给运维人员去 ...
-
java中简单内存计算
今天面试遇到一个问题,假设一个类中只声明一个int类型,那么这个对象多大,这里先写出解决方案,首先引入内存计算工具lucene-core, <dependency> <groupId ...
-
Java中前台JSP请求Servlet实例(http+Servlet)
1.前台jsp代码 himily.jsp,定义了用户名和密码两个输入框,使用post方式提交:/order-web/HimilyServlet其中order-web为站点名称,HimilyServle ...
-
java中的http请求的封装(GET、POST、form表单形式)
目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...
-
简述Java中Http/Https请求监听方法
一.工欲善其事必先利其器 做Web开发的人总免不了与Http/Https请求打交道,很多时候我们都希望能够直观的的看到我们发送的请求参数和服务器返回的响应信息,这个时候就需要借助于某些工具啦.本文将采 ...
-
java中发送http请求的方法
package org.jeecgframework.test.demo; import java.io.BufferedReader; import java.io.FileOutputStream ...
-
Java中简单的操作(if语句、常用操作符、switch语句、变量赋值等)
---------------------if语句介绍--------------------------------------------------- class IfDemo { public ...
-
[Freemarker] 在Java中简单实现对Freemarker的引用
Demo目录结构 ├─src │ ├─main │ │ ├─java │ │ │ └─demo │ │ │ └─freemarker │ │ │ ├─main │ │ │ │ Test.java │ ...
-
java中简单字符替换
在网络编程中,假设URL含有特殊字符,如空格.'#'等,server将无法识别导致无法获得正确的參数值.我们须要将这些特殊字符转换成server能够识别的字符,比如将空格转换成'%20'.给定一个字符 ...
随机推荐
-
iOS 按钮点击变色
之前一直以为是要在selected状态下增加一个背景图片,效果是颜色变深,明明我的图片是变浅: 之后试了用hightlighted 成功. [_loginBtn setBackgroundImage: ...
-
(转)SQL Server 的事务和锁(一)
SQL Server 的事务和锁(一) 最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁: 1 2 3 4 5 6 7 8 9 1 ...
-
ylbtech-dbs:ylbtech-7,welfareSystem(福利发放系统)
ylbtech-dbs:ylbtech-7,welfareSystem(福利发放系统) -- =============================================-- Datab ...
-
Ubuntu Nginx搭建Gitweb服务器
安装Nginx 和 Gitweb simba@simba-laptop:~$ sudo apt-get install nginx gitweb 修改Gitweb配置文件 simba@simb ...
-
HDU 1010 Temper of the bone(深搜+剪枝)
Tempter of the Bone Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) ...
-
Mac os 10.11 更新ruby
1.装cocoapods,ruby版本忒低->开始更新ruby->开始更新gem,这是一条不归路啊同志们,各种permission denied,各种路径不存在,各种路径没有读写权限,各种 ...
-
USCiLab cereal json 序列化
cereal json 序列化 https://blog.csdn.net/sunnyloves/article/details/51373793?utm_source=blogxgwz8 http: ...
-
dubbo 中文官网
根大家分享一下:dubbo的中文官网迁移到了githup上地址:https://dubbo.gitbooks.io/dubbo-user-book/content/preface/background ...
-
Java图片验证码乱码问题
有时部署到linux服务器上的web项目的图形验证码可能会出现乱码问题 这不是编码格式出错了,而是可能服务器上没有图形验证码中限定的那种字体 比如生成图形验证码的代码: Font font = new ...
-
ThinkPHP的A方法,R方法,M方法,D方法区别
在Thinkphp中,实例化对象有这么几种方法,如果是类,有A和R方法,区别是A方法只是对象的实例化,而R方法是可以同时实例化对象里面的方法的,这里需要去指定,如下面的实例代码: <?php n ...