业务场景:
需要接入顺丰快递的服务器,对用户订单快递进行查询、生成、取消等操作
这时我们需要去
顺丰快递对外开放API官网
查询相关资料,注册并请求权限、按照相关规则发送请求进行操作
新丰桥平台API接口规范文件
API接口列表在线文档
万事开头难,查看
文档
❓如何对请求顺丰API
分析结果:
我们是 CP,要请求 SF的 API要发送上面六个参数
用户注册成为 CP得到
partnerID
,传
serviceCode
来指定的调用的 API服务代码,按指定的加密方式得到
数字签名
,再把
相关请求的报文、时间戳、UUID随机数
作为参数,请求结果。
📰请求报文分析
每个请求的报文有所不同
这里以
路由查询报文
来分析
"language"
:
"0"
,
"trackingType"
:
"1"
,
"trackingNumber"
:
[
"444003077898"
,
"441003077850"
]
,
"methodType"
:
"1"
按照相关格式填写业务中的需要查询的快递订单id进去,实现相关查询
🌰Demo实践
Demo 代码
目标1:PostMan发送路由查询请求
目标:使用 POSTMAN发送一个路由查询请求
✍︎填参准备
⚠注意设置请求头
☢︎最重要的数字签名
文档中有加密demo
修改后输出需要的参数
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
String requestID = UUID.randomUUID().toString().replace("-", "");
String timestamp = String.valueOf(System.currentTimeMillis());
String checkWord = "XXXXXXX";
String msgData = "{\n\"language\": \"0\", \"trackingType\": \"1\", \"trackingNumber\": [\"444003077898\", \"441003077850\"], \"methodType\": \"1\" }";
String toVerifyText = msgData+timestamp+checkWord;
toVerifyText = URLEncoder.encode(toVerifyText,"UTF-8");
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(toVerifyText.getBytes("UTF-8"));
byte[] md = md5.digest();
String msgDigest = new String(new BASE64Encoder().encode(md));
System.out.println("时间戳:"+timestamp);
System.out.println("请求唯一号:"+requestID);
System.out.println("加密后的数字签名:"+msgDigest);
运行得到相关参数:
再填入剩下的参数
目标2:Java请求路由查询 API
目标:用 Java实现 post请求路由查询
就是从使用PostMan发送请求到在 Java中使用 HTTP请求工具类,对服务器传参,发送请求
🧰添加HTTP请求工具类请求接口
import org.apache.http.HttpEntity
import org.apache.http.HttpResponse
import org.apache.http.NameValuePair
import org.apache.http.ParseException
import org.apache.http.client.config.RequestConfig
import org.apache.http.client.entity.UrlEncodedFormEntity
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpPost
import org.apache.http.client.methods.HttpUriRequest
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.message.BasicNameValuePair
import org.apache.http.util.EntityUtils
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.io.IOException
import java.io.UnsupportedEncodingException
import java.nio.charset.StandardCharsets
import java.util.ArrayList
import java.util.Iterator
import java.util.List
import java.util.Map
public class HttpClientUtil {
private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class)
public static String postSFAPI(String url, String xml, String verifyCode) {
CloseableHttpClient httpClient = HttpClients.createDefault()
List<NameValuePair> parameters = new ArrayList<>()
parameters.add(new BasicNameValuePair("xml", xml))
parameters.add(new BasicNameValuePair("verifyCode", verifyCode))
HttpPost post = postForm(url, new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8))
String body = ""
body = invoke(httpClient, post)
try {
httpClient.close()
} catch (IOException var9) {
logger.error("HttpClientService post error", var9)
return body
private static String invoke(CloseableHttpClient httpclient, HttpUriRequest httpost) {
HttpResponse response = sendRequest(httpclient, httpost)
String body = ""
int statusCode = response.getStatusLine().getStatusCode()
if (statusCode == 200) {
body = parseResponse(response)
return body
private static String parseResponse(HttpResponse response) {
HttpEntity entity = response.getEntity()
String body = ""
try {
if (entity != null) {
body = EntityUtils.toString(entity)
} catch (ParseException | IOException var4) {
logger.error("HttpClientService paseResponse error", var4)
return body
private static HttpResponse sendRequest(CloseableHttpClient httpclient, HttpUriRequest httpost) {
CloseableHttpResponse response = null
try {
response = httpclient.execute(httpost)
} catch (IOException var4) {
logger.error("HttpClientService sendRequest error", var4)
return response
private static HttpPost postForm(String url, StringEntity entity) {
HttpPost httpPost = new HttpPost(url)
httpPost.setEntity(entity)
return httpPost
public static String post(String url, Map<String, String> params) throws UnsupportedEncodingException {
CloseableHttpClient httpClient = HttpClients.createDefault()
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(5000).setConnectTimeout(5000).setSocketTimeout(60000).build()
HttpPost httpPost = new HttpPost(url)
httpPost.setConfig(requestConfig)
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded
List<NameValuePair> paramsList = new ArrayList<>()
Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator()
for (Map.Entry<String, String> entry : params.entrySet()) {
paramsList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()))
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(paramsList, "UTF-8")
httpPost.setEntity(urlEncodedFormEntity)
String body = invoke(httpClient, httpPost)
try {
httpClient.close()
} catch (IOException var9) {
logger.error("HttpClientService post error", var9)
return body
调用工具类请求API
Map<String,String> params = new HashMap<>();
params.put("requestID",requestID);
params.put("msgDigest",msgDigest);
params.put("msgData",msgData);
params.put("timestamp",timestamp);
params.put("partnerID","xxxxxx");
params.put("serviceCode","EXP_RECE_SEARCH_ROUTES");
String result = null;
try {
result = HttpClientUtil.post("https://sfapi-sbox.sf-express.com/std/service", params);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
System.out.println(result);
目标3:举一反三
只改变请求的服务代码和请求的报表亦可成功访问对应的服务?
接入其他 API时,需要先申请权限
修改请求参数
serviceCode服务代码
msgData请求报表
建议抽取静态变量,方便修改
下面试着请求下订单
接口
private static String SERVICE_CODE = "EXP_RECE_CREATE_ORDER";
private static String msgData = "{
"cargoDetails":[
"count":2.365,
"unit":"个",
"weight":6.1,
"amount":100.5111,
"currency":"HKD",
"name":"护肤品1",
"sourceArea":"CHN"
"contactInfoList": [
"address":"广东省深圳市南山区软件产业基地11栋",
"contact":"小曾",
"contactType":1,
"country":"CN",
"postCode":"580058",
"tel":"4006789888"
"address":"广东省广州市白云区湖北大厦",
"company":"顺丰速运",
"contact":"小邱",
"contactType":2,
"country":"CN",
"postCode":"580058",
"tel":"18688806057"
"language":"zh_CN",
"orderId":"OrderNum20200612223"
我们尝试了
使用 postman对路由查询 API发出请求,
Java使用 HTTP工具类来接入路由查询 API,
同时举一反三地接入了生成订单 API
当然 Demo还可以进一步进行完善
Demo 完善展望
抽取服务代码做枚举类
声明用户属性的常量
- 233
-
LoneWalker
Spring Cloud