Linking

Capturing Life & Tech

  • 主页
  • 随笔
  • 关于我
所有文章 外链

Linking

Capturing Life & Tech

  • 主页
  • 随笔
  • 关于我

微信公众号开发总结

阅读数:次 2018-06-21
字数统计: 4.9k字   |   阅读时长≈ 23分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
目录
1. 调研阶段
1.1 一般开发步骤
1.2 GitHub参考项目
1.3 需客户协助公众号申请
2. 开发&测试
2.1 微信账号信息
2.2 测试服务器
2.3 测试号
2.4 用本机当外网服务器
2.5 接口测试
获取access_token
3. 部署及系统配置、部分代码
3.1 微信公众号服务系统
3.1.1 部署步骤
3.2 公众号平台管理
3.2.1 公众号信息
3.2.2 wx.properties配置信息
3.2.3 模板设置
3.2.4 公众号菜单地址配置
3.2.5 公众号网页账号授权域名配置
3.3 微信公众号 关注着 openId 获取工具类 WeChatOpenIdUtils.java
3.4 给公众号关注者微信发送通知
4. Problems
4.1 微信获取openId,跳转链接错误
4.2 ajax request HTTP status 400
4.3 db.properties 中 jdbc.username 和 jdbc.password设反
4.4 ModelAndView setview 页面不跳转,刷新后才跳转
4.5 Can't find bundle for base name system, locale zh_CN
4.6 com.mysql.jdbc.driver
4.7 BeanNotOfRequiredTypeException... but was actually of type 'com.sun.proxy.$Proxy**'
4.8 At least one base package must be specified
4.9 redirect 和 forward运用
4.10 微信公众号子菜单url size超限
4.11 WxMpConfig
4.12 AopProxyUtils.getSingletonTarget(Ljava/lang/Object;)Ljava/lang/Object;
4.13 版本对应关系

本篇主要记录开发公众号时搜集到的一些案例,开发过程,以及开发中遇到的问题及解决方式。

微信公众号,分为 订阅号、服务号、企业号,之间的区别,以下来自官方:

1
2
3
1、订阅号:主要偏于为用户传达资讯(类似报纸杂志),认证前后都是每天只可以群发一条消息;
2、服务号:主要偏于服务交互(类似银行,114,提供服务查询),认证前后都是每个月可群发4条消息;
3、企业号:主要用于公司内部通讯使用,需要先验证身份才可以关注成功企业号。

具体区别说明,见官方说明。

其中订阅号是不用写代码开发的,只是微信公众平台后台的一些配置,这是大部分公众号的使用形式,实际上也够用了,每天发发文章。而服务号需要利用微信提供的接口进行二次开发,其实就是将网页嵌入到微信公众号中。

话不多说,直接上开发过程。

1. 调研阶段

因为要在微信公众号做一些业务,所以只能采用服务号的形式,需要开发,否则可以申请个订阅号解决问题。

在确定这个方案之后,开始咨询做过这方面的同学,搜索引擎查询。

当然,做一个技术选型,市场调研时,最关键的最直接的还是访问官方,微信公众平台。

当时也考虑用第三方做,如微擎,开源地址。最后否决了,不建议,因为不可控。

1.1 一般开发步骤

1.填写服务器配置

  • 购买服务器,搭建服务;

服务器:腾讯云、阿里云或其他服务器;

搭建服务:例子是Python Web。

找到几个Java的开源项目,见下方。

  • 申请公众号(服务号需要证件、资料) 多少天?钱?

测试号

测试平台

2.验证服务器地址有效性

3.依据接口文档实现业务逻辑

接口权限根据认证与否有差别。

接口调用频次,每个帐号每月共10次清零操作机会。

1.2 GitHub参考项目

  • weixin-java-mp-demo 微信公众号demo,使用weixin-java-tools,基于Spring MVC框架
  • weixin-java-tools 微信支付、开放平台、小程序、企业号和公众号(包括服务号和订阅号) Java SDK开发工具包
  • weixin-popular 微信SDK JAVA (公众平台、开放平台、 商户平台、 服务商平台)

