Enterprise wechat address book callback template - XML to JSON - makes callback no longer difficult!

 

When developing internal applications, we need to achieve two-way synchronization between internal applications and enterprise wechat, that is, interconnection.

for instance

Synchronization 1: when modifying the internal address book, the enterprise internal OA system can synchronize the enterprise wechat (directly call the API interface)

Synchronization 2: when modifying the address book in the enterprise wechat background, feed it back to the internal OA system (explained in this article)

Generally speaking, the process of realizing address book callback is divided into four steps:

Step 1: the administrator modifies the address book information in the enterprise wechat in the background (all except API interface modification)

Step 2: after the enterprise wechat modifies the address book, send the modification details to the internal system of the enterprise in the form of XML

Step 3: after receiving the XML information, the enterprise internal system decrypts the information

Step 4: for the decrypted information, modify the address book of the enterprise's internal system

 

Concrete implementation

 

1, Guide Package

Decryption tool download address

Download the decryption tool provided by enterprise wechat and put it into your own project.

Note that the name of the com package cannot be changed

If the 1.9 package fails to compile, you can use the 1.4 package

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.4</version>
</dependency>

 

2, Verify URL

Configure the URL in the enterprise wechat management background

 

The test method is the template for verifying the URL, which can be used immediately

ParameterSettings is the class where I put fixed fields, and the corresponding parameters can be replaced

import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
     * Verify URL
     * @param request
     * @param response
     * @throws Exception
     */
    public void test(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // Wechat encryption signature
        String msg_signature = request.getParameter("msg_signature");
        // time stamp
        String timestamp = request.getParameter("timestamp");
        // random number
        String nonce = request.getParameter("nonce");
        // Random string
        String echostr = request.getParameter("echostr");

        System.out.println("request=" + request.getRequestURL());

        PrintWriter out = response.getWriter();
        // Pass inspection msg_signature verifies the request. If the verification is successful, it returns echostr as it is, indicating that the access is successful, otherwise the access fails
        String result = null;
        try {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(ParameterSettings.YHHD_TOKEN, ParameterSettings.YHHD_EAK, ParameterSettings.AS_CORPID);
            result = wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr);
        } catch (AesException e) {
            e.printStackTrace();
        }
        if (result == null) {
            result = ParameterSettings.YHHD_TOKEN;
        }
        out.print(result);
        out.close();
        out = null;
    }

Original CSDN link: https://zwz99.blog.csdn.net/article/details/113818974

3, Declassify

After verifying the URL, replace the interface method of the URL with the code of the callBack method below

When the enterprise wechat sends a callback notice, this method will receive it

The template will convert the data in XML format into standard JSON for subsequent processing

