微信商城开源版二次开发(二)最近想知道如何将Java接入微信平台快速搭建一个完整的项目开发,发现网上有很多这类的开源代码。https://gitee.com/luozijing12...就是其中之一。您可以打开网页查看介绍。下面介绍项目如何连接微信公众号并部署。下面是我自己使用docker快速部署到云服务器上的http://81.69.254.72/index。体验账号:admin/admin123SKD中微信公众号收发微信公众号消息的路由模式消息的类型会有很多,包括文字、图片、地理等。为了更好的区分不同消息的处理,JAVA微信开源包——https://github.com/Wechat-Gro...采用路由方式处理。首先在业务代码包中注入router和wxMpService(http通知处理类)@BeanpublicWxMpMessageRoutermessageRouter(WxMpServicewxMpService){//记录所有事件(异步和同步执行属性)newRouter.rule().handler(this.logHandler).next();//接收客服session管理eventhandler可以放入List中进行多次处理newRouter.rule().async(false).msgType(EVENT).event(KF_CREATE_SESSION).handler(this.kfSessionHandler).end();newRouter.rule().async(false).msgType(EVENT).event(KF_CLOSE_SESSION).handler(this.kfSessionHandler).end();新路由器规则()。async(false).msgType(EVENT).event(KF_SWITCH_SESSION).handler(this.kfSessionHandler).end();//......}异步和同步的执行方式满足不同的业务属性,比如一些数据需要异步和同步到其他业务端,可以使用异步处理。这里的异步处理用于双线程,一个线程异步执行,另一个线程异步等待,方便知道结果,提高代码可靠性。WxMpXmlOutMessageres=null;最终列表>futures=newArrayList();Iteratorvar8=matchRules.iterator();while(var8.hasNext()){finalWxMpMessageRouterRule规则=(WxMpMessageRouterRule)var8.next();if(rule.isAsync()){//线程池异步执行,futuresTask封装结果futures.add(this.executorService.submit(newRunnable(){publicvoidrun(){rule.service(wxMessage,context,mpService,WxMpMessageRouter.this.sessionManager,WxMpMessageRouter.this.exceptionHandler);}}));}else{//同步执行,进入下面的handler和aspect处理res=rule.service(wxMessage,context,mpService,this.sessionManager,this.exceptionHandler);这。log.debug("结束会话访问:async=false,sessionId={}",wxMessage.getFromUser());this.sessionEndAccess(wxMessage);}}//每次有异步任务,异步获取结果,判断异步是否完成if(futures.size()>0){this.执行者服务。submit(newRunnable(){publicvoidrun(){Iteratorvar1=期货.迭代器();while(var1.hasNext()){未来future=(Future)var1.next();尝试{future.get();WxMpMessageRouter.this.log.debug("结束会话访问:async=true,sessionId={}",wxMessage.getFromUser());WxMpMessageRouter.this.sessionEndAccess(wxMessage);//异常处理}catch(InterruptedExceptionvar4){WxMpMessageRouter.this.log.error("等待任务完成时发生错误",var4);Thread.currentThread().interrupt();}catch(ExecutionExceptionvar5){WxMpMessageRouter.this.log.error("等待任务完成时发生错误",var5);}}}});}比如wx短信进入对应的路由流程try{Iteratorvar6=this.interceptors.iterator();//路由拦截器的数组也是自定义的,方便扩展功能。拦截器中没有使用WxMpMessageInterceptor;做{如果(!var6.hasNext()){WxMpXmlOutMessageres=null;迭代器var11=this.handlers.iterator();while(var11.hasNext()){WxMpMessageHandler处理程序=(WxMpMessageHandler)var11.next();if(handler!=null){//上面定义的路由处理器数组res=handler.handle(wxMessage,(Map)context,wxMpService,sessionManager);}}返回资源;}拦截器=(WxMpMessageInterceptor)var6.next();//先执行拦截器业务}while(interceptor.intercept(wxMessage,(Map)context,wxMpService,sessionManager));返回空值;}catch(WxErrorExceptionvar9){exceptionHandler.handle(var9);返回空值;}在初始化的具体handler业务中,在网页配置页面配置如何自动回复消息。有半配和全配两种,还有图片\语音\语音等,这些数据都存储在微信云里。具体可以扫描系统绑定,在页面自动配置http://81.69.254.72/wxmp/wxau...试试。@OverridepublicWxMpXmlOutMessagehandle(WxMpXmlMessagewxMessage,Mapcontext,WxMpServicewxMpService,WxSessionManagersessionManager){//程序集回复消息if(!wxMessage.getMsgType().equals(XmlMsgType.EVENT)){WxMpXmlOutMessagers;//TODO可以选择将消息保存到本地WxUserwxUser=wxUserMapper.selectOne(Wrappers.lambdaQuery().eq(WxUser::getOpenId,wxMessage.getFromUser()));if(WxConsts.KefuMsgType.TEXT.equals(wxMessage.getMsgType())){//1、先处理是否有文本关键字回复//先完全匹配网页中的设置你可以打开网页试试你自己http://81.69.254.72/wxmp/wxautoreplyListlistWxAutoReply=wxAutoReplyService.list(Wrappers.query().lambda().eq(WxAutoReply::getType,ConfigConstant.WX_AUTO_REPLY_TYPE_3).eq(WxAutoReply::getRepMate,ConfigConstant.WX_REP_MATE_1).eq(WxAutoReply::getReqKey,wxMessage.getContent()));if(listWxAutoReply!=null&&listWxAutoReply.size()>0){rs=this.getWxMpXmlOutMessage(wxMessage,listWxAutoReply,wxUser,wxMsgService);如果(rs!=null){返回rs;}}//再半匹配listWxAutoReply=wxAutoReplyService.list(Wrappers.query().lambda().eq(WxAutoReply::getType,ConfigConstant.WX_AUTO_REPLY_TYPE_3).eq(WxAutoReply::getRepMate,ConfigConstant.WX_REP_MATE_2)喜欢(WxAutoReply::getReqKey,wxMessage.getContent()));如果(listWxAutoReply!=null&&listWxAutoReply.size()>0){rs=this.getWxMpXmlOutMessage(wxMessage,listWxAutoReply,wxUser,wxMsgService);如果(rs!=null){返回rs;}}}//2、再处理消息回复ListlistWxAutoReply=wxAutoReplyService.list(Wrappers.query().lambda().eq(WxAutoReply::getType,ConfigConstant.WX_AUTO_REPLY_TYPE_2).eq(WxAutoReply::getReqType,wxMessage.getMsgType()));rs=this.getWxMpXmlOutMessage(wxMessage,listWxAutoReply,wxUser,wxMsgService);返回rs;}returnnull;}微信token验证小程序交互时,token用于验证用户是否登录小程序。因此,每次交互都需要验证用户登录的合法性。其实通过微信获取登录用户信息,过期后保存在redis中。检查用户是否无效。这是一个通用的解决方案。它也有缺点,就是session超时不好控制,影响体验。//session过期后,请求微信获取用户信息,存入redis。设置过期时间Mapparams=newHashMap(8);params.put("appid",config.getAppid());params.put("秘密",config.getSecret());params.put("js_code",jsCode);params.put("grant_type","authorization_code");Stringresult=this.get("https://api.weixin.qq.com/sns/jscode2session",Joiner.on("&").withKeyValueSeparator("=").join(params));返回WxMaJscode2SessionResult.fromJson(result);}springsecurity拦截器检查会话有效性@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{//获取header中的thirdSessionStringthirdSessionHeader=request.getHeader(ConfigConstant.HEADER_THIRDSESSION);if(StrUtil.isNotBlank(thirdSessionHeader)){//获取绑定存在中的ThirdSessionStringkey=WxMaConstants.THIRD_SESSION_BEGIN+":"+thirdSessionHeader;对象thirdSessionObj=redisTemplate.opsForValue().get(key);if(thirdSessionObj==null){//会话过期AjaxResultr=AjaxResult.error(MyReturnCode.ERR_60001.getCode(),MyReturnCode.ERR_60001.getMsg());this.writerPrint(响应,r);返回Boolean.FALSE;}else{StringthirdSessionStr=String.valueOf(thirdSessionObj);ThirdSessionthirdSession=JSONUtil.toBean(thirdSessionStr,ThirdSession.class);ThirdSessionHolder.setThirdSession(thirdSession);//设置thirdSession}}else{AjaxResultr=AjaxResult.error(MyReturnCode.ERR_60002.getCode(),MyReturnCode.ERR_60002.getMsg());this.writerPrint(响应,r);返回Boolean.FALSE;}返回Boolean.TRUE;}privatevoidwriterPrint(HttpServletResponseresponse,AjaxResultr)throwsIOException{//返回超时错误码,触发小程序重新登录response.setCharacterEncoding(CommonConstants.UTF8);response.setContentType(MediaType.APPLICATION_JSON_VALUE);PrintWriterwriter=response.getWriter()writer.print(JSONUtil.parseObj(r));如果(作者!=null){writer.close();}}