需求
例:一个总校多个分校,一个分校一个公众号,亦对应多个商家
快速开发框架配置已经不满足需求
解决方案
思路:通过微信文档确认验证信息以token为准一验证,模板消息等只需验证token
故将token与商家appid以redis的key,value保存,以达到多配制效果
技术需求:springboot,jpa, redis, jfinal weixin 的 spring boot starter,lombok
数据库关联(略)(以实际情况为准)
application.yml(多配制的公众号token统一设置为一样的,因为后端只有一个)
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/duo?useSSL=false&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai
username: root
password: root
jpa:
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
enable_lazy_load_no_trans: true
show-sql: true
redis:
database: 0
host: ip
port: 6379
password: password
timeout: 3600
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
dream:
weixin:
dev-mode: true
url-patterns: /weixin/**
wx-configs:
- appId: appid
appSecret: appSecret
token: token
wxa-config:
app-id: app-id
app-secret: app-secret
json-type: jackson
微信配置数据库表实体WXConfig(以实际需求为准,设计关联)
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table
@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })
public class WXConfig extends Base implements Serializable,Cloneable{
private String appid;
private String secrit;
private Integer mid;
}
设计返回数据实体WXToken(以实际为准,这里只考虑了成功)
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })
public class WXToken {
private String access_token;
private Integer expires_in;
}
设计微信工具类WXUtil,方便使用(注意学习静态注入)(redis只是简单存储,实际工程应使用目录结构,需根据需求自行设计)(使用缓存因为实际微信公众号获取token接口有每日上限,每个token时限2小时,建议设置缓存有效时间低于此数值)
import cn.kudesoft.duo.entity.WXConfig;
import cn.kudesoft.duo.wx.GetTicket;
import cn.kudesoft.duo.wx.WXTicket;
import cn.kudesoft.duo.wx.WXToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
public class WXUtil {
private static StringRedisTemplate stringRedisTemplate;
@Autowired
public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
WXUtil.stringRedisTemplate = stringRedisTemplate;
}
public static String getAccessToken(WXConfig wxConfig){
String token = stringRedisTemplate.opsForValue().get(wxConfig.getAppid());
if(stringRedisTemplate.hasKey(wxConfig.getAppid())){
System.out.println("已从redis获得token");
System.out.println(token);
return token;
}
System.out.println("已从微信服务器获取token");
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity<String> entity = new HttpEntity<String>(headers);
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+wxConfig.getAppid()+"&secret="+wxConfig.getSecrit();
WXToken wxToken = restTemplate.exchange(url, HttpMethod.GET, entity,WXToken.class).getBody();
token = wxToken.getAccess_token();
stringRedisTemplate.opsForValue().set(wxConfig.getAppid(),token,90, TimeUnit.MINUTES);
System.out.println(token);
return token;
}
}