1.3 需客户协助公众号申请

  • 企业资质才可申请的微信公众号-服务号。

  • 必须经过认证,未认证的公众号许多接口不开放,功能配置也无法完成。

2. 开发&测试

2.1 微信账号信息

APPID = wxbaasdasdff1d0bae6

APPSECRET = 4cbb8dasdff7d8c104a922acef0b7TtMsR8sMx4yOYeMNPraocqKovYlUSuKWBSuakbRe5LQ

http://0f80dce6.ngrok.io/wechat/portal

2.2 测试服务器

192.168.1.1 root
域名:wechat.company-name.com(必须有域名,测试可用ngrok等工具实现内网穿透)

2.3 测试号

  • appID:wx41asdfasdf3fc29
  • appsecret:582a656aaae8387ff46bac7c58580e8d

2.4 用本机当外网服务器

运行 ngrok 8080(ngrok是一个让外网访问本机的工具)

运行ngrok后会出现类似下面的信息:

1
2
3
4
5
6
7
Tunnel Status                 online
Version 1.7/1.6
Forwarding http://1bf992b1.ngrok.com -> 127.0.0.1:8080
Forwarding https://1bf992b1.ngrok.com -> 127.0.0.1:8080
Web Interface 127.0.0.1:4040
# Conn 52
Avg Conn Time 97.88ms

以后访问 http://1bf992b1.ngrok.com 就等于访问 http://localhost:8080。

2.5 接口测试

获取access_token

https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

  • 如:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxbaadasdf481d0bae6&secret=4cbb8d7fe225297d8c104a922acef0b7
  • 返回:{“access_token”:”YkLkXErasdffadk3nSHI1OAkxefvCb_k-nhYPfkvW6aT1CegobzHg7N8l1ag5fDOK8INSXmxVaJOfGj7kCTbuhKtOk9D8ofKcshh9UIgXVZK7p-9KfaUjQAWmGDVXUgAAAOQN”,”expires_in”:7200}

3. 部署及系统配置、部分代码

3.1 微信公众号服务系统

3.1.1 部署步骤

A. 当新版本改动较大时,建议直接全量更新,步骤如下

  • 1.用FileZilla等工具传输war包到服务器/../apache-tomcat-7.0.82/webapps/wechat.xxx.com/路径下,修改war包名为ROOT.war;
  • 2.ps -ef|grep tomcat查看tomcat服务进程,kill -9 progressNum杀死进程;或使用/../apache-tomcat-7.0.82/bin/shutdown.sh命令杀死该服务;
  • 3.修改webapps/projectname/WEB_INf/classes目录下的db.properties文件的服务器地址和账号密码,修改;
  • 4.修改webapps/projectname/WEB_INf/classes目录下的wx.properties文件的微信开发账号信息;
  • 5./../apache-tomcat-7.0.82/bin/startup.sh命令 重启tomcat。

B. 当只有部分业务更改,涉及到class文件更新,则可采用替换单个文件的方式,然后按照A中的方式重启服务。

C. 当只有前端页面更改,则可直接替换jsp文件的方式,无需重启服务。

  • 访问方式

微信公众号 搜索 公众号名称

3.2 公众号平台管理

3.2.1 公众号信息

1
2
3
4
5
6
- 注册人:xxx
- 公众平台账号:email-address
- APPID: wxxxxxxxxxxxxxxxx
- Token: xxxxxxWechatKoken
- AppSecret: fsa5e2d123ba7dddc07688123gf5c352
- URL: http://domain.com/wechat/portal

3.2.2 wx.properties配置信息

先登录公众号平台,进行配置:网页帐号,网页授权获取用户基本信息。这一项需要设置域名。

