微信开发怎么实现自定义菜单
这篇文章主要介绍了微信开发怎么实现自定义菜单,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
最近有做了关于微信公众号和自己网站用户进行用户关联授权登录的一个功能,主要是用户关注该公众号,点击会员中心,则会弹出需要关联授权的网页授权:OAuth3.0网页授权,然后用户同意获取用户信息,进行用户和网站的关联,然后用户则可以使用微信进行登录。
本次做的是一个在Java的http://www.php.cn/java/java-Action.html" target="_blank">Action层处理各个返回参数获取数据。
一、 使用到的工具:
1、ngrok,将你自己的本机映射到公网,这样保证可以随时测试开发;
1、下载ngrok,网址:http://www.tunnel.mobi/
2、将文件放到Tomcat目录下,在cmd中运行ngrok -config ngrok.cfg -subdomain xinzhi 8080
3、ngrok工具为在慕课网@LAOBI 看到的
2、微信公众号测试账号,随时测试,首先保证在测试账号下没有问题后在进行公众号的移植。
二、使用到在Java中发送一个Http请求,然后返回JSON参数,获得JSON参数,然后进行处理。
首先,获取将公众号测试号放到properties文件中,以便我们进行调用或者更换,如:url请用https
AppID=wxf00**c3dd2ebfa0 AppSecret=3cb220755f****506dc35391aa5c03ec url=https://xinzhi.tunnel.mobi
这里url为我们映射到外网的地址,一会需要用到。然后需要两个工具类,该工具类作用是在Java的Action中发送http请求后获取到去返回值
启用自己有相应的改动,以适应本项目的需求:
WeixinUtil.java 和 MyX509TrustManager.java
packagecom.zhtx.common.util; importjava.io.BufferedReader; importjava.io.InputStream; importjava.io.InputStreamReader; importjava.io.OutputStream; importjava.net.ConnectException; importjava.net.URL; importjavax.net.ssl.HttpsURLConnection; importjavax.net.ssl.SSLContext; importjavax.net.ssl.SSLSocketFactory; importjavax.net.ssl.TrustManager; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; /** *公众平台通用接口工具类 * *@authorxinz *@date2015-10-14 */ publicclassWeixinUtil{ privatestaticLoggerlog=LoggerFactory.getLogger(WeixinUtil.class); /** *发起https请求并获取结果 * *@paramrequestUrl请求地址 *@paramrequestMethod请求方式(GET、POST) *@paramoutputStr提交的数据 *@returnJSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) */ publicstaticStringhttpRequest(StringrequestUrl,StringrequestMethod,StringoutputStr){ StringBufferbuffer=newStringBuffer(); try{ //创建SSLContext对象,并使用我们指定的信任管理器初始化 TrustManager[]tm={newMyX509TrustManager()}; SSLContextsslContext=SSLContext.getInstance("SSL","SunJSSE"); sslContext.init(null,tm,newjava.security.SecureRandom()); //从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactoryssf=sslContext.getSocketFactory(); URLurl=newURL(requestUrl); HttpsURLConnectionhttpUrlConn=(HttpsURLConnection)url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); //设置请求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); //当有数据需要提交时 if(null!=outputStr){ OutputStreamoutputStream=httpUrlConn.getOutputStream(); //注意编码格式,防止中文乱码 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } //将返回的输入流转换成字符串 InputStreaminputStream=httpUrlConn.getInputStream(); InputStreamReaderinputStreamReader=newInputStreamReader(inputStream,"utf-8"); BufferedReaderbufferedReader=newBufferedReader(inputStreamReader); Stringstr=null; while((str=bufferedReader.readLine())!=null){ buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); //释放资源 inputStream.close(); inputStream=null; httpUrlConn.disconnect(); }catch(ConnectExceptionce){ log.error("Weixinserverconnectiontimedout."); }catch(Exceptione){ log.error("httpsrequesterror:{}",e); } returnbuffer.toString(); } }
对于https请求,我们需要一个证书信任管理器,这个管理器类需要自己定义,但需要实现X509TrustManager接口,代码如下:
packagecom.zhtx.common.util; importjava.security.cert.CertificateException; importjava.security.cert.X509Certificate; importjavax.net.ssl.X509TrustManager; /** *证书信任管理器(用于https请求) * *@authorxinz *@date2015-10-14 */ publicclassMyX509TrustManagerimplementsX509TrustManager{ publicvoidcheckClientTrusted(X509Certificate[]chain,StringauthType)throwsCertificateException{ } publicvoidcheckServerTrusted(X509Certificate[]chain,StringauthType)throwsCertificateException{ } publicX509Certificate[]getAcceptedIssuers(){ returnnull; } }
微信返回参数的一个POJO类:
privateStringopenid;//用户的唯一标识 privateStringnickname;//用户昵称 privateIntegersex;//用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 privateStringprovince;//用户个人资料填写的省份 privateStringcity;//普通用户个人资料填写的城市 privateStringcountry;//国家,如中国为CN privateStringheadimgurl;//用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 privateStringprivilege;//用户特权信息,json数组,如微信沃卡用户为(chinaunicom) privateStringunionid;//只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。详见:获取用户个人信息(UnionID机制) privateStringaccess_token;
授权凭证验证的类:
privateStringerrcode; privateStringerrmsg;
通过code换取网页授权access_token
privateStringaccess_token; privateStringexpires_in; privateStringrefresh_token; privateStringopenid; privateStringscope; privateStringunionid;
关于微信头像的,获取的是一个http的url,则需要将图片下载到服务器存储,然后获得相对路径:
/** *使用url或者http存入文件 *@Title:fileUpload *@param@paramfileUrl文件url,可以是http *@param@parampath文件存储路径 *@returnvoid *@throwsxinz */ publicstaticvoidfileUpload(StringfileUrl,Stringpath){ //读取文件 Strings1=fileUrl; java.io.InputStreamis=null;//定义一个输入流。 BufferedInputStreambis=null;//定义一个带缓冲的输入流。 //写到本地 BufferedOutputStreambos=null;//定义一个带缓冲的输出流。 try{ java.net.URLurl=newjava.net.URL(s1);//创建一个URL对象。 is=url.openStream();//打开到此URL的连接并返回一个用于从该连接读入的InputStream。 bis=newjava.io.BufferedInputStream(is); Filefile=newFile(path); if(!file.exists()){//测试此抽象路径名表示的文件或目录是否存在。 file.createNewFile();//创建此抽象路径名表示的文件或目录。 } bos=newBufferedOutputStream(newFileOutputStream(file));; byte[]b=newbyte[1024];//创建字节数组。 while(bis.read(b)!=-1){//输入流中的数据如果还有下一行(!=-1)将继续循环 bos.write(b);//将字节数组写入输出流。 } }catch(Exceptione){ System.out.println(e.toString()); }finally{ try{ bos.flush();//刷新此缓冲的输出流。 bis.close();//关闭此输入流。 }catch(Exceptione){ System.out.println(e.toString()); } } }
现在是基础工作都做完了,现在开发代码的开发,然后我们按照这个步骤开发:
第一步:用户同意授权,获取code
这里的url就是前面所准备在properties中的url了。
/** *微信用户授权 *@Title:wechatOauth *@param@paramrequest *@param@paramresponse *@param@parammodel *@param@return *@returnString *@throwsxinz */ @RequestMapping("wechatOauth") publicStringwechatOauth(HttpServletRequestrequest,HttpServletResponseresponse,Modelmodel){ /** *1第一步:用户同意授权,获取code */ //首先拿到微信公众号的AppID、AppSecret等参数 StringAppID=ZhtxHelper.getApplicationResourcesProp("sendSms","AppID"); StringurlOpen=ZhtxHelper.getApplicationResourcesProp("sendSms","url"); //如果用户授权成功则跳转到此url StringloginUrl=""+urlOpen+"/zhtx-wap/weixin/getAccessToken"; //用户授权,获取code Stringurl="https://open.weixin.qq.com/connect/oauth3/authorize?" +"appid="+AppID+"" +"&redirect_uri="+loginUrl+"" +"&response_type=code" +"&scope=snsapi_userinfo" +"&state=123#wechat_redirect"; //forwardredirect return"redirect:"+url+""; }
第二步:通过code换取网页授权access_token
/** *通过code换取网页授权access_token *@Title:getAccessToken *@param@paramrequest *@param@paramresponse *@param@parammodel *@param@return *@returnString *@throwsxinz */ @RequestMapping("getAccessToken") publicStringgetAccessToken(HttpServletRequestrequest,HttpServletResponseresponse,Modelmodel){ //获取到返回的参数 try{ //首先拿到微信公众号的AppID、AppSecret等参数 StringAppID=ZhtxHelper.getApplicationResourcesProp("sendSms","AppID"); StringAppSecret=ZhtxHelper.getApplicationResourcesProp("sendSms","AppSecret"); Stringcode=request.getParameter("code"); Stringurl=null; if(code!=null){ /** *2第二步:通过code换取网页授权access_token */ //用户授权,获取code url="https://api.weixin.qq.com/sns/oauth3/access_token?" +"appid="+AppID+"" +"&secret="+AppSecret+"" +"&code="+code+"" +"&grant_type=authorization_code"; StringrequestMethod="GET"; StringoutputStr=""; StringhttpRequest=WeixinUtil.httpRequest(url,requestMethod,outputStr); System.out.println("通过code换取网页授权access_token="+httpRequest); AccessTokenModelaccTok=JSON.parseObject(httpRequest,AccessTokenModel.class); /** *4第四步:拉取用户信息(需scope为snsapi_userinfo) */ //用户授权,获取code StringurlUser="https://api.weixin.qq.com/sns/userinfo?" +"access_token="+accTok.getAccess_token()+"" +"&openid="+accTok.getOpenid()+"" +"&lang=zh_CN"; StringhttpUser=WeixinUtil.httpRequest(urlUser,requestMethod,outputStr); System.out.println("拉取用户信息=="+httpUser); WechatUserwechatUser=JSON.parseObject(httpUser,WechatUser.class); wechatUser.setAccess_token(accTok.getAccess_token()); /** *5附:检验授权凭证(access_token)是否有效 */ WechatMsgcheckAccessToken=checkAccessToken(wechatUser.getAccess_token(),wechatUser.getOpenid()); if(checkAccessToken.getErrcode().equals("0")){ CurrentSession.setAttribute("wechatUser",wechatUser); WechatUserwechatU=newWechatUser(); wechatU.setOpenid(wechatUser.getOpenid()); List<WechatUser>findWechatUser=wechatUserService.findWechatUser(wechatU); if(findWechatUser.size()>0){ UserRegisteruserRegister=userService.findUserByOpenid(wechatUser.getOpenid()); CurrentSession.setAttribute("user",userRegister); return"redirect:/user/userCenter"; }else{ return"/jsp/wechat/wechatregister"; } }else{ //如果access_token失效,则再次进行调用,并存储access_token值,access_token有效期为2个小时 this.wechatOauth(request,response,model); } } }catch(Exceptione){ System.out.println("===拉取用户出错==="); e.printStackTrace(); } //forwardredirect return"/jsp/wechat/wechatregister"; }
第四步:拉取用户,和自己网站用户绑定
/** *微信关联用户 *@Title:saveWechatUser *@param@parammobilePhone *@param@parampassword *@param@paramvalidataCode *@param@return *@returnString *@throwsxinz */ @RequestMapping("saveWechatUser") publicStringsaveWechatUser(HttpServletResponseresponse,StringmobilePhone,Stringpassword,StringvalidataCode){ //使用手机号来判断该手机是否在注册 UserRegisteruserRegister=userService.findUserByPhone(mobilePhone); WechatUserwechatUser=(WechatUser)CurrentSession.getAttribute("wechatUser"); WechatUserwechatU=newWechatUser(); wechatU.setOpenid(wechatUser.getOpenid()); List<WechatUser>findWechatUser=wechatUserService.findWechatUser(wechatU); if(findWechatUser.size()>0&&userRegister.getOpenid()!=null){ CurrentSession.setAttribute("user",userRegister); return"redirect:/user/userCenter"; }else{ //如果没有注册,开始注册 if(userRegister==null){ Result<UserRegister>saveUserInfoApp=userRegisterService.saveUserInfoApp(mobilePhone,password,validataCode,wechatUser); if(saveUserInfoApp.getState()==1){ //进行微信和用户的关联 wechatUserService.saveWechatUser(wechatUser); CurrentSession.setAttribute("user",userRegister); return"redirect:/user/userCenter"; } }elseif(userRegister.getOpenid()==null||userRegister.getOpenid().equals("")){ //否则,查询出用户信息,放入session中,关联微信,跳转到用户中心 UserRegisteruserReg=newUserRegister(); userReg.setId(userRegister.getId()); //存入微信openid userReg.setOpenid(wechatUser.getOpenid()); userService.upUser(userReg); UserInfouser=newUserInfo(); //存入微信头像 //图片类型 StringdateStr=DateUtil.format(DateUtil.getCurrentDate(),"yyyyMMdd")+"/"; //图片类型 StringimgType="JPG"; //微信头像名称 Stringapp2DBarNameAndType=UuidUtil.getUUID()+"."+imgType; //微信头像路径 Stringpath=ZhtxHelper.getApplicationResourcesProp("application","app.img.projectpath")+SysConstant.GOODS2DBARPATH+dateStr; Filefile1=newFile(path); file1.mkdirs(); //图片全路径 StringimgUrl=SysConstant.GOODS2DBARPATH+dateStr+app2DBarNameAndType; FileUtil.fileUpload(wechatUser.getHeadimgurl(),path); user.setRegisterId(userRegister.getId()); user.setImageUrl(imgUrl); userInfoService.updateUserInfo(user); //存入微信用户 wechatUserService.saveWechatUser(wechatUser); UserRegisteruserW=userService.findUserByPhone(mobilePhone); CurrentSession.setAttribute("user",userW); return"redirect:/user/userCenter"; }else{ CurrentSession.setAttribute("user",userRegister); return"redirect:/user/userCenter"; } } return"redirect:/user/userCenter"; }
附:检验授权凭证(access_token)是否有效
/** *检验授权凭证(access_token)是否有效 *@Title:checkAccessToken *@param@paramaccess_token网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 *@param@paramopenid用户的唯一标识 *@returnWechatMsg返回消息实体 *@throwsxinz */ publicstaticWechatMsgcheckAccessToken(Stringaccess_token,Stringopenid){ StringrequestMethod="GET"; StringoutputStr=""; Stringurl="https://api.weixin.qq.com/sns/auth?" +"access_token="+access_token+"" +"&openid="+openid+""; Stringhttpmsg=WeixinUtil.httpRequest(url,requestMethod,outputStr); System.out.println("拉取用户信息返回消息=="+httpmsg); WechatMsgmsg=JSON.parseObject(httpmsg,WechatMsg.class); returnmsg; }
然后在网页端,则是需要编写H5页面,进行自己网站和微信用户的关联,我这里是使用手机号,用户输入手机号,进行判断,如果注册过就直接关联,如果用户没有注册则进行注册后关联,完成后跳转到会员中心。
感谢你能够认真阅读完这篇文章,希望小编分享的“微信开发怎么实现自定义菜单”这篇文章对大家有帮助,同时也希望大家多多支持恰卡编程网,关注恰卡编程网行业资讯频道,更多相关知识等着你来学习!
推荐阅读
-
EasyWechat如何开发微信公众号自动回复
-
微信开发怎样直接访问本地调试
微信开发怎样直接访问本地调试这篇文章主要为大家分析了微信开发怎样直...
-
微信开发中的自定菜单该如何创建
微信开发中的自定菜单该如何创建这篇文章主要为大家分析了微信开发中的...
-
如何实现微信打开网址添加在浏览器中打开提示
-
微信被限制登录的原因有哪些
-
微信中文件撤回时间延长了多久
-
微信提示登录环境异常的原因有哪些
这篇文章主要介绍微信提示登录环境异常的原因有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!微信提示登录...
-
微信开发之用户与姓名不匹配指的是什么意思
这篇文章给大家分享的是有关微信开发之用户与姓名不匹配指的是什么意思的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过...
-
微信聊天中拍了拍指的是什么意思
-
微信莫名退出登录原因有哪些
小编给大家分享一下微信莫名退出登录原因有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!微信莫名退出登录原因:...