编程语言
首页 > 编程语言> > 从源码研究实现Java发送get和post请求

从源码研究实现Java发送get和post请求

作者:互联网

一、get和post的一些基础知识

get请求:

  1. 原理:get请求本质上是去数据库里面查资源;

  2. 表现形式:请求数据会依附在url只有,以?分割,参数与参数之间以&符号相连,请求参数最多只能是1024个字节;

  3. 提交形式:请求和header一起发出;

  4. 安全性:安全性低,参数明文传输。

post请求:

  1. 原理:post请求本质是向数据库提交数据,增删改操作;

  2. 表现形式:提交的数据放在http的body体内,http协议对post请求的参数大小没有限制,但是不排除各大浏览器自己会做限制;

  3. 提交形式:请求header先发出,收到服务器返回的response header后,body再发出;

  4. 安全性:相对get请求,post请求的请求参数放在body体内相对安全一些,涉及用户登录密码和金钱相关的数据要特别注意加密处理。

二、http协议和https协议

二者的区别:

  1. http协议:超文本传输协议,且信息是明文传输;若攻击者截取客户端和服务器之间的传输报文,就可以获取用户信息,不安全;
  2. https协议:是具有安全性的ssl加密传输协议,为客户端和服务器之间的通信加密,确保数据传输安全。
  3. http结构:http–tcp–ip;https结构:http–ssl–tcp–ip;
  4. http协议连接简单,是无状态的;https是有ssl+http协议构建的加密传输、身份认证的网络协议;
  5. http协议的端口是80;https协议的端口是443;
  6. http证书申请免费,https证书需要到ca申请,需要交费。

三、Java-HTTPclient官方网站

2.1 官网地址:

http://hc.apache.org/httpcomponents-client-4.5.x/quickstart.html

2.2 eclipse中maven工程在pom.xml中配置HTTPclient依赖

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
		<dependency>
		    <groupId>org.apache.httpcomponents</groupId>
		    <artifactId>httpclient</artifactId>
		    <version>4.5.6</version>
		</dependency>

四、java发送get请求

CookieStore cookieStore = new BasicCookieStore();
client = HttpClients.custom().setDefaultCookieStore(cookieStore).build();

如果想要输出cookie信息,则需要注意两点:
1、输出cookie信息的操作要在执行请求后,即服务器返回结果后,在关闭response和client对象之前;
2、通过cookieStore.getCookies()方法得到的是一个List对象,数组的输出通过for循环即可得到结果。

简单封装后的发送get请求整个过程代码如下:

public static void sendGet(String url, String param) throws Exception {
		String result = null;
		CloseableHttpClient client = null;
		CloseableHttpResponse response = null;
		String finUrl = url + "?" + param;
		try {
			client = HttpClients.createDefault();
			HttpGet httpGet = new HttpGet(finUrl);
			
			//设置请求头
			httpGet.setHeader("Content-Type", "application/json; charset=utf-8");
			httpGet.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36");
			
			//设置请求超时 
			Builder builder = RequestConfig.custom();
    		builder.setConnectionRequestTimeout(3000);
			RequestConfig config = builder.build();
			httpGet.setConfig(config);
			httpGet.setConfig(RequestConfig.custom().setConnectionRequestTimeout(3000).build());
			
			response = client.execute(httpGet);
			int code = response.getStatusLine().getStatusCode();
   
			if (code == HttpStatus.SC_OK) {
				HttpEntity entity = response.getEntity();
				result = EntityUtils.toString(entity, "utf-8");
			}else {
				result = "服务器状态码为:" + code + " ,请检查接口地址和请求参数。";
			}	
		}finally {
			response.close();
			client.close();
		}
		return result;
	}

五、java发送post请求

List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("username", "vip"));
nvps.add(new BasicNameValuePair("password", "secret"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));

因为我们正常提供的测试case,在param字段中一般存String类型,所以找传String类型的请求参数,放到httpPost对象中(通过httpPost.setEntity()方法),携带发送请求。经过研究发现httpPost.setEntity()方法的入参是HttpEntity源码类的对象,但是HttpEntity是个接口,只能通过实例化子类来得到父类对象,找到StringEntity源码类,发现使用这个源码类中的其中一个构造方法,可以传String类型的参数,new子类通过向上转型,从而得到HttpEntity的对象,到此我们把sendPost方法中的String param字段添加到了httpPost对象内;

简单封装后的发送post请求整个过程代码如下:

public static String sendPost(String url, String param) throws Exception {
		String result = null;
		CloseableHttpClient client = null;
		CloseableHttpResponse response = null;
		try {
			client = HttpClients.createDefault();
			HttpPost httpPost = new HttpPost(url);
			//设置请求头
			httpPost.setHeader("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148");
			httpPost.setHeader("Content-Type", "application/json");
			
			//设置请求超时 
			Builder builder = RequestConfig.custom();
			builder.setConnectionRequestTimeout(3000);
			RequestConfig config = builder.build();
			httpPost.setConfig(config);
			httpPost.setConfig(RequestConfig.custom().setConnectionRequestTimeout(3000).build());
			
			//设置post请求参数
//			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
//			BasicNameValuePair bnvp = new BasicNameValuePair(null, null);
			// 直接添加NameValuePair类型的数据 遇到一级value下又有多级数据时也是直接写入吗?例如:"h_ids": {"idfa": "0CB4E1A5-1782-4F31-8B30-0218453BBCBE"}
//			nvps.add(new BasicNameValuePair("name", "zhaoliu"));
//			httpPost.setEntity(new UrlEncodedFormEntity(nvps));
			
                   //入参是HttpEntity类型,HTTPEntity是个接口,需要通过子类实例化得到父类对象,找HTTPEntity的实现类,StringEntity
//			httpPost.setEntity(HTTPEntity httpEntity);
			httpPost.setEntity(new StringEntity(param, "utf-8"));
			
			// 执行发送请求操作
			response = client.execute(httpPost);
			int code = response.getStatusLine().getStatusCode();
			
			if (code == HttpStatus.SC_OK) {
				HttpEntity entity = response.getEntity();
				result = EntityUtils.toString(entity, "utf-8");
			}else {
				result = "服务器状态码为:" + code + " ,请检查接口地址和请求参数。";
			}
		}finally {
			response.close();
			client.close();
		}
		return result;
	}

六、总结

6.1 不管发送post请求还是get请求,都需要先定义CloseableHttpClient的对象client。client对象可以生成一个CookieStore的对象管理和存储header的cookie和服务器返回的session信息,即cookie和session信息是在client对象这里操作的;

6.2 得到HttpGet或者HttpPost对象后,我们要设置的请求超时、请求header数据都是在这一步生成和操作的;

6.3 get请求的参数通过拼接即可实现,但post请求的请求参数是在body体内的,要通过httpPost.setEntity(new StringEntity(param, “utf-8”))代码绑定到HttpPost的对象上;

6.4 以上三步准备好之后,通过client.excute(httpPost) / client.excute(httpGet)拿到CloseableHttpResponse类型的一个返回值,我们初步拿到了服务器的返回结果;

6.5 对服务器返回结果做处理,通过response.getEntity()方法把返回结果转化成HttpEntity类型,最后通过EntityUtils工具类中的toString()方法把服务器返回的结果转化成我们常见的String类型;

6.6 最后就是善后工作,关闭response对象,关闭client对象。

赶快自己去实验一下吧!
中间的一些源码转换没有详细记录,哪里看不太懂欢迎和我交流!

标签:Java,请求,get,对象,client,httpPost,源码,response,String
来源: https://blog.csdn.net/weixin_44332139/article/details/115696174