Este artículo hablará sobre el primer paso en el desarrollo de WeChat, el acceso a la cuenta oficial y la gestión de Access_Token.
1. Acceso a la cuenta oficial de WeChat
En el Manual de Desarrollo de la Cuenta Oficial de WeChat, el contenido sobre la sección de acceso de cuenta oficial se escribe con más detalle. El documento dice que acceder a la cuenta oficial requiere tres pasos, a saber:
De hecho, el paso 3 ya no puede considerarse como el paso de acceder a la cuenta oficial. Sin embargo, después del acceso, los desarrolladores pueden hacer algún desarrollo en función de la interfaz proporcionada por la cuenta oficial de WeChat.
En el paso 1, la configuración del servidor incluye la dirección del servidor (URL), Token y EncodingaEesKey.
La dirección del servidor es la dirección de entrada que proporciona lógica comercial al backend de la cuenta oficial. Actualmente, solo admite el puerto 80. Después de eso, la verificación de acceso y cualquier otra solicitud de operación (como envío de mensajes, administración de menores, gestión de materiales, etc.) deben ingresarse desde esta dirección. La diferencia entre la verificación de acceso y otras solicitudes es que cuando la verificación de acceso es una solicitud GET, y cuando otras veces es una solicitud posterior;
El desarrollador puede completar el token y utilizado como firma para generar (el token se comparará con el token contenido en la URL de la interfaz para verificar la seguridad);
EncodingaEsKey es rellenado manualmente o generado aleatoriamente por el desarrollador y se utilizará como la clave de descifrado cifrada del cuerpo de mensajes. En este ejemplo, todos son mensajes de texto sin formato sin cifrar, y este elemento de configuración no está involucrado.
Paso 2: Verifique la validez de la dirección del servidor. Al hacer clic en el botón "Enviar", el servidor WeChat enviará una solicitud HTTP GET a la dirección del servidor que acaba de completar y llevará cuatro parámetros:
Después de recibir la solicitud, necesitamos hacer los siguientes tres pasos. Si confirmamos que la solicitud GET proviene del servidor WeChat y devuelve el contenido del parámetro ECHOSTR tal como está, el acceso entrará en vigencia, de lo contrario el acceso fallará.
El código puede hablar. La siguiente es una entrada de servicio que definí, en la que el método de verificación se define en el método Doget:
// tokenprivate final string token = "fengzheng"; Doget vacío protegido (HTTPServletRequest Solicitud, respuesta httpservletResponse) arroja servletException, ioexception {system.out.println ("inicio de verificación de firma"); Cadena firma = request.getParameter ("firma"); String timestamp = request.getParameter ("Timestamp"); Cadena nonce = request.getParameter ("nonce"); String echostr = request.getParameter ("echostr"); ArrayList <String> array = new ArrayList <String> (); array.add (firma); array.add (marca de tiempo); array.add (nonce); // clasificar cadena sortString = sort (token, timestamp, nonce); // cifrado cadena myToken = descript.sha1 (sortString); // Verifique la firma if (myToken! = Null && myToken! = "" && mytoken.equals (firma)) {System.out.println ("Pases de verificación de firma"); respuesta.getWriter (). println (ecostr); // Si la verificación se produce con éxito ECHOSTR, el servidor WeChat confirmará que la verificación se completa solo después de recibir esta salida. } else {System.out.println ("Falló de verificación de firma"); }} /** * Método de clasificación * @param token * @param timestamp * @param nonce * @return * /public static string sort (string token, string timestamp, string nonce) {string [] strarray = {token, timestamp, nonce}; Matrices.sort (Strarray); StringBuilder sBuilder = new StringBuilder (); for (string str: strarray) {sbuilder.append (str); } return sbuilder.ToString ();}El siguiente código es el método de cifrado:
Descript de clase pública {public static string sha1 (descript de cadena) {try {MessageDigest Digest = MessageDigest .getInstance ("SHA-1"); digest.update (descript.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); } return hexString.ToString (); } Catch (nosuchalgorithMexception e) {E.PrintStackTrace (); } devolver ""; }}El XML mapeado por el servlet es el siguiente:
<Servlet> <Servlet-name> start </servlet-name> <ervlet-class> org.fengzheng.wechat.start </servlet-class> </servlet> <ervlet-mapping> <ervlet-name> start </servlet-name> <url-pattern>/wechat </sl-pattern> </servlet-mapping>
Estoy usando el desarrollo IntelliJ Idea+TomCat7.0 aquí, inicia el proyecto directamente y luego uso NGROK para mapear el puerto local 8080 a la red externa. Ingrese la interfaz de administración oficial de cuentas de WeChat Test, complete la dirección de red externa asignada y el token en la información de configuración de la interfaz.
Haga clic en el botón Enviar y la página solicitará que la configuración sea exitosa.
Irá al IDE y verá la salida de información en la consola.
2. Access_Token Management
Antes de Access_Token, hay dos parámetros importantes que deben ser conocidos. Estos dos parámetros son APPID y APPSECRET. Esto se asigna automáticamente a la cuenta oficial al solicitar una cuenta oficial. Es equivalente a la marca de identidad de la cuenta oficial. Estos dos parámetros son necesarios en muchas interfaces. A continuación, al solicitar Access_Token, se necesitan estos dos parámetros.
Después de acceder a la cuenta oficial, se debe implementar la lógica correspondiente. Al usar la interfaz de cuenta oficial de WeChat, descubrí que muchas solicitudes requieren access_token. Access_token es la credencial única global de la cuenta oficial. Access_Token es necesario al llamar a cada interfaz de la cuenta oficial. Los desarrolladores deben guardarlo correctamente. El almacenamiento de Access_Token debe retener al menos 512 espacio de caracteres. El período de validez de Access_Token es actualmente 2 horas y debe actualizarse regularmente. La adquisición repetida hará que el Access_Token que haya obtenido la última vez no sea válida. Y el límite superior de la interfaz Access_Token se llama todos los días es de 2,000 veces.
Para resumir la explicación anterior, Access_Token debe hacer los siguientes dos puntos:
En este sentido, la solución adoptada aquí es la siguiente: defina un servlet de inicio predeterminado, inicie un hilo en el método de inicio y defina un método de bucle infinito en este proceso para obtener access_token. Cuando la adquisición es exitosa, el proceso duerme durante 7000 segundos, de lo contrario, dormirá durante 3 segundos para continuar obteniendo. El diagrama de flujo es el siguiente:
La siguiente es la idea anterior que se ha implementado en el proyecto, debido a que los datos devueltos están todos en formato JSON, la biblioteca Fastjson de Alibaba se utilizará aquí para proporcionar soporte para la serialización y deserialización de los datos después de construir solicitudes y solicitudes de procesamiento. También se utilizarán otras interfaces posteriores.
1. Defina una entidad de acceso
public class AccessToken {public String getAccessToken () {return accessToken; } public void setAccessToken (string accessToken) {this.accesstoken = accessToken; } public int getExpiresin () {return expiresIn; } public void setExpiresin (int expiresin) {this.expiresin = expiresIn; } cadena privada AccessToken; privado int expirado; } 2. Defina un servlet de inicio predeterminado, inicie un hilo en el método de inicio y establezca este servlet en el autoinscartes predeterminado en Web.xml.
import javax.servlet.servletException; import javax.servlet.annotation.webservlet; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletresponse; importar; import java.io.ioException; @WebServlet (name = "AccessTokenServlet") Public Class AccessTokenServlet extiende httpservlet {public void init () lanza servletException {tokenthread.appid = getInitParameter ("appid"); // Obtenga los parámetros iniciales de Servlet AppID y AppSecret tokenthread.appSecret = getInitParameter ("AppSecret"); System.out.println ("Appid:"+tokenthread.appid); System.out.println ("AppSecret:"+tokenthread.appSecret); nuevo hilo (nuevo tokenthread ()). start (); // Inicie el proceso} protegido void dopost (httpservletRequest solicitud, httpServletResponse) lanza ServletException, ioexception {} protegido void doget (httpservletRequest solicitud, respuesta httpservletreponse) tira servletException, ioexception {}}}}}}}}}}}}}}}}}}}}} Establecer Servlet AutoStart en Web.xml y Establecer parámetros de inicialización AppID y AppSecret
<Servlet> <Servlet-name> initaccesstokenServlet </servlet-name> <ervlet-class> org.fengzheng.wechat.accesstoken.accesstokenservlet </servlet-class> </init-param> <amamname> appid </param-value> su appid </aam-val <amamname> appSecret </amamname> <amam-value> su AppSecret </am-value> </it-param> <carga-on-startup> 0 </load-on-startup> </servlet>
3. Defina la clase de subprocesos, llame a Access_Token en esta clase para obtener la interfaz y abstraga los datos resultantes a una entidad estática para su uso en otros lugares. La dirección de la interfaz es https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=appsecret, donde Grant_type se escribe fijamente como client_credential. Esta solicitud es una solicitud HTTPS Get, y el formato de datos devuelto es {"access_token": "access_token", "expires_in": 7200}.
La implementación de la clase de proceso es la siguiente:
import com.alibaba.fastjson.json; import com.alibaba.fastjson.jsonObject; import org.fengzheng.wechat.common.networkhelper; clase pública implementa runnable {public static string appid = ""; Public static string appSecret = ""; <br> // Tenga en cuenta que es estática public static accesstoken accesstoken = null; public void run () {while (true) {try {accessToken = this.getAccessToken (); if (null! = accessToken) {System.out.println (accesstoken.getAccessToken ()); Thread.sleep (7000 * 1000); // consigue access_token a dormir durante 7000 segundos} else {hilt.sleep (1000*3); // El access_token obtenido es un sueño vacío durante 3 segundos}} Catch (Exception e) {System.out.println ("La excepción ocurre:"+E.getMessage ()); E.PrintStackTrace (); intente {Thread.sleep (1000*10); // La excepción ocurre para dormir por 1 segundo} Catch (Exception e1) {}}}}}/** * get access_token * @return */private accesstoken getaccesstoken () {networkHelper nethelper = new NetworkHelper (); String url = string.format ("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%up", this.appid, this.appsecret); String result = nethelper.gethttpsResponse (url, ""); System.out.println (resultado); //Response.getWriter().println(Result); JsonObject json = json.parseObject (resultado); AccessToken Token = new AccessToken (); token.setaccessToken (json.getString ("access_token")); token.setExpiresin (json.getInteger ("expires_in")); token de regreso; }}El método GethtTPSResponse en NetworkHelper solicita una dirección HTTPS, el parámetro RequestMethod es la cadena "Get" o "Post", y el valor predeterminado es el método GET.
La implementación es la siguiente:
public String gethttpSResponse (String hsurl, string requestMethod) {url url; InputStream es = nulo; Cadena resultData = ""; intente {url = new url (hsurl); Httpsurlconnection con = (httpsurlconnection) url.openconnection (); TrustManager [] tm = {xtm}; SslContext ctx = sslContext.getInstance ("tls"); ctx.init (nulo, tm, nulo); con.setsslsocketFactory (ctx.getSocketFactory ()); con.sethostNameverifier (nuevo hostnameverifier () {@Override public boolean Verify (string arg0, sslsession arg1) {return true;}}); con.setDoInput (verdadero); // Permitir transmisiones de entrada, es decir, descargas,/en Android, este elemento debe establecerse en falso con.setDooutput (falso); // permitir transmisiones de salida, es decir, carga con.setUsecaches (falso); // No use Buffering if (null! = RequestMethod &&! RequestMethod.equals ("")) {con.setRequestMethod (requestMethod); // use el método especificado} else {con.setRequestMethod ("get"); // use la solicitud get} IS = con.getInputStream (); // Obtenga el flujo de entrada, y luego el enlace está realmente establecido. InputStreamReader isr = new InputStreamReader (is); BufferedReader BufferReader = new BufferedReader (ISR); String inputline = ""; while ((inputline = bufferReader.readline ())! = null) {resultData + = inputline + "/n"; } System.out.println (resultData); Certificado [] certs = con.getServerCertificates (); int certnum = 1; para (certificado Cert: certs) {x509Certificate xcert = (x509Certificate) cert; }} catch (Exception e) {E.PrintStackTrace (); } return denteData; } X509TrustManager xtm = new X509TrustManager () {@Override public x509Certificate [] getACceptedIssuers () {// TODO Método Generado Autorgenerado Trasto de retorno NULL; } @Override public void checkServerTrusted (x509Certificate [] arg0, string arg1) lanza certificateException {// TODO Método Generado automático stub} @Override public void checkClientTrusted (x509Certificate [] arg0, string arg1) tira certificadoxception {// ado-geverated método stub stub stub stub stub stub};En este punto, después de implementar el código, el proyecto se implementa y la salida de la consola es la siguiente:
Para ver el efecto, puede establecer el tiempo de sueño un poco más corto, como obtenerlo una vez en 30 segundos, y luego emitir Access_Token. Hagamos una página de prueba JSP y establezcamos el tiempo de sueño en 30 segundos. De esta manera, después de 30 segundos, puede ver los cambios. Por cierto, cómo obtener access_token en otros lugares
< %@ page contentType = "text/html; charset = utf-8" lenguaje = "java" %> < %@ page import = "org.fengzheng.wechat.accesstoken.tokenthread" %> <html> <bead> <title> </title> <bead> <body> Access_token es: <%= Tokenthread.accesstoken.getAccessToken ()%> </body> </html>
De esta manera, navegue por esta página en el navegador, y el efecto de visualización es el siguiente:
Actualizado después de 30 segundos, este valor cambió:
Este artículo se ha compilado en "Resumen del tutorial de desarrollo de WeChat Android", y el "Tutorial de Desarrollo Java WeChat" dan la bienvenida a todos a aprender y leer.
Lo anterior se trata de este artículo. Espero que sea útil para todos desarrollar una cuenta oficial de Java WeChat.