Public number background development (SpingMVC receive public response number message)

1. Prepare

1. Preparation Services

And interfacing micro-channel url to meet the following conditions:

(1) the public has access to the Internet

(2) port only supports 80 ports

  Here, if the service is a public network access to the best mapping may be performed by other external networks or peanut shell mapping tool, such as ngrok .

2. The principle of data exchange

  Development mode and edit mode are mutually exclusive, open development model when the edit mode automatically reply with a custom menu fail; open Edit mode or an automatic reply from when developing custom menu mode will fail.

 

 

Data exchange principle development model are as follows:

 

  We need to develop public task is Wearnes number of the server, including business logic, authentication, and other operations.

2. Access background

  Reference number of public development documents: Development -> Developer Tools - "developer documentation, there are documents like docking nails, and other guides have access to interface documentation.

  https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

1. The first step: Fill in the server configuration

 

Step 2: Verify message is from the micro-channel server (for authentication servers in their own micro channel)

  Developer information submitted after the micro channel server sends a GET request to the URL address of the server filled, carries GET request parameters as follows:

 

Developer test signature is performed by the request check (check mode below). If confirmed the GET request to the server from the micro-letter, please return it unchanged echostr content parameters, the access into effect, become a successful developer, or access failure. Encryption / verification process is as follows:

1) The token, timestamp, nonce three parameters lexicographically sorting 2) the blending of three parameters sha1 string into a string encrypted 3) string developer obtained can be compared with an encrypted signature, identify the source of the request in the micro-channel

SpringMVC received code is as follows:

package cn.qlq.controller.weixin;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.qlq.controller.UserController;
import cn.qlq.utils.weixin.WeixinCheckUtils;

@Controller
@RequestMapping("weixin")
public class WeixinController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @ResponseBody
    @RequestMapping("index")
    public String index(@RequestParam(required = false) String signature,
            @RequestParam(required = false) String timestamp, @RequestParam(required = false) String nonce,
            @RequestParam(required = false) String echostr) {

        logger.debug("signature: {}, timestamp: {}, nonce: {}, echostr: {}", signature, timestamp, nonce, echostr);

        if (StringUtils.isNoneBlank(signature, timestamp, nonce)
                && WeixinCheckUtils.checkSignature(signature, timestamp, nonce)) {
            return echostr;
        }

        return "error";
    }
}

 

Verification tools as follows:

package cn.qlq.utils.weixin;

import java.security.MessageDigest;
import java.util.Arrays;

public  class WeixinCheckUtils {

    // token, consistent with the public micro-channel number background 
    Private  static  Final String token = "devqiaolq" ;

    public static boolean checkSignature(String signature, String timestamp, String nonce) {
        String[] arr = new String[] { token, timestamp, nonce };

        // Sort 
        Arrays.sort (arr);

        // 生成字符串
        StringBuffer content = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }

        // sha1加密
        String temp = getSha1(content.toString());
        return temp.equals(signature);

    }

    public static String getSha1(String str) {
        if (str == null || str.length() == 0) {
            return null;
        }

        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));

            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }
}

 

  Note: If login filter, micro-channel release request remember in the filter.

 

3. The third step: implement business logic based interface document

1. After you first need to enable developer mode :( enable developers to model your own custom menus will not take effect)

Receiving a response text message 2

  When ordinary users micro-channel message to the public accounts, micro-letters POST XML data server message packets to fill out the developer's URL.

xml data format of a text message is as follows:

<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>
</xml>

 

Parameters explanation:

parameter description
ToUserName Developers Micro Signal
FromUserName Sender account (the OpenID a)
CreateTime Message creation time (integer)
MsgType Message type, text to text
Content Text message content
MsgId Message id, 64-bit integer

 

(1) establishing TextMessage entity class corresponding to the background:

package cn.qlq.bean.weixin;

public class TextMessage {

    /**
     * Developers Micro Signal
     */
    private String ToUserName;

    /**
     * Sender account (the OpenID a)
     * / 
    Private String FromUserName;

    /**
     * Message creation time (integer)
     */
    private long CreateTime;