1
2
3
4
5
6
7
8
9
10
11
# 正式帐号 gh_123fe421235c 
#wx_appid=wxfd456bce1123569f
#wx_appsecret=caasdfd4easdfhy9dc1234569asdfasdfa3
#wx_token=xxxxxxxWechatKoken
#wx_aeskey=

#
### 申请人openid-用于接收请求,这个只做测试用,具体在代码里获取。参考 ## WeChatTestAccountAndProcess.md中 openId获取
#wx_user_open_id=o0pME0sMGKM_g123fg2nOmu123fU0
### 公众号管理员帐号-用于接收请求,此帐号需固定
#wx_admin_open_id=o0pME0i123fsdffUhkTcpsxG_zSg

WeChat openId 的获取方法见附录 4.2.

3.2.3 模板设置

排序 模板id 对象 模板标题 模板内容
1 8jkcCo8u0OSasdffdsb9PYzatk2TtsFflC-XhBXUg 申请提交,通知管理员 申请通知 申请从 进入园区。请尽快审核!
2 KLmQ_CBKiJqsadfge94R6qAasffJnNHnmJT6Lqxev7_i0 审核提交,同时通知提交人 申请成功,等候审核 您的申请已提交给管理员审核,通过之后会在微信通知您。
3 x2ouup403Masdfgo0o9Ey5pQ5hoXMRYasfaasdWDrhFEXW-sRk 审核通过,通知申请人 车辆入园审核通过 申请从 进入园区。已由管理员审核通过!

请使用管理员微信号登录公众号管理平台,设置消息模板。
模板申请 通过需要 1-3个工作日。

1.给管理员的申请

标题:申请通知

模板:

1
2
3
4
5
{{first.DATA}}
申请人:{{keyword1.DATA}}
申请内容:{{keyword2.DATA}}
申请时间:{{keyword3.DATA}}
{{remark.DATA}}

2.给申请人的提醒

标题:申请成功,等候审核

模板:

1
2
3
4
5
{{first.DATA}}
:{{carNum.DATA}}
校区:{{campus.DATA}}
大门:{{gate.DATA}}
{{remark.DATA}}

3.通过,给申请人

标题:车辆入园审核通过

模板:

1
2
3
4
5
{{first.DATA}}
申请类型:{{keyword1.DATA}}
申请人:{{keyword2.DATA}}
申请时间:{{keyword3.DATA}}
{{remark.DATA}}

3.2.4 公众号菜单地址配置

1
2
3
4
5
6
7
8
9
10
11
# 车辆入园申请 url
String redirectUri = URLEncoder.encode(basePath + "/intoApply");
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
+ this.wxConfig.getAppid() + "&redirect_uri="
+ redirectUri + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";

# 如 https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxwerqwrqwrqwer23fc29&redirect_uri=https%3A%2F%2F07282c25.ngrok.io%2FintoApply%2FtoIntoApply&response_type=code&scope=snsapi_base&state=123#wechat_redirect

# 重定向方式:https://wechat.xxx.com/intoApply/requestOpenId

# 需更换appid及域名

注意:需确保该服务器访问公网的权限放开,因为需要请求微信的api。

1
org.apache.http.conn.ConnectTimeoutException: Connect to api.weixin.qq.com:443 [api.weixin.qq.com/110.214.11.192, api.weixin.qq.com/110.214.0.121] failed: Connection timed out

解决方式

Linux 虚拟机 服务器 放行,使其可访问公网。

服务器可被外网访问和服务器可访问外网是两个概念。

3.2.5 公众号网页账号授权域名配置

登录微信公众平台,进入公众号设置-功能设置-网页授权域名,填写域名,注意需要先将MP_verify_RC1aoToVCFF3stcz.txt文件放置到ROOT目录下,否则会出现下面错误:

1
"GET /MP_verify_RC1aoToVCFF3stcz.txt HTTP/1.0" 404 1011

3.3 微信公众号 关注着 openId 获取工具类 WeChatOpenIdUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package com.xxx.utils;

