需要重新构造快100提供的类
1.api
package com.kuaidi100.sdk.api;
import com.google.gson.Gson;
import com.kuaidi100.sdk.core.BaseClient;
import com.kuaidi100.sdk.request.BaseRequest;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.QueryTrackReq;
import com.kuaidi100.sdk.response.QueryTrackResp;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
/**
* 实时查询
*
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 16:27
*/
public class QueryTrack extends BaseClient {
public String getApiUrl(BaseRequest request) {
return ApiInfoConstant.QUERY_URL;
}
public QueryTrackResp queryTrack(QueryTrackReq queryTrackReq) throws Exception{
HttpResult httpResult = execute(queryTrackReq);
if (httpResult.getStatus() == HttpStatus.SC_OK && StringUtils.isNotBlank(httpResult.getBody())){
return new Gson().fromJson(httpResult.getBody(),QueryTrackResp.class);
}
return null;
}
}
package com.kuaidi100.sdk.api;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.core.BaseClient;
import com.kuaidi100.sdk.request.BaseRequest;
/**
* 快递信息地图轨迹
*
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 16:27
*/
public class QueryTrackMap extends BaseClient {
public String getApiUrl(BaseRequest request) {
return ApiInfoConstant.QUERY_MAP_VIEW_URL;
}
}
2.url配置
package com.kuaidi100.sdk.contant;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-15 17:43
*/
public class ApiInfoConstant {
/**
* 查询url
*/
public static final String QUERY_URL = "https://poll.kuaidi100.com/poll/query.do";
/**
* 快递查询地图轨迹url
*/
public static final String QUERY_MAP_VIEW_URL = "https://poll.kuaidi100.com/poll/maptrack.do";
}
package com.kuaidi100.sdk.contant;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-15 17:24
*/
public class CompanyConstant {
public static final String SF = "shunfeng";
public static final String ZT = "zhongtong";
public static final String YT = "yuantong";
public static final String HT = "huitongkuaidi";
public static final String ST = "shentong";
public static final String YD = "yunda";
public static final String EMS = "ems";
public static final String JD = "jd";
public static final String ZJS = "zhaijisong";
public static final String DB = "debangkuaidi";
public static final String SS = "shansong";
public static final String KFW = "kfw";
}
3.获取信息的类
package com.kuaidi100.sdk.core;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.BaseRequest;
import com.kuaidi100.sdk.utils.HttpUtils;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-11-25 16:02
*/
public abstract class BaseClient implements IBaseClient{
private int connectTimeout = 3000;
private int socketTimeout = 3000;
public HttpResult execute(BaseRequest request) throws Exception{
return HttpUtils.doPost(getApiUrl(request),request,connectTimeout,socketTimeout);
}
public abstract String getApiUrl(BaseRequest request);
}
package com.kuaidi100.sdk.core;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.BaseRequest;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-11-25 16:09
*/
public interface IBaseClient {
HttpResult execute(BaseRequest request) throws Exception;
}
4.返回的格式
package com.kuaidi100.sdk.pojo;
import lombok.Data;
@Data
public class HttpResult {
/**
* HTTP状态码
*/
private int status;
/**
* HTTP响应正文
*/
private String body;
/**
* 错误信息
*/
private String error;
public HttpResult() {
}
public HttpResult(int status, String body, String error) {
this.status = status;
this.body = body;
this.error = error;
}
}
5.请求对象属性
package com.kuaidi100.sdk.request;
import lombok.Data;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-11-25 16:12
*/
@Data
public class BaseRequest {
private String url;
}
package com.kuaidi100.sdk.request;
import lombok.Data;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 15:58
*/
@Data
public class QueryTrackParam {
/**
* 查询的快递公司的编码,一律用小写字母
*/
private String com;
/**
* 查询的快递单号, 单号的最大长度是32个字符
*/
private String num;
/**
* 收件人或寄件人的手机号或固话
*/
private String phone;
/**
* 出发地城市,省-市-区
*/
private String from;
/**
* 目的地城市,省-市-区
*/
private String to;
/**
* 添加此字段表示开通行政区域解析功能。0:关闭(默认),1:开通行政区域解析功能,2:开通行政解析功能并且返回出发、目的及当前城市信息
*/
private String resultv2 = "0";
/**
* 返回数据格式。0:json(默认),1:xml,2:html,3:text
*/
private String show = "0";
/**
* 返回结果排序方式。desc:降序(默认),asc:升序
*/
private String order = "desc";
}
package com.kuaidi100.sdk.request;
import lombok.Data;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 15:56
*/
@Data
public class QueryTrackReq extends BaseRequest {
/**
* 我方分配给贵司的的公司编号, 点击查看账号信息
*/
private String customer;
/**
* 签名, 用于验证身份, 按param + key + customer 的顺序进行MD5加密(注意加密后字符串要转大写), 不需要“+”号
*/
private String sign;
/**
* 其他参数组合成的json对象
*/
private String param;
}
6.响应对象属性
package com.kuaidi100.sdk.response;
import lombok.Data;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-11-25 16:11
*/
@Data
public class BaseResponse<T> {
private boolean result;
private String message;
private String status;
private T data;
}
package com.kuaidi100.sdk.response;
import lombok.Data;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 16:13
*/
@Data
public class QueryTrackData {
/**
* 时间,原始格式
*/
private String time;
/**
* 物流轨迹节点内容
*/
private String context;
/**
* 格式化后时间
*/
private String ftime;
/**
* 行政区域的编码
*/
private String areaCode;
/**
* 行政区域的名称
*/
private String areaName;
/**
* 签收状态 (0在途,1揽收,2疑难,3签收,4退签,5派件,6退回,7转投)
*/
private String status;
/**
* 本数据元对应的行政区域经纬度,resultv2=4或6标记后才会出现
*/
private String areaCenter;
/**
* 本数据元对应的行政区域拼音,resultv2=4或6标记后才会出现
*/
private String areaPinYin;
/**
* 状态值
*/
private String statusCode;
}
package com.kuaidi100.sdk.response;
import lombok.Data;
import lombok.ToString;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-12-24 17:34
*/
@Data
@ToString(callSuper = true)
public class QueryTrackMapResp extends QueryTrackResp {
/**
* 轨迹地图链接
*/
private String trailUrl;
/**
* 预计到达时间
*/
private String arrivalTime;
/**
* 平均耗时
*/
private String totalTime;
/**
* 到达还需多少时间
*/
private String remainTime;
}
package com.kuaidi100.sdk.response;
import lombok.Data;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 16:16
*/
@Data
public class QueryTrackPosition {
/**
* 地址编码
*/
private String number;
/**
* 地址名称
*/
private String name;
}
package com.kuaidi100.sdk.response;
import lombok.Data;
import java.util.List;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 16:07
*/
@Data
public class QueryTrackResp {
/**
* 消息体,请忽略
*/
private String message;
/**
* 快递单号
*/
private String nu;
/**
* 是否签收标记
*/
private String ischeck;
/**
* 快递公司编码,一律用小写字母
*/
private String com;
/**
* 通讯状态
*/
private String status;
/**
* 轨迹详情数组
*/
private List<QueryTrackData> data;
/**
* 快递单当前状态,包括0在途,1揽收,2疑难,3签收,4退签,5派件,6退回,7转投,10待清关,11清关中,12已清关,13清关异常,14拒签 等13个状态
*/
private String state;
/**
* 快递单明细状态标记
*/
private String condition;
private QueryTrackRouteInfo routeInfo;
/**
* 查不到轨迹或者其他问题返回码
*/
private String returnCode;
/**
* 查不到轨迹或者其他问题返回结果
*/
private boolean result;
}
package com.kuaidi100.sdk.response;
import lombok.Data;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 16:14
*/
@Data
public class QueryTrackRouteInfo {
/**
* 出发位置
*/
private QueryTrackPosition from;
/**
* 当前位置
*/
private QueryTrackPosition cur;
/**
* 收货地
*/
private QueryTrackPosition to;
}
7.工具类
package com.kuaidi100.sdk.utils;
import com.kuaidi100.sdk.pojo.HttpResult;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
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.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 16:59
*/
public class HttpUtils {
private final static String CHARSET_DEFAULT = "UTF-8";
/**
* post请求 编码格式默认UTF-8
*
* @param url 请求url
* @return
*/
public static HttpResult doPost(String url, Object obj,int connectTimeout,int socketTimeout) throws IOException, IllegalAccessException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse resp = null;
HttpResult result = new HttpResult();
try {
Map<String, String> params = ObjectToMapUtils.objectToMap(obj);
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setSocketTimeout(socketTimeout).build();
httpPost.setConfig(requestConfig);
if (params != null && params.size() > 0) {
List<NameValuePair> list = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : params.entrySet()) {
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(list, CHARSET_DEFAULT));
}
resp = httpClient.execute(httpPost);
String body = EntityUtils.toString(resp.getEntity(), CHARSET_DEFAULT);
int statusCode = resp.getStatusLine().getStatusCode();
result.setStatus(statusCode);
result.setBody(body);
} finally {
if (null != resp) {
resp.close();
}
}
return result;
}
/**
* post请求 编码格式默认UTF-8
*
* @param url 请求url
* @return
*/
public static HttpResult doPostFile(String url, File file,int connectTimeout,int socketTimeout) throws IOException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse resp = null;
HttpResult result = new HttpResult();
try {
HttpPost httpPost = new HttpPost(url);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setSocketTimeout(socketTimeout).build();
httpPost.setConfig(requestConfig);
// 把文件加到HTTP的post请求中
builder.addBinaryBody(
"file",
new FileInputStream(file),
ContentType.MULTIPART_FORM_DATA,
file.getName()
);
//HttpEntity
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
resp = httpClient.execute(httpPost);
result.setStatus(resp.getStatusLine().getStatusCode());
result.setBody(EntityUtils.toString(resp.getEntity(), CHARSET_DEFAULT));
} finally {
if (null != resp) {
resp.close();
}
}
return result;
}
}
package com.kuaidi100.sdk.utils;
import java.lang.reflect.Field;
import java.util.*;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-12-01 9:19
*/
public class ObjectToMapUtils {
/**
* 将Object对象里面的属性和值转化成Map对象
*
* @param obj
* @return
* @throws IllegalAccessException
*/
public static Map<String, String> objectToMap(Object obj) throws IllegalAccessException {
if (obj == null) {
return null;
}
Map<String, String> map = new HashMap<String,String>();
List<Field> allField = getAllField(obj);
for (Field field : allField) {
field.setAccessible(true);
String fieldName = field.getName();
String fieldValue = "";
if (field.getType()== String.class || field.getType() == Integer.class || field.getType() == int.class){
fieldValue = field.get(obj)==null?"": field.get(obj).toString();
}
map.put(fieldName, fieldValue);
}
return map;
}
private static List<Field> getAllField(Object obj){
List<Field> fieldList = new ArrayList<Field>() ;
Class<?> clazz = obj.getClass();
while (clazz != null){
fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
clazz = clazz.getSuperclass();
}
return fieldList;
}
}
package com.kuaidi100.sdk.utils;
import org.apache.commons.codec.digest.DigestUtils;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-14 16:54
*/
public class SignUtils {
/**
* 快递100加密方式统一为MD5后转大写
*
* @param msg
* @return
*/
public static String sign(String msg) {
return DigestUtils.md5Hex(msg).toUpperCase();
}
/**
* 查询加密
* @param param
* @param key
* @param customer
* @return
*/
public static String querySign(String param,String key,String customer){
return sign(param+key+customer);
}
/**
* 打印/下单 加密
* @param param
* @param t
* @param key
* @param secret
* @return: java.lang.String
* @author: api.kuaidi100.com
* @time: 2020/12/3 9:23
*/
public static String printSign(String param,String t,String key,String secret){
return sign(param+t+key+secret);
}
/**
* 云平台 加密
* @param key
* @param secret
* @return: java.lang.String
* @author: api.kuaidi100.com
* @time: 2020/12/3 9:23
*/
public static String cloudSign(String key,String secret){
return sign(key+secret);
}
/**
* 短信加密
* @param key
* @param userId
* @return: java.lang.String
* @author: api.kuaidi100.com
* @time: 2020/12/3 9:32
*/
public static String smsSign(String key,String userId){
return sign(key+userId);
}
}
9.测试
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.QueryTrack;
import com.kuaidi100.sdk.api.QueryTrackMap;
import com.kuaidi100.sdk.core.IBaseClient;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.QueryTrackParam;
import com.kuaidi100.sdk.request.QueryTrackReq;
import com.kuaidi100.sdk.response.QueryTrackMapResp;
import com.kuaidi100.sdk.utils.SignUtils;
import org.junit.Test;
/**
* @Author: api.kuaidi100.com
* @Date: 2020-07-15 16:20
*/
public class BaseServiceTest {
String key = "tSCsmBmK2314";
String customer = "CF6BE6E2E679D2EA2E132E2363846FB4";
/**
* 实时快递查询接口
*/
@Test
public void testQueryTrack() throws Exception{
QueryTrackReq queryTrackReq = new QueryTrackReq();
QueryTrackParam queryTrackParam = new QueryTrackParam();
queryTrackParam.setCom("shunfeng");
queryTrackParam.setNum("SF1457184997079");
queryTrackParam.setPhone("17843342795");
String param = new Gson().toJson(queryTrackParam);
queryTrackReq.setParam(param);
queryTrackReq.setCustomer(customer);
queryTrackReq.setSign(SignUtils.querySign(param ,key,customer));
IBaseClient baseClient = new QueryTrack();
HttpResult execute = baseClient.execute(queryTrackReq);
System.out.println(execute);
}
/**
* 快递查询地图轨迹
*/
@Test
public void testQueryMapView() throws Exception{
QueryTrackReq queryTrackReq = new QueryTrackReq();
QueryTrackParam queryTrackParam = new QueryTrackParam();
queryTrackParam.setCom("shunfeng");
queryTrackParam.setNum("SF1457184997079");
queryTrackParam.setPhone("17843342795");
queryTrackParam.setFrom("浙江省嘉兴市");
queryTrackParam.setTo("浙江省杭州市");
queryTrackParam.setResultv2("2");
String param = new Gson().toJson(queryTrackParam);
queryTrackReq.setParam(param);
queryTrackReq.setCustomer(customer);
queryTrackReq.setSign(SignUtils.querySign(param ,key,customer));
IBaseClient baseClient = new QueryTrackMap();
HttpResult result = baseClient.execute(queryTrackReq);
//QueryTrackMapResp queryTrackMapResp = new Gson().fromJson(result.getBody(),QueryTrackMapResp.class);
//System.out.println(queryTrackMapResp);
System.out.println(result);
}
}