微信JS-SDK开发(自定义分享)

来源:互联网 发布:网络贷款5000新口子 编辑:程序博客网 时间:2024/05/17 15:18

因为工作需要,最近在做微信公众号开发,主要是在微信分享时自定义公司的logo和文案,开发过程中遇到了一些问题,总结如下:

开发前首先得去微信公众号平台申请注册一个账号,注册成功后拿到appid和secret。具体申请流程请参考微信公众号平台。
开发步骤:
1.通过appid,secret和“client_credential”获取token,因为获取token的api调用次数有限且有限时长为2小时,所以第一次取到token后必须全局缓存(放到数据库还是前端根据业务需要)。
2.通过第一步得到的token,调用微信jsapi获取ticket,同样ticket也需要进行全局缓存。
3.通过获取到的ticket,随机串,时间戳和当前页面的url,按照微信生成签名的规则进行加密并生成签名。
4.把上述得到的数据返回给前端。

开发过程中遇到了一些问题:
1.2小时内尽管token,ticket,timestamp等都是不变的,但是每次进入新的页面时url是变化的,所以sign得相应的变化。
2.自定义的图片太大时会出现图片显示不出来的问题,所以要将图片压缩,最好在10K以内。

JavaScript代码:
!function() {var dataForWeixin = {title: "",desc: "",imgUrl:“logo.png",link: ”要分享的链接“};var href = location.origin + location.pathname + location.search;$.ajax({url: '/ebusiness/auto/getWechatConfigParams.do',data: {'href': href,'ticket': localStorage.getItem('ticket') || "",'nonceStr': localStorage.getItem('nonceStr') || "",'timestamp': localStorage.getItem('timestamp') || ""},datatype: 'json',cache: false,async: false,success: function(msg) {var result = JSON.parse(msg);if (result.code == 1) {localStorage.setItem('appId', result.appId);localStorage.setItem('accessToken', result.access_token);localStorage.setItem('timestamp', result.timestamp);localStorage.setItem('ticket', result.ticket);localStorage.setItem('nonceStr', result.nonceStr);localStorage.setItem('signature', result.signature);dataForWeixin.title = result.title;dataForWeixin.desc = result.desc;} else if (result.code == 2) {localStorage.setItem('signature', result.signature);dataForWeixin.title = result.title;dataForWeixin.desc = result.desc;} else {console.log("获取token异常!");}},error: function(msg) {console.log("请求数据失败!");}});wx.config({debug : false,appId : localStorage.getItem('appId'),timestamp : localStorage.getItem('timestamp'),nonceStr : localStorage.getItem('nonceStr'),signature : localStorage.getItem('signature'),jsApiList : [ 'checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ' ]});wx.ready(function() {wx.checkJsApi({jsApiList : ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ' ],fail: function(res) {console.log("微信版本过低,请升级到新版本!");}});wx.onMenuShareTimeline({title : dataForWeixin.desc,link : dataForWeixin.link,imgUrl : dataForWeixin.imgUrl,      success: function (res) {        console.log("分享到朋友圈成功!");    },fail: function(res) {console.log("分享到朋友圈失败!");}});wx.onMenuShareAppMessage({title : dataForWeixin.title,desc : dataForWeixin.desc,link : dataForWeixin.link,imgUrl : dataForWeixin.imgUrl,      success: function (res) {        console.log("分享到微信好友成功!");    },fail: function(res) {console.log("分享到微信好友失败!");}});    wx.onMenuShareQQ({        title: dataForWeixin.title,        desc: dataForWeixin.desc,        link: dataForWeixin.link,        imgUrl: dataForWeixin.imgUrl,      success: function (res) {        console.log("分享到QQ好友成功!");    },fail: function(res) {console.log("分享到QQ好友失败!");}     });});wx.error(function(res) {console.log(res.errMsg);});}();

java代码:
public class GetWechatConfigParamsController extends AbstractController {private static final String APP_ID = "";private static final String SECRET = "";private static final String GRANT_TYPE = "client_credential";private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";private static final String TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";private static final String WECHAT_TITLE = "wechat.title";private static final String WECHAT_DESC = "wechat.desc";private Logger logger = Logger.getLogger(this.getClass());@Overrideprotected ModelAndView handleRequestInternal(HttpServletRequest request,HttpServletResponse response) throws Exception {String href = request.getParameter("href");String ticket = request.getParameter("ticket");String nonceStr = request.getParameter("nonceStr");String timestamp = request.getParameter("timestamp");long curTimestmap = (long)(new Date().getTime() / 1000);JSONObject result = new JSONObject();if (!this.isNullOrEmpty(ticket) && !this.isNullOrEmpty(nonceStr) && !this.isNullOrEmpty(timestamp)&& (curTimestmap - Long.parseLong(timestamp) <= 7000)) {logger.info("已缓存token且没有超过2小时!");result.put("code", 2);result.put("appId", APP_ID);result.put("timestamp", timestamp);result.put("ticket", ticket);result.put("nonceStr", nonceStr);String signature = CoderUtils.encodeSHA(this.constructEncryptString(href, nonceStr, result));logger.info("进行sha1签名后的字符串为---> " + signature);result.put("signature", signature);result.put("title", Configuration.getValue(WECHAT_TITLE));result.put("desc", Configuration.getValue(WECHAT_DESC));} else {logger.info("开始获取access_token!");String accessTokenResult = this.getWechatInfoByGetMethod(this.constructAccessTokenUrl(GRANT_TYPE, APP_ID, SECRET));logger.info("获取到的access_token信息为:" + accessTokenResult);result = JSONObject.fromObject(accessTokenResult);//用于给页面的标识:0表示失败,1表示成功,2表示已缓存相关值if (null != accessTokenResult) {result.put("code", 1);result.put("appId", APP_ID);result.put("timestamp", (long)(new Date().getTime() / 1000));logger.info("开始获取jsapi_ticket!");String ticketResult = this.getWechatInfoByGetMethod(this.constructTicketUrl(result.getString("access_token"), "jsapi"));logger.info("获取到的jsapi_ticket信息为:" + ticketResult);JSONObject ticketJson = JSONObject.fromObject(ticketResult);if (0 == ticketJson.getInt("errcode") && "ok".equals(ticketJson.getString("errmsg").toLowerCase())) {  //成功result.put("ticket", ticketJson.getString("ticket"));String nonceString = this.createRandomString();result.put("nonceStr", nonceString);String signature = CoderUtils.encodeSHA(this.constructEncryptString(href, nonceString, result));logger.info("进行sha1签名后的字符串为:" + signature);result.put("signature", signature);result.put("title", Configuration.getValue(WECHAT_TITLE));result.put("desc", Configuration.getValue(WECHAT_DESC));}} else {result.put("code", 0);}}logger.info("返回给页面的数据:" + result.toString());response.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");response.getWriter().print(result);return null;}/** * @param grant_type * @param appId * @param secret * @return  组装好的获取access_token的url */private String constructAccessTokenUrl(String grant_type, String appId, String secret) {StringBuffer url = new StringBuffer(ACCESS_TOKEN_URL);url.append("?").append("grant_type=" + grant_type).append("&").append("appid=" + appId).append("&").append("secret=" + secret);logger.info("获取微信access_token的URL为:" + url.toString());return url.toString();}/** * @param accessToken * @param jsApi * @return 获取jsapi_ticket的url */private String constructTicketUrl(String accessToken, String jsApi) {StringBuffer url = new StringBuffer(TICKET_URL);url.append("?")   .append("access_token=" + accessToken)   .append("&")   .append("type=" + jsApi);logger.info("获取微信jsapi_ticket的URIL为:" + url.toString());return url.toString();}/** * @param url 获信息的url * @return 获取到的微信信息 */private String getWechatInfoByGetMethod(String url) {HttpClient httpClient = HttpClientUtils.getHttpClient();GetMethod getMethod = new GetMethod(url);try {if (HttpStatus.SC_OK == httpClient.executeMethod(getMethod)) {return getMethod.getResponseBodyAsString();}} catch (HttpException e) {logger.error("http请求错误!请求路径为:" + url);e.printStackTrace();} catch (IOException e) {logger.error("io读写错误!");e.printStackTrace();}return null;}/** * @return 生成随机字符串 */private String createRandomString() {StringBuffer result = new StringBuffer();String fromString = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ";int length = fromString.length();Random random = new Random();for (int index = 0; index < 16; index++) {result.append(fromString.charAt(random.nextInt(length)));}logger.info("随机字符串为:" + result.toString());return result.toString();}/** * @param href 链接 * @param randomString 随机串 * @param jsonStr json对象 * @return 拼接后的字符串 */private String constructEncryptString(String href, String randomString, JSONObject jsonStr) {StringBuffer result = new StringBuffer();result.append("jsapi_ticket=" + jsonStr.getString("ticket")).append("&").append("noncestr=" + randomString).append("&").append("timestamp=" + jsonStr.getString("timestamp")).append("&").append("url=" + href);logger.info("拼接后的待签名字符串为:" + result.toString());return result.toString();}/** * @param str 待判断的字符串 * @return 空返回true,非空返回fasle */private boolean isNullOrEmpty(String str) {if (null == str || str.isEmpty() || "".equals(str)) {return true;}return false;}}




0 0
原创粉丝点击