import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;

/**
* @author linking
* @Date 2018/4/24
* @Title
* @Since V1.0
*/
public class WeChatOpenIdUtils {

public static String OPENID = "openid";

public static WeChatOpenIdUtils getInstance() {
return new WeChatOpenIdUtils();
}

/**
* 获取请求 微信openId 的链接
* 本来想在Java中发送请求 HttpClientUtil.httpGet(url)
* 但微信的机制,无效
* 目前是直接在菜单menu上绑定链接,省去中间跳转过程
* @param appId wxConfig.appId
* @return url
*/
public static String getRequestOpenIdUrl(HttpServletRequest request, String appId) {
String fullctx = ResourceUtil.getFullctx(request);
String redirectUrl = fullctx + "/intoApply/toIntoApply";

String redirectUri = URLEncoder.encode(redirectUrl);
return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId
+ "&redirect_uri=" + redirectUri + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
}


/**
* 调用微信接口取openID
*
* @param code
* @return
* @throws ParseException
* @throws IOException
* @throws InterruptedException
*/
public String queryOpenID(String code, String appId, String appSecret) throws ParseException, IOException, InterruptedException {
String openId = null;

String weixinOpenidUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId
+ "&secret=" + appSecret + "&grant_type=authorization_code&code=" + code;

JSONObject jsonObject = doGetStr(weixinOpenidUrl);
if (jsonObject != null) {
if (null != jsonObject.getString(OPENID)) {
openId = jsonObject.getString(OPENID);
}
}
return openId;
}

/**
* get请求
*
* @param url
* @return
* @throws ParseException
* @throws IOException
*/
public static JSONObject doGetStr(String url) throws ParseException, IOException {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
JSONObject jsonObject = null;
HttpResponse httpResponse = client.execute(httpGet);
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSONObject.fromObject(result);
}
return jsonObject;
}

/**
* POST请求
*
* @param url
* @param outStr
* @return
* @throws ParseException
* @throws IOException
*/
public static JSONObject doPostStr(String url, String outStr) throws ParseException, IOException {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpost = new HttpPost(url);
JSONObject jsonObject = null;
httpost.setEntity(new StringEntity(outStr, "UTF-8"));
HttpResponse response = client.execute(httpost);
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
jsonObject = JSONObject.fromObject(result);
return jsonObject;
}

/**
* 公共方法-请求openId
* 实验得出 不可行的结论,必须在单个方法中请求 url
*
* @param redirectUrl redirectUrl
* @param request request
* @param response response
*/
/* public void requestOpenId(String redirectUrl, String appId, HttpServletRequest request, HttpServletResponse response) {
// 成功的链接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx64c2e6c309d3fc29
&redirect_uri=https%3A%2F%2Fba9f504f.ngrok.io%2FintoApply%2FtoIntoNav
&response_type=code&scope=snsapi_base&state=123#wechat_redirect

String basePath = ResourceUtil.getScheme() + "//" + request.getServerName();// 80端口不需要加 + ":" + request.getServerPort();
String redirectUrl = basePath + "/intoApply/toIntoApply";
String appId = this.wxConfig.getAppid();

String redirectUri = URLEncoder.encode(redirectUrl);
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId
+ "&redirect_uri=" + redirectUri + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
try {
HttpClientUtil.httpGet(url);
} catch (AppException e) {
e.printStackTrace();
}
}*/
}

