Cómo recibir y responder a los mensajes de la API de desarrollo de WeChat, le presentaré a continuación
1. Explicación
* Este ejemplo se desarrolla y demostró de acuerdo con el documento de desarrollo de WeChat: http://mp.weixin.qq.com/wiki/home/index.html Última versión (4/3/2016 5:34:36 pm).
* Plataforma de edición: myeclipse10.7+win32+jdk1.7+tomcat7.0
* Servidor: Alibaba Cloud Windows Server 2008 64bits
* Requisitos de la plataforma: Método de anotación de uso del servlet, Requisitos de la plataforma: J2EE6.0+, JDK6.0+, Tomcat7.0+
* La demostración se centra más en el análisis de API.
* En aras de las instrucciones de prueba, cada caso de prueba es independiente y no depende de otros métodos. No considere mucho el embalaje.
* La demostración se lleva a cabo tanto como sea posible de acuerdo con los requisitos de la API. Propósito: Comprenda cómo se usa el documento y logra el efecto de aprender de un ejemplo y aplicarlo a otros.
* Requisitos de conocimiento: Fundación Sólida Java, Comprensión del conocimiento de la comunicación de la red HTTP, tener suficiente comprensión de Javaweb, Análisis JSON
* Esta parte del código fuente de demostración se dará al final de cada artículo. Después de analizar la API, todos los códigos de origen de demostración se darán en forma de un paquete de código fuente.
* Hora actual: 4/3/2016 5:32:57 PM, esta vez prevalecerá.
2. Documento de gestión original de mensajes de texto (Resumen)
• Dirección del documento: http://mp.weixin.qq.com/wiki/17/f298879f8fb29ab98b2f2971d42552fd.html
• Gestión de mensajes
◦ Reconocer el mensaje de reconozca el mensaje normal
◦ Push de eventos de recepción de mensajes de recepción
◦ Enviar mensajes de mensaje de respuesta-respuesta
◦ Enviar mensajes-cifrado y descifrado cuando la respuesta pasiva
◦ Mensaje de servicio de mensajes de mensajes de envío
◦ Interfaz de masaje de mensajes de envío
◦ Interfaz de mensajes de mensajes de envío de mensajes.
◦ Sesencia de especificaciones de operación de mensajes de plantilla de mensajes
◦ Obtenga la configuración de respuesta automática para la cuenta oficial
3. Comprensión de documentos
• Recibir mensajes
◦ El documento explica esto: cuando un usuario de WeChat ordinario envía un mensaje a una cuenta pública, el servidor WeChat empaquetará los datos XML del mensaje de publicación a la URL llena por el desarrollador.
◦ Entenden: el servidor WeChat devuelve el mensaje enviado por el usuario a REQ en forma de una transmisión posterior. Cuando queremos que el usuario envíe el mensaje, podemos obtenerlo a través de req.getInputStream (). Por supuesto, podemos realizar el análisis necesario basado en el formato XML del mensaje de retorno en el documento.
◦
lograr:
/** En esta parte, obtenemos la información enviada por el usuario y la analizamos en <k, v> para la pantalla* /// analizar la información enviada por el usuario. InputStream es = req.getInputStream (); // Obtenga la transmisión de solicitud // almacene el resultado analizado en mapas hashmap <string, string> map = new Hashmap <String, String> (); // Parse XML, Parse el resultado de retorno obtenido en la información de texto que se usamos a Saxreader lector = nuevo Saxreader (); // tercero Party xml] documento documento = null; try {document = lector.read (is);} catch (documentException e1) {// tODO Auto Generated Catch Bloque e1.printstacktrace ();} // get xml elemento root root = document.getrooTelement (); // Obtenga todos los indes de los niños de la lista de elementos root <emana> root.elements (); for (elemento e: elementlist) map.put (e.getName (), e.gettext ()); // Test Outtut Set <string> keySet = map.KeySet (); // Después de que la salida de prueba se analiza, la información enviada por el usuario es enviada por el sistema de usuario.out.println (etiqueta + ": Comience a analizar la información enviada por el usuario");; for (clave de cadena: keySet) {system.out.println (key + ":" + map.get (key));} system.out.println (etiqueta + ": finalizar para analizar la información enviada por el usuario"); • Enviar un mensaje
◦ El documento explica esto: cuando un usuario envía un mensaje a la cuenta oficial (o cuando un evento es presionado por una operación de usuario específica), se generará una solicitud posterior. El desarrollador puede devolver una estructura XML específica en el paquete de respuesta (obtener) para responder al mensaje (ahora admite texto de respuesta, imágenes, imágenes, texto, voz, video y música). Hablando estrictamente, enviar mensajes de respuesta pasiva no es en realidad una interfaz, sino una respuesta a un mensaje enviado a un servidor WeChat.
◦ Entenden: cuando un usuario envía una solicitud, se generará una solicitud de publicación y podemos responder a los mensajes a través de Repone. Sin embargo, el contenido de respuesta tiene requisitos de formato estrictos. Solo cuando se cumplan los requisitos de formato, el servidor WeChat procesará y lo devolverá al usuario. Al ver el módulo de "administración de mensajes" del documento, podemos ver que hay varios mensajes en WeChat, y cada tipo de mensaje tiene sus propios requisitos de formato específicos. Debemos seguir los requisitos para devolver la información específica al usuario normalmente. Intentamos responder a los usuarios con información de texto y mensajes gráficos en el formato requerido del documento. Enfoque: Construya los parámetros requeridos de acuerdo con los requisitos del documento. Nota especial: los parámetros son sensibles a la caja.
◦ Implemento 1 repleto a los mensajes de texto normales:
// Ejemplo 1: Envíe un mensaje de texto normal, verifique el formato XML del documento sobre el "mensaje de texto de respuesta" // Paso 1: Construya los parámetros requeridos TextMsg TextMsg = new Textmsg (); TextMsg.setTousername (map.get ("fromUsername"); // Enviar y recibir el mensaje "usuario" solo el opuesto textmsg.setFromUsername (map.get ("tousername")); textmsg.setCreateTime (new date (). getTime ()); // Message Creation Time (Integer) TextmSg.SetMsgType ("Text"); // Text Tipo TextmSg.SetContent ("Estoy respondiendo al usuario"); // // El segundo paso es Convertir la información de construcción de la construcción de la construcción de la construcción de la construcción de la construcción del usuario "). xml format recognized by WeChat [Baidu: xstream bean to xml]XStream xStream = new XStream();xStream.alias("xml", textMsg.getClass());String textMsg2Xml = xStream.toXML(textMsg);System.out.println(textMsg2Xml);// // The third step is to send the xml Formatear información al servidor WeChat, y el servidor la reenvía al usuario printWriter printWriter = resp.getwriter (); printwriter.print (textmsg2xml); ◦ Implemento 2-respuesta al mensaje de texto:
// Ejemplo 2, envíe mensajes gráficos y de texto. Consulte el formato XML del documento "Responder al mensaje de texto" // Paso 1: Construya los parámetros requeridos por las respuestas a la lista de mensajes de texto <Atículo> Artículos = new ArrayList <Artículo> (); Artículo a = nuevo artículo (); A.Settitle ("i am the peting"); a.setpicurl ("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg"); // Esta dirección es una dirección de imagen válida a.set -description ("Soy la descripción de la image");articles.add(a);PicAndTextMsg picAndTextMsg = new PicAndTextMsg();picAndTextMsg.setToUserName(map.get("FromUserName"));// Send and receive the message "User" just the opposite picAndTextMsg.setFromUserName(map.get("ToUserName"));picAndTextMsg.setCreateTime(new Date (). Gettime ()); // tiempo de creación de mensajes (entero) picandTextMsg.setmsgtype ("noticias"); // Tipo gráfico y de texto Mensaje PicandTextMsg.SetArticleCount (1); picandTextMsg.SetArticles (artículos); // El segundo paso es convertir la información construida en el formato XML reconocido por wechat [baidu: xstream bean a xml] xstream xstream = new xStream (); xStream.alias ("xml", picandTextMsg.getClass ()); xStream.Alals ("item (", ",", "))). picandTextMsg2xml = xstream.toxml (picandTextMsg); system.out.println (picandTextMsg2xml); // El tercer paso es enviar la información de formato de XML al servidor WeChat, y el servidor lo reenvía al escritor de usuarios Printwriter = resp.getwriter (); PrintWriter.Print (Print (PRINT (PRINT (PRINT (PRINT (PRINT (PRINT (PRISTE (PIECHA Todos los códigos fuente de operación en esta parte se pueden usar directamente
• CoreServlet.java (incluido el acceso al servidor, recibir mensajes de envío del usuario, responder a mensajes de texto comunes y responder a mensajes gráficos. Jares de terceros: DOM4J, XStream)
paquete com.gist.servlet; import java.io.ioException; import java.io.inputstream; import java.io.printwriter; import java.security.messagedigest; import java.security.nosuchalgorithmexception; import java.util.arraylist; import java.utililia. java.util.hashmap; import java.util.list; import java.util.map; import java.util.set; import javax.servlet.servletException; import javax.servlet.annotation.webservlet; import javax.servlet.http.httpservlet; import; javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; import og.dom4j.document; import og.dom4j.documentException; import org.dom4j.emement; import org.dom4j.io.saxreader; import.g.GeS.Gean. com.gist.bean.picandTextmsg; import com.thoughtworks.xstream.xstream;/** * @author gao yuan </n> correo electrónico: [email protected] </n> blog http://blog.csdn.net/wgyscsf </> * ulistren */@Webservlet ("/coreServlet") public class CoreServlet extiende httpservlet {private static final long SerialVersionUid = 1l; Cadena etiqueta = "coreServlet"; / * * Paso 2: Verifique la validez de la dirección del servidor después de que el desarrollador envíe la información, el servidor WeChat enviará una solicitud GET a la URL de la dirección del servidor completado. * La solicitud GET tiene cuatro parámetros: firma, timestamp, nonce, ecostr * El desarrollador verifica la solicitud al verificar la firma (hay un método de verificación a continuación). Si confirma que la solicitud GET es del servidor WeChat, devuelva el contenido del parámetro ECHOSTR tal como está. *, el acceso entrará en vigencia y se convertirá en un desarrollador con éxito, de lo contrario el acceso fallará. * * El proceso de cifrado/verificación es el siguiente: 1. Orden de diccionario de clasificación de token, Timestamp y Nonce 2. * Empalme las tres cadenas de parámetros en una cadena para el cifrado SHA1 3. Las cadenas después del desarrollador obtienen la cadena cifrada se pueden comparar con la firma, identificando que la solicitud proviene de WeChat */ * * * * Diccionario (lexicógico * orden de clasificación de la firma es una firma para la firma para que el método de clasificación de la clasificación es un método de clasificación al azar (lexicótica * para la firma de la firma para la firma de la firma para el método de clasificación * Variables para formar secuencias. El método es formar una secuencia de pequeño a grande en orden alfabético o en el orden de números pequeños y grandes. */ @Override Protected void doget (httpservletRequest req, httpservletResponse resp) lanza ServletException, ioexception {// establecer la codificación req.setcharacterEncoding ("UTF-8"); resp.setContentType ("html/text; charset = utf-8"); resp.setcharacteriCoding ("utf-8"); // Get Outtre Stream PrintWriter PrintWriter = resp.getwriter (); // Establecer un token global, el desarrollador lo establece él mismo. API explica esto: el desarrollador puede completar el token a voluntad, // utilizado como firma de generación (el token se comparará con el token contenido en la url de la interfaz para verificar la seguridad) String token = "wgyscsf"; // Según la descripción de la API, obtenga los cuatro parámetros anteriores cadena firma = req.getParameter ("firma"); String timestamp = req.getParameter ("timestamp"); Cadena nonce = req.getParameter ("nonce"); String echostr = req.getParameter ("echostr"); // // temp: Impresión temporal, mire la situación del parámetro de retorno // system.out.println (etiqueta + ": firma:" + firma + ", timestamp:" // + timestamp + ", nonce:" + nonce + ", echostr:" + echostr); // Acceso de acuerdo con el "proceso de cifrado/verificación" mencionado por la API. Hay tres pasos en total // Paso 1: Orden de diccionario de clasificación de token, timestamp, nonce tres parámetros cadena [] parms = new String [] {token, timestamp, nonce}; // Pon las cadenas que deben clasificarse en el diccionario en la matriz. Cifrado // emplome la cadena de cadena parmsString = ""; // Tenga en cuenta que no puede = nulo aquí. for (int i = 0; i <parms.length; i ++) {parmsString+= parms [i]; } // cadena de cifrado SHA1 mParms = null; // Resultado cifrado MessageGest digest = null; intente {digest = java.security.messageGest.getInstance ("sha"); } Catch (nosuchalgorithMexception e) {// TODO BLOQUE DE CABTA AUTO GENERADA E.PRINTSTACKTRACE (); } digest.update (parmsString.getBytes ()); byte messageDigest [] = digest.digest (); // Crear HEX String StringBuffer HexString = new StringBuffer (); // Convertir la matriz de bytes en el número hexadecimal para (int i = 0; i <messagedigest.length; i ++) {string shahex = integer.tohexString (messageDigest [i] & 0xff); if (shahex.length () <2) {hexString.append (0); } hexstring.append (Shahex); } mParms = hexString.ToString (); // Resultado de cifrado/ * * Requisitos de la API: Si confirma que la solicitud GET proviene del servidor WeChat, devuelva el contenido del parámetro ECHOSTR tal como está, y el acceso entrará en vigencia y se convertirá en un desarrollador con éxito. De lo contrario, el acceso fallará. *// Paso 3: el desarrollador obtiene la cadena cifrada y puede compararla con la firma para identificar que la solicitud proviene del acceso exitoso de WeChat. // system.out.println (etiqueta + ":" + mparms + "--->" + firma); if (mParms.equals (Signature)) {// System.out.println (tag + ":" + mParms + "---->" + firma); printWriter.Write (ECHOSTR); } else {// Access falló, no es necesario escribir // System.out.println (etiqueta + "Fallado de acceso"); }} / * * Verifique el documento API para enviar y recibir mensajes y presionar básicamente el mismo formato de mensaje. As in the following format: <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> * <Centent> <! [CDATA [esta es una prueba]]> </tent content> * <sgid> 1234567890123456 </sgid> </ xml> Entonces, podemos realizar un procesamiento unificado. * / / * * ¡Primero obtengamos la secuencia de entrada y vemos la información en la secuencia de entrada. Al probar el flujo de impresión, podemos ver que cada vez que el usuario solicita, recibimos una solicitud REQ. El formato de solicitud está en formato XML, que se explica en el documento. * / / * * Tenga en cuenta que req.getInputStream () solo se puede recuperar una vez y solo se puede leer una vez. Si desea leerlo varias veces, debe encontrar otra forma. Para simplificar, * solo obtenemos req.getInputStream () una vez y ya no imprime la información del flujo de salida. Imprima directamente la información analizada. */ @Override Proteged void dopost (httpservletRequest req, httpservletResponse resp) lanza servletException, ioexception {// establecer codificación req.setcharacterEncoding ("UTF-8"); resp.setContentType ("html/text; charset = utf-8"); resp.setcharacteriCoding ("utf-8"); /** En esta parte obtenemos la información enviada por el usuario y la analizamos en <k, v> para display*/ // analizar la información enviada por el usuario inputStream es = req.getInputStream (); // Obtener la transmisión de solicitudes // almacenar los resultados analizados en el mapa hashmap <string> map = new hachmap <string, string,); // analiza XML, analizando el resultado de retorno obtenido XML en la información de texto que se utilizan para saxreader lector = new SaxReader (); // Jar de terceros: DOM4J [Baidu: Saxreader analizando XML] documento = NULL; intente {document = Reader.read (is); } catch (DocumentException e1) {// TODO Auto Generado Bloque E1.PrintStackTrace (); } // Get XML Root Element Element Root = document.getRootElement (); // Obtenga todos los nodos infantiles de la lista de elementos raíz <emememento> elementList = root.elements (); // atraviesa todos los nodos infantiles para (elemento e: elementlist) map.put (e.getName (), e.gettext ()); // Test Outtut Set <String> keySet = map.KeySet (); // Prueba el mensaje de salida enviado por el usuario después del análisis de análisis.out.println (etiqueta + ": comience a analizar la información enviada por el usuario"); for (tecla de cadena: keySet) {system.out.println (key + ":" + map.get (key)); } System.out.println (etiqueta + ": final de analizar la información enviada por el usuario"); / * * En esta parte, intentamos responder información de texto y mensajes gráficos al usuario de acuerdo con el formato requerido del documento. Enfoque: Construya los parámetros requeridos de acuerdo con los requisitos del documento. Nota especial: los parámetros son sensibles a la caja. *// // Ejemplo 1: Envíe un mensaje de texto normal, consulte el formato XML del documento sobre "Mensaje de texto de respuesta" // // Paso 1: Construya los parámetros requeridos de acuerdo con la información de texto de respuesta // TextMsg TextMsg = new TextMsg (); // textmsg.setTouserName (map.get ("fromUsername")); // Enviar y recibir el mensaje "Usuario" exactamente el opuesto // TextmSg.SetFromUsername (map.get ("tousername"); // textmsg.setCreateTime (nueva fecha (). gettime ()); // tiempo de creación de mensajes (entero) // textmsg.setmsgtype ("text"); // text type mensaje // textmsg.setContent ("Soy el servidor responde al usuario"); // // // // // // El segundo paso es convertir la información construida en el formato XML reconocido por WeChat [Baidu: xstream Bean a xml] // xstream xstream = new xstream (); // xstream.alias ("xml", textmsg.getclass ()); // cadena textmsg2xml = xstream.toxml (textmsg); // System.out.println (TextMsg2xml); // // // // // // // El tercer paso es enviar la información de formato del XML al servidor WeChat, y el servidor la reenvía al usuario // printwriter printwriter = resp.getwriter (); // printwriter.print (textmsg2xml); // // Ejemplo 2, envíe mensajes gráficos y de texto. Consulte el documento sobre el formato XML de "Responder al mensaje de texto" // Paso 1: Construya los parámetros requeridos de acuerdo con las respuestas a la lista de mensajes de texto <artículo> Artículos = new ArrayList <Artículo> (); Artículo a = nuevo artículo (); A.Settitle ("Yo soy el título de la imagen"); a.setUrl("www.baidu.com");// This address is after clicking on the picture and jumping a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// This address is a valid image address a.setDescription ("Soy la descripción de la imagen"); Artículo.Add (a); PicandTextMsg picandTextMsg = new PicandTextMsg (); picandTextMsg.setTousername (map.get ("fromUsername")); // Enviar y recibir el mensaje "Usuario" solo el opuesto PICAntTextMsg.SetFromUsername (map.get ("tousername")); picandTextMsg.setCreateTime (nueva fecha (). getTime ()); // Tiempo de creación de mensajes (entero) picandTextMsg.setmsgType ("News"); // Mensaje gráfico PicandTextMsg.SetActicleCount (1); PicandTextMsg.SetArticles (artículos); // El segundo paso es convertir la información construida en el formato XML reconocido por WeChat [Baidu: xstream Bean a xml] xstream xstream = new xStream (); xstream.alias ("xml", picandTextMsg.getClass ()); xstream.alias ("item", a.getClass ()); Cadena picandTextMsg2xml = xstream.toxml (picandTextMsg); System.out.println (picandTextMsg2xml); // El tercer paso es enviar la información de formato del XML al servidor WeChat, y el servidor la reenvía al usuario PrintWriter printWriter = resp.getwriter (); printwriter.print (picAndTextMsg2xml); }}
• testmsg.java (bean de texto de texto normal)
paquete com.gist.bean;/** * @author gao yuan </n> correo electrónico: [email protected] </n> Blog http://blog.csdn.net/wgyscsf </n> * Período de escritura 2016-4 2:09:27 PM */Public Class Texmmsg {String privado Tousername; cadena privada fromUsername; Privado Long Createtime; cadena privada msgtype; @Override public string toString () {return "textmsg [tousername =" + tousername + ", fromUSername =" + fromUsername + ", createTime =" + createTime + ", msgtype =" + msgtype + ", content =" + content + "]"; } Contenido de cadena privada; Public TextMsg (String tousername, string fromUsername, long CreateTime, string msgtype, string content) {super (); Tousername = tousername; FromUsername = fromUsername; CreateTime = CreateTimeMe; Msgtype = msgtype; Contenido = contenido; } public textmsg () {super (); } public String getTousername () {return tousername; } public void setTousEname (string tousername) {tousername = tousername; } public String getFromUsername () {return fromUsername; } public void setFromUsername (string fromUsername) {fromUsername = fromUsername; } public Long 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; }}
• Artículo. Java (Bean de artículo dentro del mensaje de texto)
paquete com.gist.bean;/** * @author gao yuan </n> correo electrónico: [email protected] </n> Blog http://blog.csdn.net/wgyscsf </n> * Período de escritura 2016-4 2:47:08 PM */Artículo de clase pública {Título de cadena privada; @Override public String toString () {return "item [title =" + title + ", descripción =" + descripción + ", picurl =" + picurl + ", url =" + url + "]"; } public String gettitle () {Título de retorno; } public void settitle (título de cadena) {title = title; } public String getDescription () {return Descripción; } public void setDescription (String Descripción) {Descripción = Descripción; } public String getPiCurl () {return picurl; } public void setPiCURL (String picurl) {picurl = picurl; } public String getUrl () {return url; } public void seturl (url de cadena) {url = url; } Descripción de la cadena privada; Picurl de cadena privada; URL de cadena privada;}
• PicandTextMsg.java (Mensaje de texto gráfico Bean)
paquete com.gist.bean; import java.util.list;/** * @author gao yuan </n> correo electrónico: [email protected] </n> Blog http://blog.csdn.net/wgyscsf </n> * período de escritura 2016-4-4 2:47:08 PM */public class Picandtextms. cadena privada fromUsername; Privado Long Createtime; cadena privada msgtype; privado int articlecount; Lista privada <Artículo> Artículos; @Override public string toString () {return "PICAnDTextMsg [tousername =" + tousername + ", fromUSername =" + fromUsername + ", createTime =" + createTime + ", msgtype =" + msgtype + ", articleCount =" + ArticleCount + Articles = " + Articles +"] "; } public String getTousername () {return tousername; } public void setTousEname (string tousername) {tousername = tousername; } public String getFromUsername () {return fromUsername; } public void setFromUsername (string fromUsername) {fromUsername = fromUsername; } public Long Long GetCreateTime () {return CreateTime; } public void setCreateTime (Long CreateTime) {CreateTime = CreateTime; } public String getMsgType () {return msgType; } public void setMsgType (string msgtype) {msgtype = msgtype; } public int getArticLecount () {return articLecount; } public void setTarticlecount (int } Lista pública <At artículo> getArticles () {return artículos; } public void setARTicles (List <Atem> Artículos) {Artículos = Artículos; }}
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.