    /**
     * text
     */
    private String MsgType;

    /**
     * Text message content
     */
    private String Content;

    /**
     * Message id, 64-bit integer
     */
    private String MsgId;

    @Override
    public String toString() {
        return "TextMessage{" + "ToUserName='" + ToUserName + '\'' + ", FromUserName='" + FromUserName + '\''
                + ", CreateTime=" + CreateTime + ", MsgType='" + MsgType + '\'' + ", Content='" + Content + '\''
                + ", MsgId='" + MsgId + '\'' + '}';
    }

    public String getToUserName() {
        return ToUserName;
    }

    public void setToUserName(String toUserName) {
        ToUserName = toUserName;
    }

    public String getFromUserName() {
        return FromUserName;
    }

    public  void setFromUserName (String fromUserName) {
        FromUserName = fromUserName;
    }

    public long getCreateTime() {
        return CreateTime;
    }

    public void setCreateTime(long createTime) {
        CreateTime = createTime;
    }

    public String getMsgType() {
        return MsgType;
    }

    public void setMsgType(String msgType) {
        MsgType = msgType;
    }

    public String getContent() {
        return Content;
    }

    public void setContent(String content) {
        Content = content;
    }

    public String getMsgId() {
        return MsgId;
    }

    public void setMsgId(String msgId) {
        MsgId = msgId;
    }

}

 

(2) preparation of tools to achieve xml (xml received data) are converted into the transfer map and TextMessage object xml (xml response data format)

pom added:

        <!--微信转换XML所需包 -->
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.10</version>
        </dependency>

 

Tools:

package cn.qlq.utils.weixin;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;

import cn.qlq.bean.weixin.TextMessage;

public  class MessageUtils {

    /**
     * Xml data transfer map
     *
     * @param request
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException {
        Map<String, String> map = new HashMap<>();
        SAXReader reader = new SAXReader();

        InputStream inputStream = request.getInputStream();
        Document document = reader.read(inputStream);

        Element root = document.getRootElement ();
        List<Element> list = root.elements();

        for (Element element : list) {
            map.put(element.getName(), element.getText());
        }

        inputStream.close();
        return map;
    }

    /**
     * To convert the text message object into xml
     *
     * @param textMessage
     * @return
     */
    public static String textMessageToXml(TextMessage textMessage) {
        XStream the XStream = new new the XStream ();
         // replace the root element into xml xml 
        xStream.alias ( "xml" , textMessage.getClass ());
         return xStream.toXML (textMessage);
    }
}

 

(3) receive messages and response messages rewriting Controller

package cn.qlq.controller.weixin;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import cn.qlq.bean.weixin.TextMessage;
import cn.qlq.controller.UserController;
import cn.qlq.utils.weixin.MessageUtils;
import cn.qlq.utils.weixin.WeixinCheckUtils;