3.4 给公众号关注者微信发送通知

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* 审核通过
*
* @param request request
* @param httpSession httpSession
* @return AjaxJson
*/
@RequestMapping("/agreeApply")
public @ResponseBody
AjaxJson agreeApply(HttpServletRequest request, SmIntoApply model, HttpSession httpSession) {
AjaxJson json = new AjaxJson();
String message;
int code = 0;
try {

Long id = RequestUtils.getLongParameter(request, "id", -1L);
if (id > -1L) {
model = intoApplyService.getModelByKey(id);
} else {
code = ErrorUtil.AGREE_ERROR.getCode();
throw new WarnException(ErrorUtil.AGREE_ERROR.getMsg());
}

if (httpSession.getAttribute(WeChatOpenIdUtils.OPENID) != null) {
model.setIsaAuditWechatOpenid(httpSession.getAttribute(WeChatOpenIdUtils.OPENID).toString());
} else if (this.wxConfig.getWxAdminOpenId() != null) {
model.setIsaAuditWechatOpenid(this.wxConfig.getWxAdminOpenId());
}
model.setAuditStatus(1L);
int result = intoApplyService.update(model);
if (result > 0) {

/** 审核通过,给申请人发通知 start **/
String clickTemptoUrl = WeChatOpenIdUtils.getDetailUrl(request, model.getId(), this.wxConfig.getAppid());

WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder().build();
templateMessage.setToUser(model.getIsaWechatOpenid());
templateMessage.setTemplateId(wxConfig.getWxTempIdSucc4user());
templateMessage.setUrl(clickTemptoUrl);

//申请-大门
if (model.getIsaCampus() != null || model.getIsaGate() != null) {
WxMpTemplateData dataCampus = new WxMpTemplateData();
dataCampus.setColor("#576b95");
dataCampus.setValue(model.getIsaCampus() + "-" + model.getIsaGate());
dataCampus.setName("gate");
templateMessage.addWxMpTemplateData(dataCampus);
}
//申请车牌号码
if (model.getIsaCarNum() != null) {
WxMpTemplateData dataCarNum = new WxMpTemplateData();
dataCarNum.setName("carNum");
dataCarNum.setColor("#09BB07");
dataCarNum.setValue(model.getIsaCarNum());
templateMessage.addWxMpTemplateData(dataCarNum);
}

wxMpTemplateMsgService.sendTemplateMsg(templateMessage);
/** 审核通过,给申请人发通知 end **/

code = ErrorUtil.SERVER_SUCCESS.getCode();
message = ErrorUtil.SERVER_SUCCESS.getMsg();
json.setSuccess(true);
} else {
message = ErrorUtil.AGREE_ERROR.getMsg();
code = ErrorUtil.AGREE_ERROR.getCode();
json.setSuccess(false);
}
JSONObject data = new JSONObject();
json.setData(data);
} catch (WarnException ex) {
message = ex.getMessage();
json.setSuccess(false);
} catch (Exception e) {
message = e.getMessage();
code = ErrorUtil.SERVER_EXCEPT.getCode();
json.setSuccess(false);
}
json.setCode(code);
json.setMessage(message);
return json;
}

4. Problems

本节记录开发过程中遇到的问题。包括但不限于编码问题。

4.1 微信获取openId,跳转链接错误

  • 可能原因分析

    • 微信跳转机制?
    • 服务器配置错误?
    • 微信公众平台网页授权域名配置错误?
    • 基本配置里,ip白名单配置错了,成了局域网ip?公网ip啊

发现错误:

1
org.apache.http.conn.ConnectTimeoutException: Connect to api.weixin.qq.com:443 [api.weixin.qq.com/120.204.11.196, api.weixin.qq.com/120.204.0.120] failed: Connection timed out
  • 尝试措施
序号 措施 结果 备注
1 通过另一个页面,用js跳转 失败
2 直接将微信公众号主页菜单,配置为open链接 失败
  • 最终解决方式

Linux 虚拟机 服务器 放行,使其可访问公网。

服务器可被外网访问和服务器可访问外网是两个概念。

收获:

1.log日志相当重要。尤其是涉及到网络、IO
2.Linux操作不熟练
3.网络知识匮乏

4.2 ajax request HTTP status 400

服务器返回400错误。

原因:form表单提交的字段名称与后端接收的model类型中字段 数据类型 不一致。

