Este artigo falará sobre a primeira etapa do desenvolvimento do WeChat, o acesso à conta oficial e a administração de access_token.
1. Acesso à conta oficial do WeChat
No manual de desenvolvimento de contas oficiais do WeChat, o conteúdo sobre a seção de acesso oficial à conta é escrito com mais detalhes. O documento diz que o acesso à conta oficial requer três etapas, a saber:
De fato, a etapa 3 não pode mais ser considerada como a etapa de acessar a conta oficial. No entanto, após o acesso, os desenvolvedores podem fazer algum desenvolvimento com base na interface fornecida pela conta oficial do WeChat.
Na etapa 1, a configuração do servidor inclui o endereço do servidor (URL), token e codingaeskey.
O endereço do servidor é o endereço de entrada que fornece lógica de negócios para o back -end da conta oficial. Atualmente, ele suporta apenas a porta 80. Depois disso, a verificação de acesso e quaisquer outras solicitações de operação (como envio de mensagens, gerenciamento de menus, gerenciamento de materiais etc.) devem ser inseridos a partir deste endereço. A diferença entre a verificação de acesso e outras solicitações é que, quando a verificação de acesso é uma solicitação GET e, quando outras vezes é uma solicitação de postagem;
O token pode ser preenchido pelo desenvolvedor e usado como assinatura para gerar (o token será comparado com o token contido no URL da interface para verificar a segurança);
O codingaeskey é preenchido manualmente ou gerado aleatoriamente pelo desenvolvedor e será usado como a chave de descriptografia criptografada do corpo da mensagem. Neste exemplo, todos são mensagens simples e não criptografadas, e esse item de configuração não está envolvido.
Etapa 2: verifique a validade do endereço do servidor. Ao clicar no botão "Enviar", o servidor WeChat enviará uma solicitação HTTP para o endereço do servidor que você acabou de preencher e transportará quatro parâmetros:
Depois de receber a solicitação, precisamos fazer as três etapas a seguir. Se confirmarmos que a solicitação GET vem do servidor WeChat e retorne o conteúdo do parâmetro ECHOSTR como ele é, o acesso entrará em vigor; caso contrário, o acesso falhará.
O código pode falar. A seguir, é apresentado um servlevt de entrada que eu defini, no qual o método de verificação é definido no método Doget:
// tokenprivate final string token = "fengzheng"; Void protegido Doget (solicitação httpServletRequest, httpServletResponse Response) lança servletexception, ioexception {System.out.println ("Start Signature Verification"); String assinatura = request.getParameter ("assinatura"); String timestamp = request.getParameter ("Timestamp"); String nonce = request.getParameter ("nonce"); String ecostr = request.getParameter ("ECHOSTR"); ArrayList <String> Array = new ArrayList <String> (); Array.add (assinatura); Array.add (Timestamp); Array.add (nonce); // classificando string sortString = classy (token, registro de data e hora, nonce); // Encrypt String myToken = descritt.sha1 (SortString); // Verifique a assinatura if (myToken! = Null && myToken! = "" && mytoken.equals (assinatura)) {System.out.println ("Passes de verificação de assinatura."); resposta.getWriter (). println (ecostr); // Se a verificação for emitida com sucesso ECHOSTR, o servidor WeChat confirmará que a verificação é concluída somente após o recebimento dessa saída. } else {System.out.println ("Verificação da assinatura falhou."); }} /** * Método de classificação * @param token * @param timestamp * @param nonce * @return * /public static string STRY (string token, string timestamp, string nonce) {string [] strarray = {token, timestamp, nonece}; Arrays.sort (Strarray); Stringbuilder sbuilder = new stringbuilder (); para (String str: Strarray) {sbuilder.append (str); } retorna Sbuilder.toString ();}O código a seguir é o método de criptografia:
classe pública Descript {public static string sha1 (string descritor) {try {Messagedigest digers = MessAgedigest .getInstance ("sha-1"); Digest.Update (descript.getBytes ()); byte Messagedigest [] = DIGEST.Digest (); // Crie String Hex StringBuffer hexstring = new StringBuffer (); // Converta a matriz de bytes em número hexadecimal para (int i = 0; i <Messagedigest.Length; i ++) {String Shahex = Integer.ToHexString (Messagedigest [i] e 0xff); if (shahex.length () <2) {hexstring.append (0); } hexstring.append (shahex); } retornar hexstring.toString (); } catch (nosuchalgorithMexception e) {e.printStackTrace (); } retornar ""; }}O XML mapeado pelo servlet é o seguinte:
<Vertlet> <Verlet-name> Start </servlet-name> <Servlet-class> org.fengzheng.wechat.start </servlet-class> </servlet> <Vertlet-Mapping> </irl-name> start </irvlet-name> <url-Pattern>/wechat </url-tattern>
Estou usando o desenvolvimento Intellij Idea+TomCat7.0 aqui, inicie o projeto diretamente e use o NGROK para mapear a porta local 8080 para a rede externa. Digite a interface de gerenciamento de contas oficiais do WeChat Test, preencha o endereço de rede externa mapeado e o token nas informações de configuração da interface.
Clique no botão Enviar e a página solicitará que a configuração seja bem -sucedida.
Você irá ao IDE e verá a saída de informações no console
2. Access_Token Management
Antes do Access_Token, existem dois parâmetros importantes que precisam ser conhecidos. Esses dois parâmetros são Appid e AppSecret. Isso é atribuído automaticamente à conta oficial ao solicitar uma conta oficial. É equivalente à marca de identidade da conta oficial. Esses dois parâmetros são necessários em muitas interfaces. Em seguida, ao solicitar access_token, esses dois parâmetros são necessários.
Depois que a conta oficial é acessada com sucesso, a lógica correspondente deve ser implementada. Ao usar a interface da conta oficial do WeChat, descobri que muitas solicitações exigem access_token. Access_Token é a credencial exclusiva global da conta oficial. Access_Token é necessário ao ligar para cada interface da conta oficial. Os desenvolvedores precisam salvá -lo corretamente. O armazenamento de access_token deve reter pelo menos 512 espaço de caracteres. O período de validade do Access_Token é atualmente 2 horas e precisa ser atualizado regularmente. Aquisição repetida fará com que o Access_Token obteve da última vez que seja inválido. E o limite superior da interface access_token é chamado todos os dias é 2.000 vezes.
Para resumir a explicação acima, o Access_Token precisa fazer os dois pontos a seguir:
Nesse sentido, a solução adotada aqui é a seguinte: Defina um servlet de inicialização padrão, inicie um thread no método init e defina um método de loop infinito nesse processo para obter access_token. Quando a aquisição é bem -sucedida, o processo dorme por 7000 segundos, caso contrário, dormirá por 3 segundos para continuar a obter. O fluxograma é o seguinte:
A seguir, a ideia acima foi implementada no projeto, porque os dados retornados estão todos no formato JSON, a Biblioteca Fastjson da Alibaba será usada aqui para fornecer suporte à serialização e deseralização de dados após a construção de solicitações e solicitações de processamento. Outras interfaces subsequentes também serão usadas.
1. Defina uma entidade de acesso ACCESSTOKE
public class AccessToken {public String getAccessToken () {return AccessToken; } public void setAccessToken (string accessToken) {this.acccessToken = accessToken; } public int getExpiresin () {return expira; } public void setexpiresin (int expiresin) {this.expiresin = expiresin; } private String accessToken; Private Int expira; } 2. Defina um servlet de inicialização padrão, inicie um thread no método init e defina este servlet como o iniciante em 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;import java.io.ioException; @webServlet (name = "accessTokenservlet") classe public AccessTokenservlet estende httpServlet {public void init () lança servletexception {tokenthread.appid = getinitParameter ("appid"); // Obtenha os parâmetros iniciais do servlet Appid e AppSecret tokenthread.appSecret = getinitParameter ("AppSecret"); System.out.println ("Appid:"+tokenthread.appid); System.out.println ("appSecret:"+tokenthread.appsecret); novo thread (novo tokenthread ()). start (); // Iniciar o processo} Protegido void DoPost (solicitação HttPervletRequest, resposta HTTPERTletResponse) lança servletexception, ioexception {} vazio protegido doget (httpServleTrequest Solicy, httpSerplroPonse) Throws servexception, IoException {{}} Resposta de resposta)) Defina o Servlet AutoStart em web.xml e defina parâmetros de inicialização Appid e AppSecret
<Verlet> <Verlet-name> initaccessTokenServlet </servlet-name> <Servlet-class> org.fengzheng.wechat.accesstoken.accesstokenservlet </servlet-class> </-param> <amam-name> Appid </ama Param-name> <aMaram> </-param> <amam-name> Appid <amam-name> AppSecret </amam-name> <amam-value> seu appSecret </amam-value> </irit-param> <adar load-on-startup> 0 </olload-on-startup> </servlet>
3. Defina a classe Thread, ligue para Access_Token nesta classe para obter a interface e abstrair os dados resultantes para uma entidade estática para uso em outros locais. O endereço da interface é https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=appSecret, onde Grant_type é fixado como Client_credential. Esta solicitação é uma solicitação GET HTTPS e o formato de dados retornado é {"Access_Token": "Access_Token", "Expires_in": 7200}.
A implementação da classe de processo é a seguinte:
importar com.alibaba.fastjson.json; importar com.alibaba.fastjson.jsonObject; importar org.fengzheng.wechat.common.networkhelper; classe pública tokenthread implementos runnable {public static string appid = ""; public static string appSecret = ""; <br> // Observe que é estático estático estático accessToken accessToken = null; public void run () {while (true) {try {AccessToken = this.getAccessToken (); if (null! = accessToken) {System.out.println (accessToken.getAccessToken ()); Thread.sleep (7000 * 1000); // Obtenha Access_Token no sono por 7000 segundos} else {thread.sleep (1000*3); // o access_token obtido é o sono vazio por 3 segundos}} Catch (Exceção e) {System.out.println ("Exceção ocorre:"+e.getMessage ()); E.PrintStackTrace (); tente {thread.sleep (1000*10); // A exceção ocorre para dormir por 1 segundo} Catch (Exceção 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=%S", this.appid, this.apsecret); Resultado da string = nethelper.gethttpsResponse (url, ""); System.out.println (resultado); //Response.getWriter().println(result); JsonObject json = json.parseObject (resultado); Token AccessToken = new AccessToken (); token.setAccessToken (json.getString ("access_token")); token.setexpiresin (json.getInteger ("expires_in")); Token de retorno; }}O método GethttPSResponse no NetworkHelper solicita um endereço HTTPS, o parâmetro requestMethod é a string "get" ou "post", e o padrão é o método GET.
A implementação é a seguinte:
public string gethttpsResponse (string hsurl, string requestMethod) {url url; InputStream é = nulo; String resultData = ""; tente {url = novo url (hsurl); HttpsurlConnection con = (httpsurlConnection) url.openconnection (); TrustManager [] tm = {xtm}; SslContext ctx = sslContext.getInstance ("tls"); ctx.init (null, tm, null); Con.SetsSlSocketFactory (ctx.getSocketFactory ()); con.SethostNameVerriFier (new HostNameVerriFier () {@Override public boolean Verify (string arg0, sslSession arg1) {return true;}}); con.setDoinput (true); // Permitir fluxos de entrada, ou seja, downloads,/in Android, este item deve ser definido como false con.SetdoOutput (false); // Permitir fluxos de saída, ou seja, carregam Con.SetUseCaches (false); // não use buffer if (null! = RequestMethod &&! RequestMethod.equals ("")) {con.setRequestMethod (requestMethod); // use o método especificado} else {con.setRequestMethod ("get"); // use get request} is = con.getInputStream (); // Obtenha o fluxo de entrada e, em seguida, o link é realmente estabelecido. InputStreamReader isr = new InputStreamReader (IS); BufferReader bufferReader = new BufferredReader (ISR); String inputline = ""; while ((inputline = bufferReader.readline ())! = null) {resultData + = inputline + "/n"; } System.out.println (resultadoData); Certificado [] certs = con.getServerCertificates (); int certnum = 1; para (certificado certificado: certs) {x509Certificate xCert = (x509Certificate) cert; }} catch (Exceção e) {e.printStackTrace (); } retornar resultData; } X509TrustManager xtm = new x509TrustManager () {@Override public x509Certificate [] getAceceptEdissuers () {// TODO Método Auto-Generated Stub Return NULL; } @Override Public void checkServerTrusted (x509Certificate [] arg0, string arg1) lança certificadoException {// TODO Método Auto-Generado} @Override public void CheckclientTrusted (x509Certificate [] arg0, string arg1) throws {//109Certificate [] arg0, string arg1) throws {//109Certificate [] arg0, string arg1) throws {/uerdo-ingdo;Neste ponto, após a implementação do código, o projeto é implantado e a saída do console é a seguinte:
Para visualizar o efeito, você pode definir o tempo de sono um pouco mais curto, como obtê -lo uma vez em 30 segundos, e depois em saída access_token. Vamos fazer uma página JSP de teste e definir o tempo de sono para 30 segundos. Dessa forma, após 30 segundos, você pode ver as alterações. A propósito, como obter access_token em outros lugares
< %@ página contenttype = "text/html; charset = utf-8" idioma = "java" %> < %@ página import = "org.fengzheng.wechat.accesstoken.tokenthread" %> <html> <head> </title> </head> <body> access_talken é: <%= Tokenthread.accessToken.getAccessToken ()%> </body> </html>
Dessa forma, procure esta página no navegador, e o efeito da exibição é o seguinte:
Atualizado após 30 segundos, esse valor mudou:
Este artigo foi compilado no "Resumo do Tutorial de Desenvolvimento do Android WeChat" e "Java WeChat Development Tutorial Resumo" recebe todos para aprender e ler.
O acima é tudo sobre este artigo. Espero que seja útil que todos desenvolvam uma conta oficial do Java WeChat.