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&param2=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请求的更多相关文章

  1. JAVA中简单的for循环竟有这么多坑,你踩过吗

    JAVA中简单的for循环竟有这么多坑,你踩过吗 实际的业务项目开发中,大家应该对从给定的list中剔除不满足条件的元素这个操作不陌生吧? 很多同学可以立刻想出很多种实现的方式,但你想到的这些实现方式 ...

  2. java中简单的反射

    1.为什么会用到反射机制? 最近需要写定时服务,如果一个一个去写定时服务的话,后期维护是很烦人的,通过反射机制,我们就可以将定时服务的信息通过数据配置来实现,这样我们后期就可以将整个模块交给运维人员去 ...

  3. java中简单内存计算

    今天面试遇到一个问题,假设一个类中只声明一个int类型,那么这个对象多大,这里先写出解决方案,首先引入内存计算工具lucene-core, <dependency> <groupId ...

  4. Java中前台JSP请求Servlet实例(http+Servlet)

    1.前台jsp代码 himily.jsp,定义了用户名和密码两个输入框,使用post方式提交:/order-web/HimilyServlet其中order-web为站点名称,HimilyServle ...

  5. java中的http请求的封装(GET、POST、form表单形式)

    目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...

  6. 简述Java中Http/Https请求监听方法

    一.工欲善其事必先利其器 做Web开发的人总免不了与Http/Https请求打交道,很多时候我们都希望能够直观的的看到我们发送的请求参数和服务器返回的响应信息,这个时候就需要借助于某些工具啦.本文将采 ...

  7. java中发送http请求的方法

    package org.jeecgframework.test.demo; import java.io.BufferedReader; import java.io.FileOutputStream ...

  8. Java中简单的操作(if语句、常用操作符、switch语句、变量赋值等)

    ---------------------if语句介绍--------------------------------------------------- class IfDemo { public ...

  9. [Freemarker] 在Java中简单实现对Freemarker的引用

    Demo目录结构 ├─src │ ├─main │ │ ├─java │ │ │ └─demo │ │ │ └─freemarker │ │ │ ├─main │ │ │ │ Test.java │ ...

随机推荐

  1. MySQL浅谈 LEFT JOIN

    On条件(在“A left join b on conditional_expr”)决定如何从table B 中检索数据行(Matching-State); 如果B中没有行匹配On 条件,额外的B的所 ...

  2. 微信小程序实现顶部、底部联动滑动

    这个场景一般用于展示数据时,数据过多,每条一行显示不下,表头可以横向滑动,下面要显示的数据部分横向纵向都可以滑动.表头或下面数据部分横向滑动的时候,两部分可以进行联动 具体效果像这样(随便写的丑样式布 ...

  3. JVM内存划分简介

    参考:深入理解JAVA虚拟机(第二版)

  4. 单KEY业务,数据库水平切分架构实践

    本文将以"用户中心"为例,介绍"单KEY"类业务,随着数据量的逐步增大,数据库性能显著降低,数据库水平切分相关的架构实践: 如何来实施水平切分 水平切分后常见的 ...

  5. python_如何快速找打字典中公共key

    场景实例: 西班牙足球联赛,每轮球员进球统计: 第一轮:{'1':1,'2':4,'5':2,'7':3} 第一轮:{'2':1,'5':4,'6':2,'3':3} 第一轮:{'1':1,'4':4 ...

  6. RESTClient

    RESTClient是Mozilla Firefox一个用于测试http请求插件. 1.打开火狐扩展搜索RESTClient进行安装并重启浏览器. 2.重启后可以在Mozilla Firefox地址栏 ...

  7. JMeter打开jmx文件报错解决方法

    错误提示: Error Problem loading XMLfrom:'D:\software\apace-jmeter-3.3\bin\线程组jmx', missing class com.tho ...

  8. php加入环境变量

    一.配置变量 右击计算机-属性-高级系统设置-环境变量-系统变量-双击path,编辑,将php的文件夹路径添加到后面,我是:D:\wamp64\bin\php\php5.6.25 二.测试 当没有加入 ...

  9. Regular Expression Syntax

    python的正则表达式 正则表达式的概念 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个"规则字符串",这个"规 ...

  10. NFS+sersync+Keepalived高可用方案

    标签(linux): nfs+keepalived 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 这套解决方法案的优点是配置比较简单.容易上手,缺点是当主NFS ...