业务背景:最近在实现微信授权登陆,并且获取授权用户的手机号码,其中是需要我们后台写工具类来模拟对接口的调用来取得相应参数,其实就是相当于实现PostMan、AirPost之类的工具对后端接口发起请求的功能,本篇是以Post的请求方式,参数以JSON格式封装在请求体中,请求头为application/json,进行示例模拟。
关于获取微信授权数据的相关文章会在后续写出(先给自己挖个坑)。
一、导入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
二、实现代码
package user;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import java.io.IOException;
/**
* @author w7h1te
* @version 6月...
* @date 2022/6/30 11:31
*/
public class UserTrain {
/***
* 在咱们平常作项目的时候,有时候不免会接触到HttpClient进行一些数据的请求和传输。HttpClient默认使用的是表单提交的形式进行数据post,
* 有时候咱们须要使用json或者其余形式发送数据那么咱们就须要修改他的content-typejson
*/
@Test
public void testPostRequest() {
//咳咳,接口地址还是要隐藏的,一个登陆接口的测试
String url = "http://*****:8080/***/***/login";
//请求体,随便放两个参
JSONObject parammap = new JSONObject();
parammap.put("userName", "1371606161111");
parammap.put("passWord","12332211");
String str = doPost(url, parammap.toJSONString());
// 输出响应内容
System.out.println(str);
}
public String doPost(String url ,String json) {
// 建立Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String res = "";
try {
// 建立Http Post请求
HttpPost post = new HttpPost(url);
// 建立请求内容 ContentType:请求格式设置
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
post.setEntity(entity);
// 执行http请求
response = httpClient.execute(post);
res = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return res;
}
}
执行结果
{"success":false,"resultCode":"-1","resultMsg":"用户名和密码不匹配,请您检查后重新登录","data":null}
三、使用我们的AirPost再次做个测试
直接上图来点真实的
可以看到,这个返回结果是走了我们的后台逻辑判断的,请求是成功的。
四、注意
可以看到我们是请求成功的,当然这里面还是有很多点值得注意的。
4.1 第一点:参数传输问题
Content-Type:application/json这样的请求格式,可以在上面AirPost中看到,传入的参数是以json的格式,那么我们相应的后台接收应该是 以method(@RequestBody VO index)
的方式来接收,否则是接收不到的。
4.2 第二点:关于ContentType
HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。其中 POST 一般用来向服务端提交数据,本文主要讨论 POST 提交数据的几种方式。
我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。
协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。
前端 Content-Type | 后端 ContentType | json对象/字符串 | 后端参数获取形式 | |
1 | application/json | APPLICATION_JSON | 字符串 | method(@RequestBody VO index) |
2 | appcalition/www-form-urlencode | APPLICATION_FORM_URLENCODED | 对象 | method(VO index) |
4.3 第三点:获取参数的几种常用注解
@PathVariable:一般我们使用URI template样式映射使用,即url/{param}这种形式,也就是一般我们使用的GET,DELETE,PUT方法会使用到的,我们可以获取URL后所跟的参数。
@RequestParam:一般我们使用该注解来获取多个参数,在()内写入需要获取参数的参数名即可,一般在PUT,POST中比较常用。
@RequestBody:该注解和@RequestParam殊途同归,我们使用该注解将所有参数转换,在代码部分在一个个取出来,也是目前我使用到最多的注解来获取参数
@RequestHeader来获取头信息里的值,@CookieValue来获取Cookie值等等。在这,我也仅仅说明一些较常用的取值方法而已。