get请求:
原理:get请求本质上是去数据库里面查资源;
表现形式:请求数据会依附在url只有,以?分割,参数与参数之间以&符号相连,请求参数最多只能是1024个字节;
提交形式:请求和header一起发出;
安全性:安全性低,参数明文传输。
post请求:
原理:post请求本质是向数据库提交数据,增删改操作;
表现形式:提交的数据放在http的body体内,http协议对post请求的参数大小没有限制,但是不排除各大浏览器自己会做限制;
提交形式:请求header先发出,收到服务器返回的response header后,body再发出;
安全性:相对get请求,post请求的请求参数放在body体内相对安全一些,涉及用户登录密码和金钱相关的数据要特别注意加密处理。
二者的区别:
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>
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; }
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对象。
赶快自己去实验一下吧!
中间的一些源码转换没有详细记录,哪里看不太懂欢迎和我交流!