wxJava+springboot+idea 对接详细流程
首先是pom.xml文件的架包这里我只用到了第一个
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-open</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>3.8.0</version>
</dependency>
其他的模板后续完善。目前对接通过第一个模板(weixin-java-mp)
还有application.yml文件(这个文件一定要配置,wxJava开发文档是说的很清楚的,百度已有很多)
#公众号
wx:
mp:
configs:
- appId: wx8a6250c9e94a2919 #(一个公众号的appid)
secret: 0324806d61799a6b7d05e54fbe88ef80 #(公众号的appsecret)
token: CESHITOKEN2020 #(接口配置里的Token值)
aesKey: 111 #(接口配置里的EncodingAESKey值)
# - appId: 2222 #(另一个公众号的appid,以下同上)
# secret: 1111
# token: 111
# aesKey: 111
#小程序
miniapp:
configs:
- appId: 111 #(小程序的appid)
secret: 111 #(小程序的appsecret)
#微信支付
pay:
configs:
- appId: #微信公众号或者小程序等的appid
mchId: #微信支付商户号
mchKey: #微信支付商户密钥
subAppId: #服务商模式下的子商户公众账号ID
subMchId: #服务商模式下的子商户号
keyPath: # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
#微信开放平台
open:
configs:
componentAppId: #
componentSecret: #
componentToken: #
componentAesKey: #
这里也是只用到了wx:mp:configs中第一个配置
其次是我们的配置.java文件,(可能叫配置不正确)
这个文件我这样理解:映射我们application.yml文件中的对应值(其他的包 微信支付,公众平台这些可能一样,还没有去研究)
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* @Author
* @Param
* @CreateDate
**/
@Data
@ConfigurationProperties(prefix = "wx.mp")
public class WxMpProperties {
private List<MpConfig> configs;
public static class MpConfig {
/*
* 设置微信公众号的appid
*/
private String appId;
/*
* 设置微信公众号的app secret
*/
private String secret;
/*
* 设置微信公众号的token
*/
private String token;
/*
* 设置微信公众号的EncodingAESKey
*/
private String aesKey;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getAesKey() {
return aesKey;
}
public void setAesKey(String aesKey) {
this.aesKey = aesKey;
}
}
public List<MpConfig> getConfigs() {
return configs;
}
public void setConfigs(List<MpConfig> configs) {
this.configs = configs;
}
}
还有这个java文件(我的理解是把我们映射的appId这些值传到我们的WxMpServer这个对象中,或者换种说法,就是把我们AppId这些值赋值到我们 weixin-java-mp 包里面去)
import cn.yygzs.modules.wechat.utils.WxMpProperties;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author
* @Param
* @CreateDate
**/
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpServiceConfiguration {
@Autowired
private WxMpProperties properties;
@Bean
public WxMpService wxMpService() {
final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
if (configs == null) {
throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
}
WxMpService service = new WxMpServiceImpl();
Map<String, WxMpConfigStorage> collect = configs.stream().map(a -> {
WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
configStorage.setAppId(a.getAppId());
configStorage.setSecret(a.getSecret());
configStorage.setToken(a.getToken());
configStorage.setAesKey(a.getAesKey());
return configStorage;
}).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o));
service.setMultiConfigStorages(collect);
return service;
}
}
到这里基本上就配置完了,剩下的就是调用,这里以微信公众号网页授权为实例
记住:WxMpService 如下这个文件引用
import cn.yygzs.common.utils.StringUtils;
import cn.yygzs.modules.wechat.utils.WeChatUtils;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 微信对接控制层
* @Author
* @Param
* @CreateDate
**/
@RestController
@RequestMapping(value = "/wechat/weChat")
public class WeChatController {
private static Logger log = LoggerFactory.getLogger(WeChatController.class);
//微信对接
@Autowired
private WxMpService wxService;
/**
* 功能描述:
* 微信公众号认证的方法
* @auther
* @date 2020/6/17 12:09
* @param
* @return
*/
@CrossOrigin
@GetMapping("/authGet")
public String authGet(@RequestParam(name = "signature", required = false) String signature,
@RequestParam(name = "timestamp", required = false) String timestamp,
@RequestParam(name = "nonce", required = false) String nonce,
@RequestParam(name = "echostr", required = false) String echostr) {
log.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature,timestamp, nonce, echostr);
if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
throw new IllegalArgumentException("请求参数非法,请核实!");
}
if (wxService.checkSignature(timestamp, nonce, signature)) {
return echostr;
}
return "非法请求";
}
/**
* 功能描述:
* 封装网页授权地址 替换参数值 构建客户端点击地址
* @auther:
* @date: 2020/6/17 9:37
* @param
* @return
*/
@CrossOrigin
@GetMapping("/getCode")
public String getCode(){
try {
//微信获取到code回调地址
String redirectUrl = WeChatUtils.ACS_ADS_PC+"/wechat/weChat/getOpenId";
//对重定向url进行编码,官方文档要求
String customClickUrl = wxService.oauth2buildAuthorizationUrl(redirectUrl, WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);
//网页授权
log.debug("重定向url:>> " + customClickUrl);
return customClickUrl;
} catch (Exception e) {
log.error("response重定向失败:>>" + e.getMessage());
e.printStackTrace();
}
return "";
}
/**
* 功能描述:
* code换取openId
* @auther:
* @date: 2020/6/17 13:27
* @param:
* @return:
*/
@CrossOrigin
@RequestMapping(value="/getOpenId")
public void getOpenId(String code, String state, HttpServletResponse response){
try {
WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxService.oauth2getAccessToken(code);
String openId = wxMpOAuth2AccessToken.getOpenId();
log.info("微信获取openId回到地址:"+WeChatUtils.ACS_ADS_ME+"/pages/index/index?openId="+openId+"&code="+code);
response.sendRedirect(WeChatUtils.ACS_ADS_ME+"/pages/index/index?openId="+openId+"&code="+code);
} catch (WxErrorException e) {
e.printStackTrace();
throw new RuntimeException("获取openId失败!");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("获取openId回调异常!");
}
}
}
我觉得我得贴一下前端的代码,但是感觉多余,还是贴出来吧。vue做的前端
<template>
<gracePage :customHeader="false">
<view slot="gBody" class="body">
<!-- 底图 -->
<view style="height: 220rpx;margin-bottom: 50rpx; background-image: url(../../static/images/30211588163435_.pic.jpg);background-position:center;"></view>
<!-- 轮播图 -->
<view class="grace-padding-top">
<graceSwiper :swiperItems="swiperItems" :width="700" :height="315" :indicatorActiveWidth="38" @swiperchange="swiperchange"></graceSwiper>
</view>
<!-- 公告 -->
<graceSpeaker :vertical="true" :interval="5000" iconClass="grace-icons icon-gonggao" :msgs="speakerMsgs"></graceSpeaker>
<!-- 底部功能图标 -->
<gracePage :customHeader="false">
<view slot="gBody" class="grace-body">
<view class="grace-icon-classes grace-wrap grace-space-between">
<navigator :url="item.path" :open-type="item.openType" class="grace-ic-item" :style="{ background: item.bgColor }" v-for="(item, index) in classes" :key="index" >
<image :src="item.icon" class="grace-ic-image" mode="widthFix"></image>
<view class="grace-ic-content">
<text class="grace-ic-title grace-white">{{ item.txt }}</text>
<text class="grace-text-small grace-white">{{ item.smallTxt }}</text>
</view>
<image :src="item.icon" class="grace-ic-bg-image" mode="widthFix"></image>
</navigator>
</view>
</view>
</gracePage>
</view>
</gracePage>
</template>
<script>
var _self;
import gracePage from "../../graceUI/components/gracePage.vue";
import graceSwiperCard from "../../graceUI/components/graceSwiperCard.vue";
import graceSpeaker from "../../graceUI/components/graceSpeaker.vue";
import https from '../../static/js/https.js';
export default{
data() {
return {
speakerMsgs : [],
classes: [],
swiperItems : [
]
}
},
onLoad:function(e){
//判断是否授权过
_self = this;
var openId = uni.getStorageSync('openId');
console.log("用户授权openId为:===>>"+openId);
if(openId == undefined || openId==null||openId==''){
//判断是否受过权
if(e.openId!==undefined&&e.openId!=null&&e.openId!=''){
uni.setStorageSync("openId",e.openId);
uni.setStorageSync("code",e.code);
}else{
https.uRequest("/wechat/weChat/getCode","GET",{},function(data){
_self.sendGet(data)
});
}
}
},
methods:{
swiperchange : function(e){
//console.log(e);
},
//让客户点击操作
sendGet: function(url) {
// #ifdef H5
var temp = document.createElement("a");
temp.href = url;
temp.style.display = "none";
document.body.appendChild(temp);
temp.click();
document.body.removeChild(temp);
// #endif
},
//结束
},
components: {
gracePage, graceSwiperCard,graceSpeaker
}
}
</script>
<style>
/* h5 端需要动态增加 44px [ 避开默认的头部导航 ] */
.grace-fixed-top{top:0; line-height:50px; height:50px; text-align:center;}
/* #ifdef H5 */
.grace-fixed-top{top:44px; line-height:50px; height:50px; text-align:center;}
/* #endif */
page{background-image:linear-gradient(to bottom, #3688FF,#5a52ec); background-repeat:no-repeat; background-size:100% 200rpx; background-color:#F6F7F8;}
.body{margin-top:50rpx;}
.grace-ic-item {
width: 210rpx;
height: 158rpx;
font-size: 0;
border-radius: 5px;
position: relative;
margin: 10rpx 0;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
}
.grace-ic-image {
width: 60rpx;
height: 56rpx;
margin-left: 20rpx;
}
.grace-ic-bg-image {
width: 70rpx;
height: 66rpx;
position: absolute;
opacity: 0.1;
right: 6px;
bottom: 6px;
}
.grace-ic-content {
padding: 10rpx 20rpx;
}
.grace-ic-title {
line-height: 40rpx;
font-size: 28rpx;
margin-right: 3px;
}
</style>
结束了,就是这些,拜拜!