解决方式:form表单中字段用model类型的字段;保证类型一致,尤其是long和string。

4.3 db.properties 中 jdbc.username 和 jdbc.password设反

注意反了,难找到。

4.4 ModelAndView setview 页面不跳转,刷新后才跳转

Ajax请求不能用ModelAndView返回。

4.5 Can’t find bundle for base name system, locale zh_CN

1
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle("system");

引入 system.property 文件

4.6 com.mysql.jdbc.driver

注意引入 mysql-connect..jar

4.7 BeanNotOfRequiredTypeException… but was actually of type com.sun.proxy.$Proxy**

  • 解决方法
1
2
3
4
5
6
7
8
<!--开启基于注解的事务,使用xml配置形式的事务(必要主要的都是使用配置式)  -->  
<aop:config>
<!-- 切入点表达式 -->
<aop:pointcut expression="execution(* com.qihang.service..*(..))" id="txPoint"/>
<!-- 拦截器方式配置事务增强 txAdvice = tx:advice -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop:config>
<aop:aspectj-autoproxy proxy-target-class="true"/>
  • 参考

http://blog.csdn.net/CSDN___LYY/article/details/76687588

  • 错误信息:
1
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'weixinService' is expected to be of type [com.xxx.service.WeixinService] but was actually of type [com.sun.proxy.$Proxy23]

4.8 At least one base package must be specified

  • 原因

某些 service、controller、mapper、handler、config未扫描到。

  • 解决方法

1.检查 web.xml contextConfigLocation 两处配置

1
2
3
4
5
6
7
8
9
10
11
# 引入需要 SpringMVC 扫描的xml文件 
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-core.xml,classpath:spring-mybatis.xml,classpath:spring-redis.xml</param-value>
</context-param>

# servlet 配置 spring-mvc.xml
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
  1. 检查修改项目结构,加入扫描路径。
1
2
3
4
5
<!-- 自动扫描(自动注入) -->
<context:component-scan base-package="com.xxx.**.dao"/>
<context:component-scan base-package="com.xxxx.**.service"/>
<context:component-scan base-package="com.xxx.handler"/>
<context:component-scan base-package="com.xxx.config"/>
  • 错误信息如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[ERROR] 2018-01-18 18:43:37,924 [RMI TCP Connection(3)-127.0.0.1]:org.springframework.web.context.ContextLoader:351#initWebApplicationContext() Context initialization failed
java.lang.IllegalArgumentException: At least one base package must be specified
at org.springframework.util.Assert.notEmpty(Assert.java:222)
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:245)
at org.mybatis.spring.mapper.ClassPathMapperScanner.doScan(ClassPathMapperScanner.java:155)
at org.mybatis.spring.annotation.MapperScannerRegistrar.registerBeanDefinit。。。
[INFO ] 2018-01-18 18:43:37,939 [RMI TCP Connection(3)-127.0.0.1]:org.springframework.web.context.support.XmlWebApplicationContext:982#doClose() Closing Root WebApplicationContext: startup date [Thu Jan 18 18:43:36 CST 2018]; root of context hierarchy
一月 18, 2018 6:43:37 下午 org.apache.catalina.core.StandardContext startInternal
严重: Error listenerStart
一月 18, 2018 6:43:37 下午 org.apache.catalina.core.StandardContext startInternal
严重: Context [] startup failed due to previous errors
[WARN ] 2018-01-18 18:43:37,955 [RMI TCP Connection(3)-127.0.0.1]:org.springframework.web.context.support.XmlWebApplicationContext:1000#doClose() Exception thrown from LifecycleProcessor on context close
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: Root WebApplicationContext: startup date [Thu Jan 18 18:43:36 CST 2018]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:416)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:997)
。。。
[DEBUG] 2018-01-18 18:43:37,971 [RMI TCP Connection(3)-127.0.0.1]:org.springframework.beans.factory.support.DefaultListableBeanFactory:512#destroySingletons() Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7b0cb1e8: defining beans [wxProperties,org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0,secuUserMapper,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.inte
[2018-01-18 06:43:37,986] Artifact ManageWecht:war: Error during artifact deployment. See server log for details.

