微信小程序> 获取微信小程序码-图片上的小程序码怎么来的-小程序图形验证码

获取微信小程序码-图片上的小程序码怎么来的-小程序图形验证码

浏览量:2040 时间: 来源:jiuson
1.

背景:获取已有微信小程序的码(小程序码/二维码),保存为图片上传至cdn服务器,供使用方自行下载使用。

2.

查看微信小程序官方文档,获取小程序码分两个步骤,调用接口如下:

3.

1、获取access_token

4.

2、根据上面获取的access_token,请求小程序码:

上面是直接用postman请求的,下面看用Java程序获取:

首先看下设计思路:先将获取到的二进制流保存到本地图片,然后将图片文件上传到cdn上,就这么简单。(代码只展示了获取有限的永久小程序码)

packagecom.integration.wechat.impl;importjava.io.ByteArrayInputStream;importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importorg.apache.commons.codec.binary.Base64;importorg.apache.log4j.Logger;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.http.HttpEntity;importorg.springframework.http.HttpHeaders;importorg.springframework.http.HttpMethod;importorg.springframework.http.MediaType;importorg.springframework.http.ResponseEntity;importorg.springframework.http.converter.HttpMessageConverter;importorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter;importorg.springframework.stereotype.Component;importorg.springframework.web.client.RestTemplate;importcom.sunlands.si.exception.BusinessException;importcom.sunlands.si.integration.wechat.WechatMiniApp;importcom.sunlands.si.util.COSUtil;/****@authorzuowenjie**/@ComponentpublicclassWechatMiniAppImplimplementsWechatMiniApp{privateLoggerlogLogger.getLogger(WechatMiniAppImpl.class);@Value("${weixin.app_id}")privateStringappId;@Value("${weixin.app_secret}")privateStringsecretKey;@Value("${weixin.grant_type_QRCode}")privateStringgrantType;@Value("${weixin.get_access_token_url}")privateStringaccessTokenUrl;//获取小程序access_token@Value("${weixin.get_QRcode_url}")privateStringQRcodeUrl;//获取小程序码@Value("${weixin.path}")privateStringpage;@Value("${weixin.width}")privateintwidth;@Value("${weixin.localpath}")privateStringlocalpath;@AutowiredprivateCOSUtilcosUtil;privateRestTemplaterestTemplatenewRestTemplate();;publicWechatMiniAppImpl(){ListMediaTypemediaTypesnewArrayListMediaType();mediaTypes.add(MediaType.APPLICATION_JSON);mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);mediaTypes.add(MediaType.IMAGE_PNG);MappingJackson2HttpMessageConvertermj2hmcnewMappingJackson2HttpMessageConverter();mj2hmc.setSupportedMediaTypes(mediaTypes);ListHttpMessageConverter?messageConvertersrestTemplate.getMessageConverters();messageConverters.add(mj2hmc);restTemplate.setMessageConverters(messageConverters);}/***获取access_token*/@OverridepublicStringgetAccessToken(){MapString,StringrequestnewHashMapString,String();request.put("grant_type",grantType);request.put("appid",appId);request.put("secret",secretKey);log.info("获取微信小程序access_token地址:"+accessTokenUrl);log.info("获取微信小程序access_token入参:"+request.toString());@SuppressWarnings("unchecked")HashMapString,StringresultrestTemplate.getForObject(accessTokenUrl,HashMap.class,request);log.info("获取微信小程序access_token回参:"+result.toString());StringaccessTokenresult.get("access_token");if(nullaccessToken){thrownewBusinessException("获取小程序access_token异常:"+result.get("errmsg"));}returnaccessToken;}/***获取小程序码**@paramehrAccount*/@OverridepublicStringgetCodePicture(StringehrAccount){InputStreaminputStreamnull;OutputStreamoutputStreamnull;StringcosPathnull;StringaccessTokenthis.getAccessToken();Filefilenull;try{MapString,ObjectparamnewHashMap();param.put("path","page/home/index");param.put("width",430);param.put("auto_color",false);MapString,Objectline_colornewHashMap();line_color.put("r",0);line_color.put("g",0);line_color.put("b",0);param.put("line_color",line_color);log.info("调用生成微信小程序码URL接口地址:"+QRcodeUrl);log.info("调用生成微信小程序码URL接口入参:"+param);HttpHeadersheadersnewHttpHeaders();headers.setContentType(MediaType.IMAGE_PNG);HttpEntityMapString,ObjectrequestEntitynewHttpEntityMapString,Object(param,headers);ResponseEntitybyte[]entityrestTemplate.exchange(QRcodeUrl,HttpMethod.POST,requestEntity,byte[].class,accessToken);log.info("调用小程序生成微信永久小程序码URL接口回参:"+entity);byte[]resultentity.getBody();log.info("小程序码:"+Base64.encodeBase64String(result));inputStreamnewByteArrayInputStream(result);//二维码临时存放FiledirnewFile(localpath);if(!dir.isDirectory()){dir.mkdirs();}filenewFile(localpath+"/"+ehrAccount+"QRcode.png");if(!file.exists()){file.createNewFile();}outputStreamnewFileOutputStream(file);outputStream.write(result,0,result.length);outputStream.flush();cosPathcosUtil.upload(file.getAbsolutePath());}catch(Exceptione){log.error("调用小程序生成微信永久小程序码URL接口异常",e);}finally{if(inputStream!null){try{inputStream.close();}catch(IOExceptione){e.printStackTrace();}}if(outputStream!null){try{outputStream.close();}catch(IOExceptione){e.printStackTrace();}}if(null!file){file.delete();//删除临时文件}}returncosPath;}}5.

上面用的是springboot提供的restTemplate方式请求的,为什么用这个呢。原因很简单,封装的好,好用。再一个就是,我们的技术总监强制要求我们开发用springboot的全家桶,能不引用第三方的api坚决不用。插播一下,编码要求到了苛刻的地步,代码风格要统一,不定期进行代码review,接口严格遵守restful风格,命名要达到见名知意的标准,不准自制黑科技。其实,这样做好的方面是代码规范性好,便于维护,当然使用的技术也能在大boos的掌控范围内;不好的方面就是给开发人员设置了很多屏障。在另一篇文章中我会全面讲述一下我们的编码规范:

packagecom.si.util;importjava.util.Map;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.stereotype.Component;importcom.alibaba.fastjson.JSONObject;importcom.qcloud.cos.COSClient;importcom.qcloud.cos.ClientConfig;importcom.qcloud.cos.meta.InsertOnly;importcom.qcloud.cos.request.UploadFileRequest;importcom.qcloud.cos.sign.Credentials;importcom.sunlands.si.exception.BusinessException;/***腾讯云对象存储工具*@authorzuowenjie*/@ComponentpublicclassCOSUtil{@Value("${qcloud.appId}")privatelongappId;@Value("${qcloud.secretKey}")privateStringsecretKey;@Value("${qcloud.secretId}")privateStringsecretId;@Value("${qcloud.bucketName}")privateStringbucketName;@Value("${qcloud.region}")privateStringregion;@Value("${qcloud.QRCodePath}")privateStringcosPath;privateCredentialscred;privateClientConfigclientConfig;privateCOSClientcosClient;privatevoidinit(){//初始化秘钥信息crednewCredentials(appId,secretId,secretKey);//初始化客户端配置clientConfignewClientConfig();//设置bucket所在的区域,比如华南园区:gz;华北园区:tj;华东园区:sh;clientConfig.setRegion(region);//初始化cosClientcosClientnewCOSClient(clientConfig,cred);}/***上传文件到腾讯云对象存储*@paramappId*@paramsecretId*@paramsecretKey*@parambucketName*@paramcosPath*@paramlocalPath*@return*/publicStringupload(StringlocalPath){init();StringfileNamelocalPath.substring(localPath.lastIndexOf("\")+1);UploadFileRequestuploadFileRequestnewUploadFileRequest(bucketName,cosPath+"/"+fileName,localPath);uploadFileRequest.setInsertOnly(InsertOnly.OVER_WRITE);//覆盖StringuploadFileRetcosClient.uploadFile(uploadFileRequest);@SuppressWarnings("unchecked")MapString,Objectresult(MapString,Object)JSONObject.parse(uploadFileRet);if(!"SUCCESS".equalsIgnoreCase((String)result.get("message"))){thrownewBusinessException("小程序码上传失败:"+(String)result.get("message"));}@SuppressWarnings("unchecked")MapString,Stringdata(MapString,String)result.get("data");StringaccessUrldata.get("access_url");returnaccessUrl;}}6.

注意:

7.

因为微信官方返回的是一个二进制流,所以这里要特别注意用字节数组去接,不然会乱码,且保存的图片文件无法打开;

8.

还有一点给需要特别注意,也是细心的事情,在这里我就遇到了一个很傻的事情,由于原始代码是copy别人,可能之前请求的一个参数的命名被官方改了,就是这个参数:

param.put("path","page/home/index");9.

我把path写成了page,导致获取到的内容是错的,而且保存的图片打不开,但是又是用byte数组接的官方回参,这样就导致明明官方返回了错误信息,但是没转码根本看不出来是报错了,后来三个同事一起排查问题,才找出来。所以对自己的代码也不要过分自信,说不定哪个字母大小写不对就能让你花很多冤枉的时间,还会把自己逼疯。

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