业务场景:
web项目中集成第三方接口,需要将回调地址放到请求中一起发送到接收方,接收方处理完数据使用异步方式将处理结果发送到统一的回调地址中,接收到数据之后进行处理,并返回接收方处理结果
1. 书写回调接口
对应的Controller中:
@RequestMapping(value = "/notifyCreateResult")
@ResponseBody
public void createResult(HttpServletRequest request, HttpServletResponse response){
log.info("进入回调请求");
TestService.handleCreateResult(request,response);
}
TestService中:
public void handleCreateResult(HttpServletRequest request, HttpServletResponse response) {
// 读取POST请求中的参数
String method = request.getParameter("method");
String version = request.getParameter("version");
String timestamp = request.getParameter("timestamp");
String data = request.getParameter("data");
String sign = request.getParameter("sign");
// 验证签名
if (!TestUtils.validateSign(method, version, timestamp, data, sign)) {
// 签名验证失败,可以直接返回或记录日志
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
log.info("-----验证签名失败-----");
return;
}
// 处理业务逻辑
boolean success = processData(method, data);
// 构造响应数据
Map<String, Object> responseData = new HashMap<>();
responseData.put("success", success);
if (!success) {
responseData.put("msg", "处理失败了"); // 失败时的说明
}
// 返回响应
response.setContentType("application/json");
PrintWriter out = null;
try {
out = response.getWriter();
} catch (IOException e) {
throw new RuntimeException(e);
}
out.print(new Gson().toJson(responseData));
out.flush();
}
processData:
private boolean processData(String method, String data) {
// 此处书写接收到参数之后,要进行的业务处理
// 例如:改变数据库中的状态等
return true;
}
TestUtils中的validateSign:
public static boolean validateSign(String method, String version, String timestamp, String data, String appkey, String sign) {
// 按照开发文档中的规则生成待验证的签名
String expectedSign = sha1Hex("data" + data + "method" + method + "version" + version + "timestamp" + timestamp);
// 对比签名是否一致
return expectedSign.equalsIgnoreCase(sign);
}
private static String sha1Hex(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
byte[] hash = digest.digest(input.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
2. 将统一的回调地址放到请求中发送到接收方中
builder.addPart("notifyUrl",new StringBody("http://xxxxx/xxxx/xxx",ContentType.create("text/plain",Consts.UTF_8)));