当前位置:   article > 正文

微信接口配置失败、接收微信发送的消息、与微信交互_微信公众号接口配置失败

微信公众号接口配置失败

微信接口配置失败、接收微信发送的消息

1 微信接口配置失败

因为要注册测试账号,微信需要发送对应请求后,由我们返回特定信息

在这里插入图片描述
官网接入文档地址:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html

在这里插入图片描述

1.1 编写加密类

public class Decript {
    public static String SHA1(String decript) {
        try {
            MessageDigest digest = MessageDigest
                    .getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}

  • 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

1.2 编写消息处理service

@Service
public class WxSignatureCheckService {

    //token,此处token内容与网站上我们填写的token一致
    private final String token = "wxtoken";

    public String wxSignatureCheck(String signature, String timestamp, String nonce, String echostr) {
        ArrayList<String> array = new ArrayList<String>();
        array.add(signature);
        array.add(timestamp);
        array.add(nonce);

        //排序
        String sortString = sort(token, timestamp, nonce);
        //加密
        String mytoken = Decript.SHA1(sortString);
        //校验签名
        if (mytoken != null && mytoken != "" && mytoken.equals(signature)) {
            System.out.println("签名校验通过。");
            return echostr; //如果检验成功输出echostr,微信服务器接收到此输出,才会确认检验完成。
        } else {
            System.out.println("签名校验失败。");
            return null;
        }
    }

    /**
     * 排序方法
     * @param token
     * @param timestamp
     * @param nonce
     * @return
     */
    public static String sort(String token, String timestamp, String nonce) {
        String[] strArray = { token, timestamp, nonce };
        Arrays.sort(strArray);

        StringBuilder sbuilder = new StringBuilder();
        for (String str : strArray) {
            sbuilder.append(str);
        }

        return sbuilder.toString();
    }

}
  • 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

1.3 编写controller类,接收请求

@RestController
public class WxSignatureCheckController {

    @Autowired
    private WxSignatureCheckService wxSignatureCheckService;

    @RequestMapping("/wx")//此处的请求路径与网站上填写的一致
    public String wxSignatureCheck(
            @RequestParam(value = "signature") String signature,
            @RequestParam(value = "timestamp") String timestamp,
            @RequestParam(value = "nonce") String nonce,
            @RequestParam(value = "echostr") String echostr
    ){
        return wxSignatureCheckService.wxSignatureCheck(signature, timestamp, nonce, echostr);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注意:此处我使用了内网穿透服务【ngrok】
感兴趣的可以去网上下载然后开启即可,会自动分配给我们一个域名
地址:http://ngrok.cc/login.html

2 接收微信发送的消息

参考官方手册:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

微信测试账号发送消息是以POST方式发送XML数据
此处以文本信息为例:

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[this is a test]]></Content>
  <MsgId>1234567890123456</MsgId>
  <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

2.1 扫描自己的测试公众号

在这里插入图片描述
地址:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

2.2 编写请求处理类

因为微信是通过POST请求发送XML数据,所以此处采用dom4j解析XML

①引入dom4j依赖

<!--dom4j-->
<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.1</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

②编写service解析XML

@Service
public class WxService {

    /**
     * 解析通过dom4j解析XML数据
     * @param is
     * @return map
     */
    public Map<String, String> parseRequest(InputStream is){
        Map<String, String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        try{
            //读取输入流,获取文档对象
            Document document = reader.read(is);
            //根据文档对象获取根节点
            Element root = document.getRootElement();
            //获取根节点的所有子节点
            List<Element> elements = root.elements();
            for(Element e : elements){
                map.put(e.getName(), e.getStringValue());
            }
            return map;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
  • 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

③编写controller接收消息

@RestController
public class WxController {

    @Autowired
    private WxService wxService;

    @PostMapping("/wx")
    public void receiveMsg(HttpServletRequest request){
        try {
            ServletInputStream is = request.getInputStream();
            Map<String, String> result = wxService.parseRequest(is);
            System.out.println(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.3 发送消息

在这里插入图片描述

结果如下:
在这里插入图片描述
语音、图片、位置信息等内容,参考官方文档解析即可。

https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

3 接收并恢复消息

3.1 导入依赖构建返回的XML数据

 <!--xstream构建返回的XML-->
 <dependency>
     <groupId>com.thoughtworks.xstream</groupId>
     <artifactId>xstream</artifactId>
     <version>1.4.14</version>
 </dependency>

 <!--dom4j解析XML数据-->
 <dependency>
     <groupId>dom4j</groupId>
     <artifactId>dom4j</artifactId>
     <version>1.1</version>
 </dependency>

 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <version>1.18.24</version>
 </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3.2 构建返回数据

①父类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseMessage {

    @XStreamAlias("ToUserName")
    private String toUserName;
    @XStreamAlias("FromUserName")
    private String fromUserName;
    @XStreamAlias("CreateTime")
    private String createTime;
    @XStreamAlias("MsgType")
    private String msgType;
    @XStreamAlias("MsgId")
    private String msgId;

    //初始化默认数据
    public BaseMessage(Map<String, String> requestMap){
        //开始是请求方,返回数据的时候,就成为了发送方
        this.toUserName = requestMap.get("FromUserName");
        this.fromUserName = requestMap.get("ToUserName");
        //微信中的时间默认是10位数,java的currentTimeMillis是13位,因此要除以1000
        this.createTime = System.currentTimeMillis() / 1000 + "";
        this.msgId = requestMap.get("MsgId");
    }

}
  • 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

②文本消息

@Data
@AllArgsConstructor
@NoArgsConstructor
@XStreamAlias("xml")
public class TextMessage extends BaseMessage{

    //文本内容
    @XStreamAlias("Content")
    private String content;

    public TextMessage(Map<String, String> requestMap, String content){
        super(requestMap);
        //设置消息类型为文本
        super.setMsgType("text");
        //设置文本消息
        this.content = content;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

③图片消息

@Data
@AllArgsConstructor
@NoArgsConstructor
@XStreamAlias("xml")
public class PicMessage extends BaseMessage{

    //图片链接
    @XStreamAlias("PicUrl")
    private String picUrl;

    //图片消息
    public PicMessage(Map<String, String> requestMap, String picUrl){
        super(requestMap);
        this.setMsgType("image");
        this.picUrl = picUrl;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3.3 创建service处理消息

@Service
public class WxService {

    /**
     * 解析通过dom4j解析XML数据
     * @param is
     * @return map
     */
    public Map<String, String> parseRequest(InputStream is){
        Map<String, String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        try{
            //读取输入流,获取文档对象
            Document document = reader.read(is);
            //根据文档对象获取根节点
            Element root = document.getRootElement();
            //获取根节点的所有子节点
            List<Element> elements = root.elements();
            for(Element e : elements){
                map.put(e.getName(), e.getStringValue());
            }
            return map;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 返回的消息
     * @param requestMap
     * @return
     */
    public String getResponse(Map<String, String> requestMap){
        String msgType = requestMap.get("MsgType");
        //要返回的消息
        BaseMessage rtnMsg = null;
        switch (msgType){
            //根据消息类型,处理不同消息
            case "text":
                rtnMsg = dealTextMessage(requestMap);
            case "image":
                //TODO
                break;
            case "voice":

                break;
            case "video":

                break;
            case "shortvideo":

                break;
            case "location":

                break;
            case "link":

                break;
            default:
                break;
        }
        return beanToXML(rtnMsg);
    }


    /**
     * 将消息对象处理为XML数据包
     * @param msg
     * @return
     */
    public String beanToXML(BaseMessage msg){
        if(msg == null){
            return "";
        }        //公众号返回信息
        XStream stream = new XStream();
        //设置需要处理XStreamAlias("xml")注解的类
        stream.processAnnotations(TextMessage.class);
        stream.processAnnotations(PicMessage.class);
        String xml = stream.toXML(msg);
        return xml;
    }

    /**
     * 处理文本消息
     * @param requestMap
     * @return
     */
    public BaseMessage dealTextMessage(Map<String, String> requestMap){
        String returnMsg = "收到消息!!!";
        TextMessage tm = new TextMessage(requestMap, returnMsg);
        return tm;
    }
}
  • 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
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

3.4 构建controller

@PostMapping("/wx")
public void receiveMsg(HttpServletRequest request, HttpServletResponse response){
    try {
        //设置编码,防止乱码
        request.setCharacterEncoding("utf8");
        response.setCharacterEncoding("utf8");
        //获取请求信息
        ServletInputStream is = request.getInputStream();
        //处理消息和事件推送
        Map<String, String> requestMap = wxService.parseRequest(is);
        System.out.println(requestMap);
        //准备回复的数据包
        String respXML = wxService.getResponse(requestMap);
        System.out.println(respXML);
        PrintWriter out = response.getWriter();
        out.print(respXML);
        out.flush();
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3.5 测试

在测试号上发送消息:
在这里插入图片描述
控制台打印消息:
在这里插入图片描述

其他消息处理:类似,官方其他消息XML格式
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/71383
推荐阅读
相关标签
  

闽ICP备14008679号