1.首先得确定我们自己申请得是服务号还是微信号,那么就得区分服务号与订阅号的区别,服务号是需要企业才能申请,是需要微信认证的,每年需要缴纳300块钱左右;一般我们个人申请得是订阅号,订阅号可以实现得接口很少;
查看自己的公众号是否是服务号
所以你的订阅号是不能开发的,就不要走这个弯路了,那么确又想开发怎么办,微信还给我们提供了一个测试号的功能
2.测试号:这个测试号已经基本可以满足大部分的开发了(微信支付实现不了,尴尬)
通过以上两图进入管理测试号页面,也可以直接点击该链接
3.进行到这里你需要有一个属于你自己的域名(如果你已经有域名了,请直接跳到第四步),域名的用处是什么呢?简单来说就是保护你的IP与端口的,一般我们访问本地的时候都会是localhost:8080或者是192.168.0.1:8080这样的,有了域名后我们就可以使用域名来代替。我是用natapp申请的域名,链接,进入后需要下载客户端,下载到本地某个文件夹记住即可,然后需要注册购买等等(我是购买了最便宜的那个,隧道和域名都需要购买,我花了12),就不多说了。最后得到如下页面
关于隧道的配置非常重要,提供一个参考
打开你刚刚下载的文件
在图上位置输入cmd回车,进入命令行,输入命令natapp -authtoken=xxx等号后边的xxx是你的natapp中的你的authtoken值
回车后
4.上边的完成后就可以进行接下来的工作了
废话不多说直接上代码:
代码1:
//yml文件中配置你的id和secret
wechat:
mpAppId: wxb6513902370455f1
mpAppSecret: 07fec0c3d6e123464e9832cfd4937800
@Data
@Component
@ConfigurationProperties(prefix = "wechat")
public class WeChatAccountConfig {
private String mpAppId;
private String mpAppSecret;
}
//需要导入微信的jar包
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>3.5.9.B</version>
</dependency>
@Component
public class WeChatMpConfig {
@Autowired
private WeChatAccountConfig weChatAccountConfig;
@Bean
public WxMpService wxMpService(){
WxMpService wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
return wxMpService;
}
@Bean
public WxMpConfigStorage wxMpConfigStorage(){
WxMpDefaultConfigImpl wxMpDefaultConfig = new WxMpDefaultConfigImpl();
//使用配置好的id与secret
wxMpDefaultConfig.setAppId(weChatAccountConfig.getMpAppId());
wxMpDefaultConfig.setSecret(weChatAccountConfig.getMpAppSecret());
return wxMpDefaultConfig;
}
}
代码2:url使用的是你的刚申请的“域名+路径”的方式
//yml文件中配置的根路径,可以不配置,随意
server:
servlet:
context-path: /sell
@Controller
@RequestMapping("/wechat")
@Slf4j
public class WeCharController {
@Autowired
private WxMpService wxMpService;
***//该方法是用来验证token的***
@ResponseBody
@RequestMapping("/checkToken")
public void checkToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
Enumeration pNames = request.getParameterNames();
while (pNames.hasMoreElements()) {
String name = (String) pNames.nextElement();
String value = request.getParameter(name);
// out.print(name + "=" + value);
String log = "name =" + name + " value =" + value;
}
System.out.println("========WechatControllertets========= ");
String signature = request.getParameter("signature");/// 微信加密签名
String timestamp = request.getParameter("timestamp");/// 时间戳
String nonce = request.getParameter("nonce"); /// 随机数
String echostr = request.getParameter("echostr"); // 随机字符串
PrintWriter out = response.getWriter();
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
System.out.println("校验成功!!!!!!!!!!!!!");
out.print(echostr); //告诉浏览器验证成功了
}else{
System.out.println("校验失败!!!!!!");
}
out.close();
}
//该方法是用来微信访问的,这个方法提交的时候可以不写
@RequestMapping("/authorize")
public String authorize(@RequestParam("returnUrl") String returnUrl) throws Exception{
String url = "http://mile.nat300.top/sell/wechat/userInfo";
String redirectUrl = wxMpService.oauth2buildAuthorizationUrl(
url, WxConsts.OAuth2Scope.SNSAPI_USERINFO, URLEncoder.encode(returnUrl));
return "redirect:"+redirectUrl;
}
//该方法是微信跳转页面的,这个方法提交的时候可以不写
@RequestMapping("/userInfo")
public String userInfo(@RequestParam("code") String code,@RequestParam("state") String returnUrl){
WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
try {
wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
} catch (WxErrorException e) {
log.error("微信网页授权",e);
throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(),e.getError().getErrorMsg());
}
String openId = wxMpOAuth2AccessToken.getOpenId();
return "redirect:"+returnUrl+"?openid="+openId;
}
}
//验证token的工具类,就是把从浏览器拿到的token,和下边定义的token用同一种加密方式进行验证
public class SignUtil {
private static String token = "mixile123";// 与微信公众号上的token一致
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
// 将三个参数字符串拼接成一个字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
content = null;
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将字节转换为十六进制字符串
*
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
}
至此如果点击提交应该不会再验证失败而是提交成功了,具体开发的思想,请见开发文档
,如果还是提交失败,提供一个小技巧,打开F2,根据下图的错误信息再去百度查询
最后,如果你的controller也是复制的我的代码,那么你现在用你第四步关注微信公众号的的微信号就可以进行访问了,把该链接(http://你的域名/sell/wechat/authorize?returnUrl=http://www.baidu.com)复制到你的手机客户端,然后打开,就会跳转到百度页面,至此大功告成!!!!!