1. 前言
写到本文,我们已经完成了验证服务器有效性、验证微信消息合法性、自定义菜单接口调用。本篇给出一个项目的完整实例,便于大家搭建完整开发环境。
2. 构建项目
创建Maven项目,然后编写pom.xml文件,pom.xml文件确定了,Maven项目也就确定了。其实此处可以不用SpringBoot模板来建立SpringBoot项目,因为只要在pom.xml里面配置好了,Maven自动构建一个SpringBoot类型的项目。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>cn.pandabrother</groupId>
<artifactId>wx-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.0.0</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 微信公众号 -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>4.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. 编写配置文件
编写application.yml配置文件,用于给项目提供基本配置信息:
server:
port: 80 #端口
servlet:
context-path: /wx-server
通过该配置文件,我们的项目就会监听80端口的请求,且项目访问的根路径为/wx-server,这与我们在微信后台配置的服务器地址(URL)是一致的。
4. 编写启动类
启动类按照SpringBoot规范写一个即可:
/**
* SpringBoot启动类
*/
@SpringBootApplication
public class WxServerApplication {
public static void main(String[] args) {
SpringApplication.run(WxServerApplication.class, args);
}
}
5. 编写配置类
配置类其实是关键核心,我们需要配置两个关键组件:WxMpDefaultConfigImpl类型的组件用于存储微信公众平台的参数,WxMpService类型的组件用于提供微信公众平台开发响应的服务。
/**
* 微信公众平台配置
*/
@Configuration
public class WxMpConfig {
@Bean
public WxMpDefaultConfigImpl wxMpDefaultConfigImpl() {
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
config.setAppId(""); // 设置微信公众号的appid
config.setSecret(""); // 设置微信公众号的app corpSecret
config.setToken(""); // 设置微信公众号的token
config.setAesKey(""); // 设置微信公众号的EncodingAESKey
return config;
}
@Bean
public WxMpService wxMpService() {
WxMpService wxMpService = new WxMpServiceImpl();// 实际项目中请注意要保持单例,不要在每次请求时构造实例,具体可以参考demo项目
wxMpService.setWxMpConfigStorage(wxMpDefaultConfigImpl());
return wxMpService;
}
}
6. 编写自定义菜单控制器类
我们通过控制器暴露接口,调用接口可以完成自定义菜单的创建、查询、删除功能。
注意该类使用@RestController描述,是为了将返回值序列化为json格式,便于查看。
/**
* 自定义菜单
*/
@RestController
public class MenuController {
@Autowired
private WxMpService wxMpService;
/**
* 获取自定义菜单
*/
@RequestMapping("/menuGet")
public WxMpMenu menuGet() throws WxErrorException {
WxMpMenu wxMpMenu = wxMpService.getMenuService().menuGet();
return wxMpMenu;
}
/**
* 删除自定义菜单
*/
@RequestMapping("/menuDelete")
public boolean menuDelete() throws WxErrorException {
wxMpService.getMenuService().menuDelete();
return true;
}
/**
* 创建自定义菜单
*/
@RequestMapping("/menuCreate")
public boolean menuCreate() throws WxErrorException {
// 菜单
List<WxMenuButton> buttons = new ArrayList<WxMenuButton>();
WxMenuButton btn1 = new WxMenuButton();
btn1.setType("click");
btn1.setName("查询城市");
btn1.setKey("QUERY_CITY");
WxMenuButton btn2 = new WxMenuButton();
btn2.setType("view");
btn2.setName("跳转网页");
btn2.setUrl("http://www.csdn.net");
buttons.add(btn1);
buttons.add(btn2);
// 创建
WxMenu wxMenu = new WxMenu();
wxMenu.setButtons(buttons);
String re= wxMpService.getMenuService().menuCreate(wxMenu);
System.out.println(re);
return true;
}
}
8. 编写接入验证控制器
我们在微信公众平台后台配置的服务器URL配置如下:
所以我们编写控制器类, 监听/checkToken路径的请求。由于参数比较多,我们直接通过HttpServletRequest接收参数。
/**
* 接入验证控制器
*/
@Controller
public class CheckController {
@Autowired
private WxMpService wxMpService;
// 接入验证
@GetMapping("/checkToken")
@ResponseBody
public String checkTokenGet(HttpServletRequest request) {
System.out.println("接入验证");
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
// 消息不合法
return "消息不合法";
}
// 消息合法
return echostr;
}
// 消息合法验证
@PostMapping("/checkToken")
@ResponseBody
public String checkTokenPost(HttpServletRequest request) {
System.out.println("消息合法验证");
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
// 消息不合法
return "消息不合法";
}
// 消息合法则继续处理
return "";
}
}
解释下返回值的问题,此处返回的是字符串,这是根据微信官方的要求返回的。微信接受到返回值后,会根据具体的数据约定再进一步处理。
9. 小结
本篇给出了一个接入的完整示例,后续我们在该项目的基础上陆续完善各项功能即可。