Antes de usar essa estrutura, é recomendável entender os documentos de desenvolvimento da conta pública do WeChat, mas o uso dessa estrutura sem entender os documentos da conta pública também pode concluir uma conta pública simples do WeChat.
Atualmente compatível com a bota de primavera 1.4+ e a bota de mola 2.x. Todos são convidados a mencionar problemas e contribuições e também convidados a ingressar no grupo para discutir 627254793. Os projetos de código aberto precisam ser compartilhados por todos. Obrigado ~
Link de aplicativo de conta oficial de teste weChat
<!-- 支持1.4.0.RELEASE及以上,包括2.x -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<!-- fastbootWeixin的核心依赖 -->
<dependency>
<groupId>com.mxixm</groupId>
<artifactId>fastboot-weixin</artifactId>
<version>0.6.2</version>
</dependency>
<!-- SpringBoot的web项目,必须 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 暂时只能使用apache的http,后续可加入其它http支持 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
Crie um novo Application Application.Properties ou outros tipos de arquivo de configuração suportados pela Spring Boot no diretório de recursos e adicione configuração:
Código de teste:
package com.mxixm.fastboot.weixin;
import com.mxixm.fastboot.weixin.annotation.WxApplication;
import com.mxixm.fastboot.weixin.annotation.WxAsyncMessage;
import com.mxixm.fastboot.weixin.annotation.WxButton;
import com.mxixm.fastboot.weixin.module.web.WxRequest;
import com.mxixm.fastboot.weixin.module.event.WxEvent;
import com.mxixm.fastboot.weixin.module.message.WxMessage;
import com.mxixm.fastboot.weixin.module.message.WxMessageBody;
import com.mxixm.fastboot.weixin.module.user.WxUser;
import com.mxixm.fastboot.weixin.mvc.annotation.WxController;
import com.mxixm.fastboot.weixin.mvc.annotation.WxEventMapping;
import com.mxixm.fastboot.weixin.mvc.annotation.WxMessageMapping;
import org.springframework.boot.SpringApplication;
@WxApplication
@WxController
public class WxApp {
public static void main(String[] args) throws Exception {
SpringApplication.run(WxApp.class, args);
}
/**
* 定义微信菜单
*/
@WxButton(group = WxButton.Group.LEFT, main = true, name = "左")
public void left() {
}
/**
* 定义微信菜单
*/
@WxButton(group = WxButton.Group.RIGHT, main = true, name = "右")
public void right() {
}
/**
* 定义微信菜单,并接受事件
*/
@WxButton(type = WxButton.Type.CLICK,
group = WxButton.Group.LEFT,
order = WxButton.Order.FIRST,
name = "文本消息")
public String leftFirst(WxRequest wxRequest, WxUser wxUser) {
return "测试文本消息";
}
/**
* 定义微信菜单,并接受事件
*/
@WxButton(type = WxButton.Type.VIEW,
group = WxButton.Group.LEFT,
order = WxButton.Order.SECOND,
url = "http://baidu.com",
name = "点击链接")
@WxAsyncMessage
public WxMessage link() {
return WxMessage.newsBuilder().addItem("测试图文消息", "测试", "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white.png", "http://baidu.com").build();
}
/**
* 接受微信事件
* @param wxRequest
* @param wxUser
*/
@WxEventMapping(type = WxEvent.Type.UNSUBSCRIBE)
public void unsubscribe(WxRequest wxRequest, WxUser wxUser) {
System.out.println(wxUser.getNickName() + "退订了公众号");
}
/**
* 接受用户文本消息,异步返回文本消息
* @param content
* @return the result
*/
@WxMessageMapping(type = WxMessage.Type.TEXT)
@WxAsyncMessage
public String text(WxRequest wxRequest, String content) {
WxSession wxSession = wxRequest.getWxSession();
if (wxSession != null && wxSession.getAttribute("last") != null) {
return "上次收到消息内容为" + wxSession.getAttribute("last");
}
return "收到消息内容为" + content;
}
/**
* 接受用户文本消息,同步返回图文消息
* @param content
* @return the result
*/
@WxMessageMapping(type = WxMessage.Type.TEXT, wildcard = "1*")
public WxMessage message(WxSession wxSession, String content) {
wxSession.setAttribute("last", content);
return WxMessage.newsBuilder()
.addItem(WxMessageBody.News.Item.builder().title(content).description("随便一点")
.picUrl("http://k2.jsqq.net/uploads/allimg/1702/7_170225142233_1.png")
.url("http://baidu.com").build())
.addItem(WxMessageBody.News.Item.builder().title("第二条").description("随便二点")
.picUrl("http://k2.jsqq.net/uploads/allimg/1702/7_170225142233_1.png")
.url("http://baidu.com").build())
.build();
}
/**
* 接受用户文本消息,异步返回文本消息
* @param content
* @return the result
*/
@WxMessageMapping(type = WxMessage.Type.TEXT, wildcard = "2*")
@WxAsyncMessage
public String text2(WxRequestBody.Text text, String content) {
boolean match = text.getContent().equals(content);
return "收到消息内容为" + content + "!结果匹配!" + match;
}
}
Como as contas públicas do WeChat precisam configurar sua própria interface de servidor, você pode usar diretamente os testes locais durante o teste. O uso da penetração da intranet pode permitir que as plataformas públicas do WeChat acessem seu próprio servidor local.
O software pode usar NGrok ou NATAPP. Consulte os documentos oficiais de ambos.
O endereço do URL do nome de domínio gerado após a inicialização pode ser configurado no WX.Callback-URL para autenticação OAuth2. O nome de domínio no URL gerado acima também deve ser configurado no nome de domínio da página de retorno de chamada da autorização.
Preencha o nome de domínio gerado na etapa 4 nas informações de configuração da interface da conta oficial do teste. O token usa o token no arquivo de configuração. Depois de salvar, se nada inesperado acontecer, ele deve ser verificado com sucesso. Se você tiver alguma dúvida, forneça feedback com o tempo.


