实现对接第三方接口,可以使用HttpClient(年岁较久),也可以使用SpringBoot RestTemplate(新生代)。可根据个人喜好选择适当的方式进行对接,个人推荐使用SpringBoot RestTemplate。
具体使用如下:
@Data
@Component
@ConfigurationProperties(prefix = "xxx.api")
public class XXXConfig {
/**
* API 地址(一般是域名)
*/
private String baseAPIURL;
/**
* ID(根据接口文档定义就好)
*/
private String id;
/**
* 接入码
*/
private String uCode;
}
@Data
public class XXXReq extends XXXBase {
// 请求路径
public static final String REQ_URL = "xxxxxxxxx";
/**
* 请求参数
*/
private String XXXX;
}
@Data
public class XXXResp implements Serializable {
/**
* code
*/
private Integer code;
/**
* 提示信息
*/
private String msg;
/**
* 具体数据
*/
private Map<String,Object> data;
}
下图方法中入参params:表示你生成sign需要的参数。
大多数签名规则都是:拼接字符串,根据post请求参数keyASCII排序,生成一个字符串,然后对这个字符串进行MD5或者BCrypt加密,然后再将加密后的字符串转换成大写,得到的字符串作为sign。
附:MD5加密工具类:
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @author [email protected]
* @version 1.0
* @date 2019-10-24 19:20
*/
public class Md5Encrypt {
/**
* Used building output
*/
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
'b', 'c', 'd', 'e', 'f'};
/**
* 对字符串进行MD5加密
*
* @param text 明文
* @return 密文
*/
public static String md5(String text) {
MessageDigest msgDigest = null;
try {
msgDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("System doesn't support MD5 algorithm.");
}
try {
msgDigest.update(text.getBytes("UTF-8")); // 注意改接口是按照指定编码形式签名
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("System doesn't support your EncodingException.");
}
byte[] bytes = msgDigest.digest();
String md5Str = new String(encodeHex(bytes));
return md5Str;
}
private static char[] encodeHex(byte[] data) {
int l = data.length;
char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];
out[j++] = DIGITS[0x0F & data[i]];
}
return out;
}
public static void main(String[] args) {
System.out.println(Md5Encrypt.md5(Md5Encrypt.md5("123456" + "shanshi")));
}
}
XXXResp xxxApiCall(xxxxReq xxReq);
@Override
public XXXResp xxxApiCall(xxxxReq xxReq) {
//生成签名的公共请求map字段可提取一个方法mapUtil(),下面会附录。
// 该map是为了生成sign
Map map = signUtil.mapUtil();
// 非公用的属性可在这里赋值
map.put("xxxx", xxReq.getXXXX());
//param是接口请求参数
MultiValueMap<String, Object> param = signUtil.multiValueMap(map);
// 除了公用请求参数以外的请求参数,可在此添加
param.add("xxxx", xxReq.getXXXX());
// 请求全路径
String requestUrl = xxxConfig.getBaseAPIURL() + xxReq.REQ_URL;
// apiUtil.sendPost为发送请求方法
// paramList表示你请求接口的参数
// url表示请求的接口路径(全路径:域名+接口路径)
// 下面会介绍。
Map result = apiUtil.sendPost(param, requestUrl);
// signUtil.responseUtil为自定义返回数据解析方法,下面会附录。
return signUtil.responseUtil(result);
}
@PostMapping(value = "/XXXX")
@PreAuthorize("hasAnyRole('ADMIN','PRICE_ALL','PRICE_SELECT')")
@ResponseBody
public ResponseEntity getStockPrice(@RequestBody XXXReq xxxReq) {
xxxService.xxxApiCall(xxxReq);
return new ResponseEntity(xxxService.xxxApiCall(xxxReq), HttpStatus.OK);
}
paramList表示你请求接口的参数
url表示请求的接口路径(全路径:域名+接口路径)
result.getBody()就是响应回来的数据,根据自己业务要求处理数据即可。
/**
* 生成签名公共请求map字段
*
* @return
*/
public Map mapUtil() {
Map<String, Object> map = new HashMap<>();
map.put("id", xxxConfig.getId());
map.put("timeStamp", xxxx.DateUtil.getTimeStamp());
map.put("uCode", xxxConfig.getUCode());
return map;
}
/**
* 第三方接口请求参数公用字段
*
* @param map
* @return
*/
public MultiValueMap<String, Object> multiValueMap(Map map) {
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("id", map.get("id"));
param.add("uCode", map.get("uCode"));
param.add("timeStamp", map.get("timeStamp"));
param.add("sign", SignUtil.createSign(map));
return param;
}
/**
* 返回数据解析
*
* @param resultMap
* @return
*/
public XXXResp responseUtil(Map resultMap) {
XXXResp xxxResp = new XXXResp();
xxxResp.setCode((Integer) resultMap.get("code"));
xxxResp.setMsg((String) resultMap.get("msg"));
xxxResp.setData((Map) resultMap.get("data"));
return xxxResp;
}