JSON uses Alibaba's fastjson. maven depends on the following:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.9</version>
</dependency>
import com.alibaba.fastjson.JSONObject;
import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;


    /**
     * Enterprise wechat sends XML to this method
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/callBack", method = RequestMethod.POST)
    public void callBack(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String respMessage = "";
        respMessage=getDecryptMsg(request);
        //Callback processing
        dealCallBackEvent(respMessage);
        PrintWriter out = response.getWriter();
        out.print(respMessage);
        out.close();
    }

    /**
     * Decrypt XML data conversion JSON
     * @param request
     * @return
     */
    public String getDecryptMsg(HttpServletRequest request) {
        String postData="";   // Ciphertext, corresponding to the data requested by POST
        String result="";     // Plaintext, the result after decryption
        String msg_signature = request.getParameter("msg_signature"); // Wechat encryption signature
        String timestamp = request.getParameter("timestamp");   // time stamp
        String nonce = request.getParameter("nonce");          // random number
        try {
            //1. Get the encrypted request message: use the input stream to get the encrypted request message postData
            ServletInputStream in = request.getInputStream();
            BufferedReader reader =new BufferedReader(new InputStreamReader(in));

            String tempStr="";   //As a temporary string of output string, it is used to judge whether the reading is completed
            while(null!=(tempStr=reader.readLine())){
                postData+=tempStr;
            }
            //2. Obtain message plaintext: decrypt the encrypted request message to obtain plaintext
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(ParameterSettings.YHHD_TOKEN, ParameterSettings.YHHD_EAK, ParameterSettings.YH_CORPID);
            result = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, postData);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (AesException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * Conduct business logic processing on the decrypted data
     * @param text
     */
    private void dealCallBackEvent(String text) {
        JSONObject json = XmlTool.documentToJSONObject(text);
        String event = json.getString("Event");
        String changeType = json.getString("ChangeType");
        if (event.equals("change_contact")) {
            if (changeType.equals("create_user")) { // Create user callback
                String name = json.getString("Name");
                String userID = json.getString("UserID");
                String departmentStr = json.getString("Department"); // Comma separated string for Department
                String[] departmentList = departmentStr.split(",");
                String corpID = json.getString("ToUserName");
                String mobile = json.getString("Mobile");
                if (corpID.equals(ParameterSettings.YH_CORPID)) { // Replace enterprise ID
                    // Business logic code
                }
            }
        }
    }

 

That's the end of the core code. Here are all the other codes

import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class XmlTool {
    /**
     * String To org dom4j. Document
     * @param xml
     * @return
     * @throws DocumentException
     */
    public static Document strToDocument(String xml){
        try {
            //The xml tag is added to get the outermost tag, which can be removed if not needed
            return DocumentHelper.parseText(xml);
        } catch (DocumentException e) {
            return null;
        }
    }

    /**
     * org.dom4j.Document Transfer to com alibaba. fastjson. JSONObject
     * @param xml
     * @return
     * @throws DocumentException
     */
    public static JSONObject documentToJSONObject(String xml){
        return elementToJSONObject(strToDocument(xml).getRootElement());
    }

    /**
     * org.dom4j.Element Transfer to com alibaba. fastjson. JSONObject
     * @param node
     * @return
     */
    public static JSONObject elementToJSONObject(Element node) {
        JSONObject result = new JSONObject();
        // The name, text content, and attributes of the current node
        List<Attribute> listAttr = node.attributes();// list of all attributes of the current node
        for (Attribute attr : listAttr) {// Traverse all attributes of the current node
            result.put(attr.getName(), attr.getValue());
        }
        // Recursively traverse all child nodes of the current node
        List<Element> listElement = node.elements();// list of all first level child nodes
        if (!listElement.isEmpty()) {
            for (Element e : listElement) {// Traverse all first level child nodes
                if (e.attributes().isEmpty() && e.elements().isEmpty()) // Judge whether the primary node has attributes and child nodes
                    result.put(e.getName(), e.getTextTrim());// If not, the current node will be treated as the attribute of the parent node
                else {
                    if (!result.containsKey(e.getName())) // Judge whether the parent node has the attribute of the first level node name
                        result.put(e.getName(), new JSONArray());// Not created
                    ((JSONArray) result.get(e.getName())).add(elementToJSONObject(e));// Put the primary node into the value corresponding to the attribute of the node name
                }
            }
        }
        return result;
    }
}

 

import lombok.Data;
import java.util.List;

@Data
public class Items {
    List<Item> item;
}
import lombok.Data;

import java.util.List;

@Data
public class Item {
    private String type;

    private List<TextValue> text;

    private String name;

    private List<WebValue> web;
}
import lombok.Data;

import java.util.List;

@Data
public class Member {
    private String toUserName;
    private String fromUserName;
    private String createTime;
    private String msgType;
    private String event;
    private String changeType;
    private String userID;
    private String newUserID;
    private String name;
    private String department;
    private String isLeaderInDept;
    private String position;
    private String mobile;
    private String gender;
    private String email;
    private String status;
    private String avatar;
    private String alias;
    private String telephone;
    private String address;
    private List<Items> extAttr;
}
import lombok.Data;

@Data
public class TextValue {

    private String Value;
}
import lombok.Data;

@Data
public class WebValue {
    private String Title;
    private String Url;
}

 

Tags: Java JSON api

Posted by 14zero on Tue, 19 Apr 2022 02:47:41 +0930