Depois que o exemplo acima for iniciado, preste atenção à sua conta oficial. No momento, o menu da conta oficial deve ter dois menus principais: esquerda e direita, e há dois submenu à esquerda: mensagem de texto e clique em Link.
Ao clicar no menu de mensagens de texto, você receberá uma mensagem de texto, que é: Mensagem de texto de teste.
Ao clicar no segundo link de clique, você pulará para o Baidu e recebe uma mensagem gráfica com o título da mensagem gráfica de teste.
Ao enviar uma mensagem de texto para a conta oficial, se o conteúdo da mensagem não começar com 1, você receberá uma resposta à conta oficial: "O conteúdo da mensagem é recebido" + o conteúdo enviado.
Envie uma mensagem de texto para a conta oficial. Quando o conteúdo da mensagem começar com 1, você receberá uma resposta à mensagem gráfica e de texto.
Quando um usuário cancela a conta oficial, o apelido do usuário será impresso no System.out + "não inscrito na conta oficial"
Anotação @wxApplication é usada para declarar o aplicativo como um aplicativo do WeChat e começar a usar o SpringApplication. Se você já possui um ambiente de troca, adicione a anotação @enablewxmvc à sua classe @springApplication, o efeito é o mesmo. Você pode ver o código -fonte.
A anotação @wxController é usada para declarar que a classe é um controlador do WeChat. Somente quando essa anotação for declarada ela estará vinculada ao mapa de solicitação do servidor WeChat, caso contrário, a classe será ignorada.
Anotação @wxbutton (grupo = wxbutton.group.left, main = true, nome = "esquerda") é usado para declarar uma caixa de botão. O grupo representa um grupo, com três grupos à esquerda, centro e direita, correspondendo aos três menus de primeiro nível do WeChat. Main é um valor booleano, o que significa se o item de menu é um menu de primeiro nível. Nome é o nome do menu.
Anotação @wxbutton (type = wxbutton.type.click, grupo = wxbutton.group.left, ordem = wxbutton.order.first, name = "mensagem de texto") é usado para declarar o submenu do agrupamento de esquerda. A ordem representa a ordem, aqui está a primeira.
public String LeftFirst (wxRequest wxRequest, wxuser wxUser) {return "Test Text Message"; } Existem três pontos aqui:
@Wxbutton (type = wxbutton.type.view, grupo = wxbutton.group.left, ordem = wxbutton.order.second, url = "http://baidu.com", name = "clique no link") Esta anotação é a mesma que acima e o tipo se torna vista. Para conteúdo específico, você pode consultar a anotação de enumeração ou o documento oficial da conta. Observe que cada tipo de menu tem suas próprias limitações. Consulte a documentação. Se as condições não forem atendidas, ocorrerá uma exceção quando a inicialização for iniciada.
A anotação @wxasyncmessage indica que a mensagem é respondida de forma assíncrona, consulte a mensagem de atendimento ao cliente e nenhum suporte é fornecido para vários serviços ao cliente no momento.
Wxmessage.news.builder (). Na classe WxMessage, existem diferentes classes internas estáticas e seus construtores. Através do construtor, diferentes tipos de mensagens do WeChat podem ser facilmente construídos. Consulte as mensagens passivas de resposta e as mensagens de atendimento ao cliente.
Anotação @wxeventmapping (type = wxEvent.type.unsubscribe) liga o evento de cancelamento de inscrição. Quando um usuário deixa de seguir, a lógica abaixo desta anotação será inserida. Outro ponto a ser observado é que todo o conteúdo da resposta do WXEventMapping será enviado ao usuário de forma assíncrona.
Anotação @wxmessageMapping (type = wxmessage.type.text) significa vincular a mensagem de texto enviada pelo usuário à seguinte lógica do método, public string text (string content) {retornar "a mensagem recebida é" + conteúdo; }. O conteúdo será atribuído automaticamente ao conteúdo de texto enviado pelo usuário.
A anotação @wxmessageMapping (type = wxmessage.type.text, Wildcard = "1*") é a mesma que acima. A diferença é o personagem curinga do curinga. Este caractere curinga suporta conteúdo curinga. Substituindo a lógica curinga inserirá a lógica de execução abaixo.
Perfeitamente integrado à bota de mola. Se você não possui um projeto de trampolim e deseja usar essa estrutura para criar uma conta pública, você pode usar diretamente @WXAPplication para marcar a classe de inicialização. Esta anotação suporta parâmetro: MenuAutocreate, o padrão é verdadeiro. Isso significa que o menu WeChat é criado automaticamente e pode ser definido como falso para desativar o comportamento de criar automaticamente o menu. Se você já possui um projeto de inicialização de primavera e deseja introduzir essa estrutura, basta marcar a anotação @enablewxmvc em qualquer classe de configuração e os parâmetros são os mesmos que acima.
Existem três tipos de mapeamentos suportados:
Nota: A classe que você vincula deve ser declarada como @wxController
Os seguintes tipos de parâmetros são suportados:
Atualmente, a ligação de parâmetros suporta esses tipos. Se houver uma solução melhor que precise ser suportada, você também pode apresentar opiniões e sugestões diretamente, e eu lidarei com elas em tempo hábil.
O valor de retorno suporta os seguintes tipos:
As mensagens assíncronas acima são enviadas usando o WxMessageTemplate, que é explicado abaixo.
Essa estrutura fornece WxMessageTemplate para enviar mensagens e, ao mesmo tempo, fornece suporte a WxMessageProcessor no modelo, que é processar mensagens antes de enviá -las.
Por exemplo, ao retornar as mensagens de maneira síncrona, você precisa escrever o campo de nome do Username, que é o campo TouserName quando a mensagem é enviada. Não há necessidade de permitir que os usuários da estrutura processem esse campo. Este campo é processado no processador WXCommonMessageProcessor. Se você estiver interessado, pode consultar o código -fonte.
Ele também suporta a seguinte conversão: para mensagens do tipo mídia, você pode usar diretamente mediaurl ou mediapath para escrever o caminho do material, e o conversor de mensagens gerencia automaticamente o material através do WXMediaManager para obter o ID do material necessário. (Escreva abaixo sobre WxMediaManager)
Nota: Ao processar mensagens de texto, é recomendável usar o construtor do conteúdo da mensagem correspondente no WXMessage para gerá -las!
Essa estrutura fornece WXMediaManager para gerenciar materiais e também usa o banco de dados incorporado para salvar a correspondência entre materiais e arquivos locais. Embora eu tenha concluído essa parte da função no momento, sempre sinto que há um grande problema. Espero que alguém possa me ajudar a ver e me dar algumas sugestões.
A mídia na mensagem acima é realmente implementada através do gerente de material.
A versão 0.2.0.Alpha otimiza o armazenamento, usando a interface WXMediasTore para gerenciar o armazenamento de mídia, os desenvolvedores podem implementar essa interface por si mesmos e se registrar como o feijão da Spring para substituir o MapDBWXMediastore padrão. Para uso específico de cada interface, consulte MapDBWXMediasTore. Uma implementação baseada em memória também pode ser fornecida aqui para substituir o MAPDB.
Essa estrutura fornece a interface WxTokenStore para armazenar tokens e fornece uma implementação padrão baseada em memória do MemorywxtokenStore. Se você precisar ser distribuído, poderá implementar essa interface por si mesmo e injetar a classe de implementação na primavera como um feijão.
Use a interface wxapiinVokespi e a classe WxInVokerProxyFactory para gerar automaticamente o proxy de chamada da interface do WeChat. Você só precisa declarar métodos e anotações. Por padrão, a interface de chamada HTTPComponent é usada. Amigos interessados podem verificar o código -fonte. Não escrevo bem, por isso, se você tiver sugestões melhores, sinta -se à vontade para apresentá -las.
Ao mesmo tempo, uma análise preliminar do valor de retorno é realizada. Se o código de erro do conteúdo retornado da interface não for 0, ele será lançado como uma exceção. O sistema de exceção é a WxException e suas subclasses.
PS: Você também pode usar esse método para gerar sua própria interface de chamada proxy à vontade. Vou adicionar a documentação no futuro, por isso sou preguiçoso por enquanto. . .
Você pode ligar e desligar o comutador, gerar a estrutura do menu através da anotação @wxbutton e chamar automaticamente a interface para determinar se o menu altera e gerar e atualizar automaticamente o menu.
Ele pode responder corretamente à verificação do token enviada pelo WeChat, que é conveniente e rápida.
O uso dessa estrutura não terá nenhum impacto no próprio mapeamento nativo do SpringMVC, nem ocupará nenhum relacionamento de mapeamento exclusivo (exceto a solicitação de autenticação). No caso dessa estrutura, você pode usar qualquer funções nativas do Springmvc, incluindo solicitações de diretório raiz, e não será ocupado apenas pelo servidor WeChat.
Se você deseja usar um endereço separado como o endereço da chamada da API do WeChat, configure o WX.Path como as informações do caminho, que precisam ser consistentes com o caminho da URL nas informações de configuração da interface no gerenciamento de back -end da conta do WeChat.
Forneça interceptação de autenticação WECHAT OAuth2, preencha o nome de domínio da página de retorno de chamada de autorização do OAuth2, configurando o WX.Callback-Domain, configure wx.mvc.intercept.includEpatterns e wx.mvc.intercept.excludePatterns para confundir o endereço do alvo do the the alvo. Você pode fornecer uma classe de implementação da interface WXOAuth2Callback como um feijão, e esse feijão será automaticamente injetado no WXOAuth2Interceptor e chamado após (WXOAuth2Context após a aprovação da autenticação da Web WeChat. O método do contexto) passa o contexto relacionado ao método do Bean. Você pode obter o contexto wxwebuser neste método e converter o wxwebuser em wxuser através do wxuserManager. Para obter informações detalhadas sobre o relacionamento, consulte: WeChat Web Authorization.
Desde a versão 0.3.6, é fornecida a propriedade alternativa wx.callback-url de wx.callback-domain, que é usado para definir o URL do retorno de chamada, incluindo o nome de domínio e o tipo de protocolo de retorno de chamada. Existem mais tipos de protocolo que o WX.Callback Domain, use esta configuração para substituir a configuração do domínio de retorno de chamada.
Função adicional 1: Exibir tipo WXButton, que determina automaticamente se o URL pertence ao endereço sob o nome de domínio de retorno de chamada autorizado e o lida automaticamente como um URL contendo OAuth2, conforme necessário. O interceptador padrão pode ser usado para realizar a função de obter informações de cliques no URL do menu. Ao mesmo tempo, combinado com a função WX.Callback-URL, ele suporta a configuração de caminhos relativos no menu sem carregar um nome de domínio.
Função adicional 2: determine automaticamente se a URL na mensagem precisa adicionar redirecionamento do OAuth, consulte WxRedirectUtils.
No código, você pode usar o wxjsticketManager para obter o wxjsticket
@Autowired
WxJsTicketManager wxJsTicketManager;
Consulte o método para uso detalhado
Configurar wx.encrypt = true, wx.encodingaeskey = Aeskey definido no fundo da conta oficial, ou seja, habilite a criptografia e o modo de descriptografia de mensagem
Observe que, ao ativar a criptografia e a descriptografia da mensagem, você precisa ativar as permissões JCE Unlimited.
JDK7 Download Endereço: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-wnoad-432124.html
JDK8 Download Endereço: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
Após o download, você pode ver local_policy.jar, us_export_policy.jar e readme.txt. Se o JRE estiver instalado, coloque os dois arquivos JAR no %JRE_HOME % LIB Security Directory para substituir o arquivo original. Se o JDK estiver instalado, você também deverá colocar os dois arquivos JAR no %JDK_HOME % JRE LIB Security Directory para substituir o arquivo original.
Você pode adicionar suporte posterior e usar anotações para definir o atendimento ao cliente da mensagem, semelhante ao @rabbitListener
Um pouco problemático, classificação de usuário
Existe uma boa implementação do agrupamento de usuários ou algo assim? Nenhuma demanda ainda
Como pagamento, etc.
Versão inicial
Otimize a ligação ao parâmetro da mensagem, adicione a ligação do corpo da mensagem especificada, consulte WxRequestbody
Carregue o repositório central maven, gerar javadoc e uma série de normalizações
Junte -se a Apache Copyright, All Delombok
Na última vez em que entrei para os direitos autorais, excluí acidentalmente os comentários do cabeçalho de todos os arquivos. Agora preenchi alguns deles. Afinal, vou adicionar a função de cupom do cartão WeChat e lançar a versão de liberação