@Controller
@RequestMapping("weixin")
public class WeixinController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @RequestMapping(value = "index", method = { RequestMethod.GET, RequestMethod.POST })
    public void index(HttpServletRequest request, HttpServletResponse response) throws IOException {

        // the request, the response code are set to UTF-8 (Chinese prevent distortion) 
        Request.setCharacterEncoding ( "UTF-8"); // time WeChat server POST message using a UTF-8 encoding, but also when receiving with the same code, otherwise the Chinese will be garbled; 
        response.setCharacterEncoding ( "UTF-8"); // in the response message (reply message to the user), will also be encoding is set to UTF-8, the principle above; 

        String Method, = request.getMethod () toLowerCase ().;
        logger.info("method: {}", method);

        // verify that the request is a micro-channel 
        IF ( "GET" .equals (Method)) {
            doGet(request, response);
            return;
        }

        // the POST request message received, and the customer response to the message 
        doPost (request, response);
    }

    /**
     * Post after receiving a request message for message processing and message return
     * 
     * @param request
     * @param response
     * @throws IOException
     */
    private void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter out = response.getWriter();
        try {
            Map<String, String> map = MessageUtils.xmlToMap(request);
            String fromUserName = map.get("FromUserName");
            String toUserName = map.get("ToUserName");
            String msgType = map.get("MsgType");
            String content = map.get("Content");
            logger.info("map: {}", map);

            if (StringUtils.isNotBlank(content)) {
                System.out.println ( "received message:" + content + ", you can search by keyword or do other" );
            }

            String message = null;
            if ("text".equals(msgType)) {
                TextMessage TextMessage = new new TextMessage ();
                 // return message, and so to speak fromuser toUser exchange 
                textMessage.setFromUserName (toUserName);
                textMessage.setToUserName (fromUserName);
                textMessage.setMsgType(msgType);
                textMessage.setCreateTime(new Date().getTime());
                textMessage.setContent ( "message you send is:" + Content);
                logger.info("textMessage: {}", textMessage);

                message = MessageUtils.textMessageToXml(textMessage);
            }

            Out.print (Message); // send the message to the client 
        } the catch (DocumentException E) {
            logger.error("dispose post request error", e);
        } finally {
            out.close();
        }
    }

    /**
     * Get request for authentication micro-channel configuration
     * 
     * @param request
     * @param response
     * @throws IOException
     */
    private void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Signature String = request.getParameter ( "Signature"); // micro-channel encrypted signature 
        String = request.getParameter timestamp ( "timestamp"); // timestamp 
        String = request.getParameter the nonce ( "the nonce"); // random number 
        String = request.getParameter echostr ( "echostr"); // random string 
        logger.info ( "Signature: {}, timestamp: {}, the nonce: {}, echostr: {}" , Signature, timestamp, the nonce, echostr) ;

        if (StringUtils.isNoneBlank(signature, timestamp, nonce)
                && WeixinCheckUtils.checkSignature(signature, timestamp, nonce)) {
            response.getWriter().write(echostr);
        }
    }
}

 

test:

 

Java server log is as follows:

23 is 2019-10-23: 34 is: the INFO 15.625 244 500 --- [-NiO-8088-Exec. 9] cn.qlq.controller.UserController: Method: POST
2019-10-23 23 is: 34 is: the INFO 244 500 --- 15.633 [nio-8088-exec-9 ] cn.qlq.controller.UserController: map: {MsgId = 22503405793257008, fromUserName = o_qAo0u6Snhoc7Z45RfSxYatMWpo, CreateTime = 1571844638, Content = how a, ToUserName = gh_fc4bd5c2fda8, MsgType = text }
received message : how, you can search by keyword or do other
2019-10-23 23: 34: 15.635 INFO 244500 --- [nio-8088-exec-9] cn.qlq.controller.UserController: textMessage: TextMessage { ToUserName = 'o_qAo0u6Snhoc7Z45RfSxYatMWpo', fromUserName = 'gh_fc4bd5c2fda8', CreateTime = 1571844855635, MsgType = 'text', Content = ' message you send is: how', MsgId = 'null'}
2019-10-23 23:34: 20.288 INFO 244500 --- [nio-8088 -exec-3] cn.qlq.controller.UserController: method: post
2019-10-23 23: 34: 20.295 INFO 244500 --- [nio-8088-exec-3] cn.qlq.controller.UserController: map: {MsgId = 22503406289173072, FromUserName = o_qAo0u6Snhoc7Z45RfSxYatMWpo, CreateTime = 1571844642, what Content = meaning, ToUserName = gh_fc4bd5c2fda8, MsgType = text }
received message is: What do you mean, you can search by keyword or do other
2019-10-23 23: 34: 20.296 INFO 244500 --- [nio-8088-exec -3] cn.qlq.controller.UserController: textMessage: TextMessage { ToUserName = 'o_qAo0u6Snhoc7Z45RfSxYatMWpo', fromUserName = 'gh_fc4bd5c2fda8', CreateTime = 1571844860296, MsgType = 'text', Content = ' message you send is: What does it mean' MsgId = 'null'}

 

Guess you like

Origin www.cnblogs.com/qlqwjy/p/11688870.html