Java中简单Http请求
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中简单的for循环竟有这么多坑,你踩过吗
JAVA中简单的for循环竟有这么多坑,你踩过吗 实际的业务项目开发中,大家应该对从给定的list中剔除不满足条件的元素这个操作不陌生吧? 很多同学可以立刻想出很多种实现的方式,但你想到的这些实现方式 ...
- 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 │ ...
随机推荐
- AVFrame转换到Mat,yuv420p转换到RGB源代码
FFmpeg中AVFrame到OpenCV中Mat的两种转换方法 方法一:查表法 void AVFrame2Img(AVFrame *pFrame, cv::Mat& img) { int f ...
- Guake!
快捷键及其定制: [全局快捷键] F12:显示/隐藏Guake的程序界面. [局部快捷键] Ctrl+Shift+T:新建标签页: Ctrl+Shift+W:关闭标签页: Ctrl+Shift+C:复 ...
- vue学习笔记(二)——简单的介绍以及安装
学习编程需要的是 API+不断地练习^_^ Vue官网:https://cn.vuejs.org/ 菜鸟教程:http://www.runoob.com/vue2/vue-tutorial.html ...
- springmvc +mybatis 配置多数据源
1.数据源配置: jdbc_multiple.properties: # MySQL #======================================================== ...
- 前端工程构建工具FIS3
FIS3 是面向前端的工程构建工具.解决前端工程中性能优化.资源加载(异步.同步.按需.预加载.依赖管理.合并.内嵌).模块化开发.自动化工具.开发规范.代码部署等问题. 一.安装 全局安装fis3 ...
- PMS 启动流程
1.在SystemServer中启动PackageManagerService.main 2.newPackageManagerService()并添加到ServiceManager中 3.newin ...
- php加入环境变量
一.配置变量 右击计算机-属性-高级系统设置-环境变量-系统变量-双击path,编辑,将php的文件夹路径添加到后面,我是:D:\wamp64\bin\php\php5.6.25 二.测试 当没有加入 ...
- 【转】C++易混知识点1: 指针常量和常量指针的区别,附有详细案例解释
熟悉C++也已经有一些年头了,今天突然翻出当年浏览的书籍,对一些概念居然生疏了,指针常量和常量指针由于 指针 这一特殊的对象而变得难以区别.因此,在思考再三之后,决定写下该篇总结,加强对他们的区别: ...
- 【转】EI收录的中国期刊
ISSN 期刊名 0567-7718 Acta Mechanica Sinica 1006-7191 Acta Metallurgica Sinica (English Letters) ...
- 07_Python变量内存地址、小数据池
一.变量在内存中的地址 变量:用来标识(identify)一块内存区域.为了方便表示内存,我们操作变量实质上是在操作变量指向的那块内存单元.编译器负责分配.我们可以使用Python内建函数id()来获 ...