Java 美团餐饮开放平台 订单推送签名校验

独自开发了Java的功能,有对接到 美团餐饮开放平台,做的功能是将美团App上门店的订单通过回调通知给自己的系统,作为一笔系统订单进行排队、出餐处理

美团餐饮开放平台的请求采用Form表单,还有API参数会不定期更新

官方提供的SDK试了几遍,生成的Sig和请求的Sig一直对不上,就手写了一个校验的Demo。官方文档 在这里

 

Controller接收美团发起的回调请求,参数字段不固定,使用 HttpServletRequest 对象来获取所有的参数, 字母排序的话,直接使用 TreeMap 处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.demo.www.controller.openapi;
 
 
import com.google.common.base.Joiner;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RestController;
 
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.TreeMap;
 
/**
 * 美团餐饮开放平台回调接口
 * @author AnYuan
 */
 
@RestController
public class DemoController {
 
    /**
     * 签名的字段名
     */
    private final static String SIG_FIELD_NAME = "sig";
 
    /**
     * 校验签名
     * @param request  HttpServletRequest对象
     * @return 签名是否正确
     */
    public Boolean checkSign(HttpServletRequest request) {
 
        String url = String.format("%s://%s%s", request.getScheme(), request.getServerName(), request.getRequestURI());
        TreeMap<String, String> treeMap = new TreeMap<>();
        Enumeration<String> parameterNames = request.getParameterNames();
 
        while(parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            String value = request.getParameter(name);
            if (!SIG_FIELD_NAME.equals(name)) {
                treeMap.put(name, value);
            }
        }
 
        String sign = sign(url, treeMap);
        if (sign.equals(request.getParameter(SIG_FIELD_NAME))) {
            System.out.println("签名正确");
            return true;
        }
        System.out.println("签名错误");
        return false;
    }
 
    /**
     * 生成签名
     * @param url 请求的完整的url
     * @param treeMap 请求的全部参数
     * @return sign
     */
    private String sign(String url, TreeMap<String, String> treeMap) {
        String queryString = Joiner.on("&").useForNull("").withKeyValueSeparator("=").join(treeMap);
        String md5str = url.concat("?").concat(queryString).concat("美团开放平台的APP密钥");
        try {
            return DigestUtils.md5DigestAsHex(URLDecoder.decode(md5str, "UTF-8").getBytes());
        } catch (UnsupportedEncodingException encodingException) {
            System.out.println("签名生成失败");
        }
        return "";
    }
}

  

生成的签名和请求的签名匹配成功

 

posted @   安逺  阅读(640)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示