java 实现 HTTP请求(GET、POST)的方法
使用Java进行服务调用时,避免不了要使用模拟HTTP请求来实现模拟,我在开发过程中恰巧遇到了这类的业务需求,所以就对这类的方法进行了一次总结,原理层次的东西暂时不考虑,毕竟HTTP的底层实现啥的,东西挺多且挺复杂的,对我的项目而言,理解这些东西并不能从直观上得到很明显的提升或帮助,还是代码来的比较实在,so,贴出几种方法的总结,用作备份,免的日后再重复造轮子。
第一种:白痴方案,最原始的解决方案,功能暂时是实现了,但是里面会涉及到通用性和性能等的问题,暂时不考虑,代码如下
public class HttpRequest {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpRequest.class.getName());
/**
* 向指定URL发送GET方法的请求
*
* @param url 发送请求的URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
StringBuilder result = new StringBuilder();
BufferedReader bufferedReader = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
LOGGER.info("key : {}", map.get(key));
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
LOGGER.error("HTTP GET error : {}", e.getMessage());
}
// 使用finally块来关闭输入流
finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result.toString();
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
LOGGER.info("url : {}", url);
LOGGER.info("param : {}", param);
PrintWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("accept-language", "en-US,en;q=0.5");
// 发送POST请求,必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} catch (Exception e) {
LOGGER.error("HTTP POST error : {}", e.getMessage());
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) out.close();
if (in != null) in.close();
} catch (IOException ex) {
LOGGER.error("close IO error : {}", ex.getMessage());
}
}
return result.toString();
}
}
第二种:升级版本,基于上个版本进行的简化版,看起来更简洁一些,代码如下
public class HttpClientUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class.getName());
public static String sendGet(String url, String param) throws IOException {
LOGGER.info("request url info : {}", url);
HttpGet request = new HttpGet(url + "?" + param);
return send(request);
}
public static String sendPost(String url, String param) throws IOException {
LOGGER.info("request url info : {}", url);
HttpPost request = new HttpPost(url);
request.setEntity(
new StringEntity(param, ContentType.create("application/json;charset=UTF-8"))
);
return send(request);
}
private static String send(HttpRequestBase request) throws IOException {
String message = "";
request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) ...");
request.setHeader("accept", "*/*");
request.setHeader("connection", "Keep-Alive");
CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
if (entity != null) {
long length = entity.getContentLength();
if (length != -1 && length < 2048) {
message = EntityUtils.toString(entity);
} else {
InputStream in = entity.getContent();
byte[] data = new byte[4096];
int count;
while ((count = in.read(data, 0, 4096)) != -1) {
outStream.write(data, 0, count);
}
message = new String(outStream.toByteArray(), "UTF-8");
}
}
LOGGER.info(">>>>>>>>>>>>>>>>>response message info : {}", message);
return message;
}
}
第三种:这一种方案,彻底告别了傻瓜式的轮子创造过程,直接使用开源的,已封装好的代码工具来实现这一过程,但是有个问题就是,他会产生轮询日志,以此保持链接通讯,如果看着不爽,可以改源码里的配置,或者使用log4j2中的日志过滤器,直接将他的日志过滤掉,并只打印程序的日志信息,看起来更清爽一些,代码如下(PS:这个工具包全方位支持RESFUL请求方式,这里只列举常用的两种,其他的请自行实验)
public class UnirestUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(UnirestUtil.class.getName());
/**
*
* @param url 目标url
* @param name 参数名称
* @param param 请求参数
* @return 网络传输状态码或请求结果
*/
public static HttpResponse sendGet(String url, String name, String param) throws UnirestException {
LOGGER.debug("request url info : {}", url);
HttpResponse<String> response = Unirest.get(url)
.header("accept", "application/json;charset=UTF-8")
.queryString(name, param)
.asString();
LOGGER.debug("response status info : {}", response.getStatus());
LOGGER.debug("response status message info : {}", response.getStatusText());
return response;
}
/**
*
* @param url 目标url
* @param name 参数名称
* @param param 请求参数实体
* @return 网络传输状态码
*/
public static HttpResponse sendPost(String url, String name, String param) throws UnirestException {
LOGGER.debug("request url info : {}", url);
HttpResponse<String> response = Unirest.post(url)
.header("accept", "application/json;charset=UTF-8")
.queryString(name, param)
.asString();
LOGGER.debug("response status info : {}", response.getStatus());
LOGGER.debug("response status message info : {}", response.getStatusText());
return response;
}
}
OK,至此,几种方案都贴出来了,可能还有更简洁可靠的方案来实现这个功能,但是我还没找到,如果您有更好的方法,请留言交流,分享出来吧,谢谢。
java 实现 HTTP请求(GET、POST)的方法的更多相关文章
- (转)Java发送http请求(get 与post方法请求)
本文转载于:http://bijian1013.iteye.com/blog/2166855 package com.bijian.study; import java.io.BufferedRead ...
- Java发送http请求(get 与post方法请求)
转载:https://www.cnblogs.com/zzw1994/p/5140538.html
- Java获取此次请求URL以及服务器根路径的方法
http://www.jb51.net/article/71693.htm ********************************************** 本文介绍了Java获取此次请求 ...
- Java发送Http请求并获取状态码
通过Java发送url请求,查看该url是否有效,这时我们可以通过获取状态码来判断. try { URL u = new URL("http://10.1.2.8:8080/fqz/page ...
- java 实现https请求
java 实现https请求 JSSE是一个SSL和TLS的纯Java实现,通过JSSE可以很容易地编程实现对HTTPS站点的访问.但是,如果该站点的证书未经权威机构的验证,JSSE将拒绝信任该证书从 ...
- Java Web之请求和响应
Servlet最主要作用就是处理客户端请求并作出回应,为此,针对每次请求,Web容器在调用service()之前都会创建两个对象,分别是HttpServletRequest和HttpServletRe ...
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- 通过java发送http请求
通常的http请求都是由用户点击某个连接或者按钮来发起的,但是在一些后台的Java程序中需要发送一些get或这post请求,因为不涉及前台页面,该怎么办呢? 下面为大家提供一个Java发送http请求 ...
- Java数据库连接池的几种配置方法(以MySQL数据库为例)
Java数据库连接池的几种配置方法(以MySQL数据库为例) 一.Tomcat配置数据源: 前提:需要将连接MySQL数据库驱动jar包放进Tomcat安装目录中common文件夹下的lib目录中 1 ...
- 深入浅出Java 重定向和请求转发的区别
深入浅出Java 重定向和请求转发的区别 <span style="font-family:FangSong_GB2312;font-size:18px;">impor ...
随机推荐
- Android-ByteUtil工具类
Byte处理转换相关的工具类: public class ByteUtil { private ByteUtil(){} /** * 把byte[] 转成 Stirng * @param bytes ...
- ArgumentException: 已添加了具有相同键的项。
此问题出现在asp.net mvc 5 中,前端向后端请求数据,方法的参数是模型,比如 Add(Student m), 结果浏览器显示的状态是500并返回错误提示ArgumentException,如 ...
- Asp.net WebForm 中无法引用App_Code文件夹下的类
在VS2013中新建asp.net webform应用程序,手动添加"APP_Code"文件夹并新建类文件,发现这些类无法在APP_Code文件夹以外被引用. 解决办法: 选中类文 ...
- AbpZero之企业微信---登录(拓展第三方auth授权登录)---第三步:需要注意事项
1.AbpZero的auth登录会在数据库中的AbpUserLogins表会根据你登录的ProviderKey和Provider来生成生成一条记录,ProviderKey在表中是唯一的: 2.要登录成 ...
- Struts2-057/CVE-2018-11776两个版本RCE漏洞分析(含EXP)
0x01 前言 2018年8月22日,Apache Strust2发布最新安全公告,Apache Struts2存在远程代码执行的高危漏洞(S2-057/CVE-2018-11776),该漏洞由Sem ...
- Asp.Net MVC EF之一:使用Database类在EF框架中执行Sql语句
引言 从EF6开始,增加了DateBase类,他通过从 DbContext 对象获取此类的实例.可用于管理支持数据库上下文或连接的实际数据库.这包括创建.删除和检查数据库的存在. 在6以前,我们使用E ...
- .net下使用最小堆实现TopN算法
测试代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespac ...
- day52 进程与守护进程
http://www.cnblogs.com/Eva-J/articles/8253549.html 博客参考. 多进程聊天 守护进程. 多进程 1.Unix/Linux:fork()调用实现多进程. ...
- SSM集成Easyui框架及多模块开发的认识
首先我们需要建立好一个emaven项目,并且在pom.xml中导入响应的jar包, <?xml version="1.0" encoding="UTF-8" ...
- C++单继承的构造函数和析构函数调用的顺序
1.继承构造函数调用顺序以及销毁的过程 先调用父类的构造函数,在调用子类的构造函数,析构函数调用相反.