4.9 redirect 和 forward运用

1
2
3
4
5
6
7
8
# forward 绝对路径
view.setViewName("forward: /propertyReport/toReportNav");
# forward 类内部路径
view.setViewName("forward: propertyReport/toReportNav");
# 差别在前面的`/`

# redirect
view.setViewName("forward: /propertyReport/toReportNav");

4.10 微信公众号子菜单url size超限

1
2
3
me.chanjar.weixin.common.exception.WxErrorException: 
{"errcode":40027,"errmsg":"invalid sub button url size hint:
[GGFBJA0389vr24]"}

网友评论:

1
2
3
1. 微信服务器老爱抽风。
2. 这不是你们的问题,是微信服务器自身的问题,过一段时间了再试,直到成功。

参考链接:

  1. https://www.cnblogs.com/zouke1220/p/7458878.html
  2. 微信返回码查看

发现问题:

1
2
我将 button23.setUrl(baseUrl + "frame");
写成了 button23.setPagePath(baseUrl + "frame");

4.11 WxMpConfig

错误描述:

1
2
3
4
5
6
7
8
9
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'wxMpConfig': Unsatisfied dependency expressed through
field 'appid': Expression parsing failed; nested exception is org.springframework.
expression.spel.SpelEvaluationException: EL1008E:(pos 13):
Property or field 'wx_appid' cannot be found on object of type 'java.util.Properties'
- maybe not public?; nested exception is org.springframework.beans.factory
.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.
expression.spel.SpelEvaluationException: EL1008E:(pos 13): Property or field 'wx_appid'
cannot be found on object of type 'java.util.Properties' - maybe not public?

解决参考链接:
https://blog.csdn.net/daihui05/article/details/7560570

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
改用下面标签:

- spring-core.xml
头标签
xmlns:util="http://www.springframework.org/schema/util"
http://www.springframework.org/schema/util/spring-util-4.0.xsd
引入属性文件
<util:properties id="wxProperties" location="classpath:/wx.properties"/>

<util:properties id="settings" location="classpath:xclkweb.properties"></util:properties>

WxMpConfig.java代码:
@Value(value="#{wxProperties.wx_appid}")
改为
@Value("#{wxProperties['wx_appid']}")
private String appid;

OK

4.12 AopProxyUtils.getSingletonTarget(Ljava/lang/Object;)Ljava/lang/Object;

参考

Spring4.3.12 才有这个方法

4.13 版本对应关系

在中心仓库中,可以查看某个 包 依赖的对应关系。

需要特别注意,版本的兼容性,导致很多问题。

  • 本文作者: Linking
  • 本文链接: https://linking.fun/2018/06/21/微信公众号开发总结/
  • 版权声明: 版权所有,转载请注明出处!
  • wechat
  • wechat

扫一扫,分享到微信

开源GIS解决方案,暨GeoServer+OpenLayer结合开发总结
ElasticSearch简单使用
  1. 1. 1. 调研阶段
    1. 1.1. 1.1 一般开发步骤
    2. 1.2. 1.2 GitHub参考项目
    3. 1.3. 1.3 需客户协助公众号申请
  2. 2. 2. 开发&测试
    1. 2.1. 2.1 微信账号信息
    2. 2.2. 2.2 测试服务器
    3. 2.3. 2.3 测试号
    4. 2.4. 2.4 用本机当外网服务器
    5. 2.5. 2.5 接口测试
      1. 2.5.1. 获取access_token
  3. 3. 3. 部署及系统配置、部分代码
    1. 3.1. 3.1 微信公众号服务系统
      1. 3.1.1. 3.1.1 部署步骤
    2. 3.2. 3.2 公众号平台管理
      1. 3.2.1. 3.2.1 公众号信息
      2. 3.2.2. 3.2.2 wx.properties配置信息
      3. 3.2.3. 3.2.3 模板设置
      4. 3.2.4. 3.2.4 公众号菜单地址配置
      5. 3.2.5. 3.2.5 公众号网页账号授权域名配置
    3. 3.3. 3.3 微信公众号 关注着 openId 获取工具类 WeChatOpenIdUtils.java
    4. 3.4. 3.4 给公众号关注者微信发送通知
  4. 4. 4. Problems
    1. 4.1. 4.1 微信获取openId,跳转链接错误
    2. 4.2. 4.2 ajax request HTTP status 400
    3. 4.3. 4.3 db.properties 中 jdbc.username 和 jdbc.password设反
    4. 4.4. 4.4 ModelAndView setview 页面不跳转,刷新后才跳转
    5. 4.5. 4.5 Can’t find bundle for base name system, locale zh_CN
    6. 4.6. 4.6 com.mysql.jdbc.driver
    7. 4.7. 4.7 BeanNotOfRequiredTypeException… but was actually of type com.sun.proxy.$Proxy**
    8. 4.8. 4.8 At least one base package must be specified
    9. 4.9. 4.9 redirect 和 forward运用
    10. 4.10. 4.10 微信公众号子菜单url size超限
    11. 4.11. 4.11 WxMpConfig
    12. 4.12. 4.12 AopProxyUtils.getSingletonTarget(Ljava/lang/Object;)Ljava/lang/Object;
    13. 4.13. 4.13 版本对应关系
© 2015-2026 Linking
GitHub:hexo-theme-yilia-plus by Litten
本站总访问量次 | 本站访客数人
  • 所有文章
  • 外链

tag:

  • weather
  • 需求
  • essay
  • basketball
  • olympic
  • nginx
  • APPScan
  • SQl盲注
  • xss
  • Ajax
  • ajax
  • ai
  • agent
  • openclaw
  • ccf
  • Nginx
  • HTML5
  • html5
  • hmtl5
  • sse
  • JavaScriptCore
  • Oracle
  • operation
  • Linux
  • deploy
  • Mac Office
  • markdown
  • ListView
  • GridView
  • MySQL
  • 慢查询
  • mongodb
  • 转置
  • thought
  • network
  • ubuntu
  • NetworkManager
  • RFKill
  • Netplan
  • avatar
  • cocoa
  • blog
  • Gitalk
  • container
  • macvlan
  • docker
  • oracle
  • cookie
  • patch
  • gitea
  • git
  • iOS
  • https
  • 多线程
  • bundle
  • 兼容性
  • HTTP
  • 绘图
  • cs
  • java
  • 效率
  • 快捷键
  • route
  • nodejs
  • pip
  • arcgis
  • arcgis 建模
  • 标识
  • redis
  • read
  • bookList
  • running
  • showdoc
  • disk
  • unit-test
  • D.Wade
  • thoughts
  • duoduo
  • Python
  • python
  • tomcat
  • 读书节
  • session
  • jdk
  • war
  • 加班
  • Android onclick事件监听
  • 正则
  • 手机品牌匹配
  • ntp
  • OpenLayers
  • Geoserver
  • wechat
  • 微信公众号
  • 爬虫
  • WeChat
  • 张靓颖
  • 动漫
  • vpn
  • PPT
  • MarkDown
  • plan
  • 朱赟
  • 极客时间专栏
  • 极客邦
  • 模块化
  • MVC
  • excel
  • NBA
  • kobe
  • team
  • crawler
  • 进度条
  • ssl
  • book
  • anti-stealing-link
  • Agentic Engineering
  • Vibe Coding
  • Software 3.0
  • Andrej Karpathy
  • LLM
  • Programming

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia-plus根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • GitHub Trending
  • OpenAI ChatGPT
  • Gitee码云
  • 简书
  • CSDN