Java实现获取小程序带参二维码并保存到本地

网友投稿 269 2022-12-01

Java实现获取小程序带参二维码并保存到本地

目录获取小程序带参二维码并保存到本地业务场景POSTMAN调试WxUtil封装:下载带参数的小程序二维码Controller调用下载验证微信小程序码的生成及保存到阿里云oss阿里云oss工具类

获取小程序带参二维码并保存到本地

业务场景

下载并保存带参数的小程序二维码,用户直接扫描带参二维码就进入小程序,自动根据参数完成部分业务。这个时候就需要用到微信小程序提供的二维码接口 wxacode.getUnlimited ,官方文档地址

网上介绍的很多方法有些过时了,有些不科学,调用起来不方便,所以自己也总结了一份出来。虽然很久之前直接用jfinal+jfinal-wx写的,几句代码就搞定了,但是最近需要迁移项目到SpringBoot2,所以就踩了个坑顺便总结一下,确实找了大半天。

POSTMAN调试

如果一个借口postman都调用不通,那就更别说用java代码去写了,调用接口第一步就是熟悉接口请求方式 method、请求格式 Content-Type和接口参数 Body/Param以及返回的内容,POSTMAN调用参数过程

url https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={{access_token}}

json raw { "scene":"EGAG-SAL**-******"}

WxUtil封装:下载带参数的小程序二维码

import cn.hutool.http.HttpUtil;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;

import java.io.*;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.HashMap;

import java.util.Map;

/**

* 微信小程序辅助工具类 https://developers.weixin.qq.com/miniprogram/dev/api-backend/

* @Author zhengkai.blog.csdn.net

* */

@Slf4j

public class WxUtil {

public static String GET_MINICODE_URL="https://api.weixin.qq.com/wxa/getwxacodeunlimit";

public static String APPID="你的APPID";

public static String APPSECRET="你的APPSECRET";

public static String getAccessTokenAsUrl(){

String tokenStr=HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET+"");

log.info(tokenStr);

JSONObject jsonObject = JSONObject.parseObject(tokenStr);

return "?access_token="+jsonObject.getString("access_token");

}

/**

* 下载带参数的小程序二维码

* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html

* by zhengkai.blog.csdn.net

* @param pathStr 保存图片的的path

* @param certNumber 带过去小程序的参数,一般为你的业务参数,建议是id或者number

* */

public static String downloadMiniCode(String pathStr , String certNumber){

Map paramMap = new HashMap<>();

paramMap.put("scene",certNumber);

paramMap.put("is_hyaline",true);

String imgFilePath = pathStr+"/certificate/"+certNumber+".png";// 新生成的图片

try

{

URL url = new URL(GET_MINICODE_URL+getAccessTokenAsUrl());

HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

httpURLConnection.setRequestMethod("POST");// 提交模式

httpURLConnection.setConnectTimeout(10000);//连接超时 单位毫秒

httpURLConnection.setReadTimeout(10000);//读取超时 单位毫秒

// 发送POST请求必须设置如下两行

httpURLConnection.setDoOutput(true);

httpURLConnection.setDoInput(true);

// 获取URLConnection对象对应的输出流

PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());

printWriter.write(JSON.toJSONString(paramMap));

// flush输出流的缓冲

printWriter.flush();

//开始获取数据

BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());

OutputStream os = new FileOutputStream(new File(imgFilePath));

int len;

//设置缓冲写入

byte[] arr = new byte[2048];

while ((len = bis.read(arr)) != -1)

{

os.write(arr, 0, len);

os.flush();

}

os.close();

}

catch (Exception e)

{

e.printStackTrace();

}

return imgFilePath;

}

}

Controller调用

传入保存的 path地址 和 scene参数

WxUtil.downloadMiniCode(storageService.getPathString(),certCompany.getCertNumber());

下载验证

之前试过很多方法就是保存后的png图片无法使用,可能是保存的姿势、方法不对。用这个方法亲测可行。

微信小程序码的生成及保存到阿里云oss

官方文档:获取二维码

这里使用其中的接口B:适用于需要的码数量极多的业务场景(无限次数)

参数按照接口说明来传,请求成功的话接口会返回输入流,这里将输入流上传至阿里云OSS

以下是部分JAVA代码(有问题可以留言):

public class UploadTest {

@Test

public void upload(){

try {

URL url = new URL("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=你的access_token");

HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

httpURLConnection.setRequestMethod("POST");// 提交模式

// conn.setConnectTimeout(10000);//连接超时 单位毫秒

// conn.setReadTimeout(2000);//读取超时 单位毫秒

// 发送POST请求必须设置如下两行

httpURLConnection.setDoOutput(true);

httpURLConnection.setDoInput(true);

// 获取URLConnection对象对应的输出流

PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());

// 发送请求参数

JSONObject paramJson = new JSONObject();

paramJson.put("scene", "p=1234567890");

paramJson.put("page", "pages/index/index");

paramJson.put("width", 430);

paramJson.put("auto_color", true);

/**

* line_color生效

* paramJson.put("auto_color", false);

* JSONObject lineColor = new JSONObject();

* lineColor.put("r", 0);

* lineColor.put("g", 0);

* lineColor.put("b", 0);

* paramJson.put("line_color", lineColor);

* */

printWriter.write(paramJson.toStringhttp://());

// flush输出流的缓冲

printWriter.flush();

//开始获取数据

//注意 这里上传时文件大小用 HttpResponse.getEntity().getContentLength()

//用 is.available()生成图片会不全,具体参考InputStream.available

AliyunOSSClientUtil.uploadAcode2OSS(httpURLConnection.getInputStream(),"app/demo.png", httpURLConnection.getContentLengthLong()) ;

} catch (Exception e) {

e.printStackTrace();

}

}

}

阿里云oss工具类

import java.io.ByteArrayInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import java.net.URL;

import java.util.Date;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.OSSClient;

import com.aliyun.oss.model.Bucket;

import com.aliyun.oss.model.OSSObject;

import com.aliyun.oss.model.ObjectMetadata;

import com.aliyun.oss.model.PutObjectResult;

/**

*

* @ClassName: AliyunOSSClientUtil

* @Description: 阿里云OSS上传文件模块

* @author 张日天

* @date 2018年7月02日 下午23:01:46

*

*/

public class AliyunOSSClientUtil {

private static Logger logger = LoggerFactory

.getLogger(AliyunOSSClientUtil.class);

// 阿里云API的内或外网域名

private static String ENDPOINT;

// 阿里云API的密钥Access Key ID

private static String ACCESS_KEY_ID;

// 阿里云API的密钥Access Key Secret

private static String ACCESS_KEY_SECRET;

// 阿里云API的bucket名称

private static String BACKET_NAME;

//

private static String FORMATS = OSSClientConstants.FORMATS;

static {

ENDPOINT = SysPropUtils.getPropValue("aliyun.endPoint",

"properties/aliyun.properties");

ACCESS_KEY_ID = SysPropUtils.getPropValue("aliyun.accessKeyId",

"properties/aliyun.properties");

ACCESS_KEY_SECRET = SysPropUtils.getPropValue("aliyun.accessKeySecret",

"properties/aliyun.properties");

BACKET_NAME = SysPropUtils.getPropValue("aliyun.bucketName",

"properties/aliyun.properties");

}

/**

* 上传文件 至 OSS

*

* @param ossClient

* @param is

* @param bucketName

* @param remotePath

* @return

*/

public static String[] uploadObject2OSS(InputStream is, String remotePath) {

String resultStr = null;

String[] fo = new String[] { "", "" };

try {

long start = new Date().getTime();

OSSClient ossClient = getOSSClient();

// 文件大小

// Long fileSize = file.length();

// 创建上传Object的Metadata

ObjectMetadata metadata = new ObjectMetadata();

// 上传的文件的长度

//metadata.setContentLength(is.available());

//System.out.println(is.available());

// 指定该Object被下载时的网页的缓存行为

metadata.setCacheControl("no-cache");

// 指定该Object下设置Header

metadata.setHeader("Pragma", "no-cache");

// 指定该Object被下载时的内容编码格式

metadata.setContentEncoding("utf-8");

// 文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,

// 如果没有扩展名则填默认值application/octet-stream

// metadata.setContentType(getContentType(fileName));

// 指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)

// metadata.setContentDisposition("filename/filesize=" + fileName +

// "/" + fileSize + "Byte.");

// 上传文件 (上传文件流的形式)

PutObjectResult putResult = ossClient.putObject(BACKET_NAME,

remotePath, is, metadata);

// 解析结果

resultStr = putResult.getETag();

fo[1] = remotePath;

fo[0] = resultStr;

// 文件名

logger.info("文件上传成功,上传耗时:"+(new Date().getTime()-start)+"ms,路径为:" + remotePath);

ossClient.shutdown();

} catch (Exception e) {

e.printStackTrace();

logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);

}

return fo;

}

/**

* 上传微信小程序码 至 OSS

* @param is

* @param remotePath

* @param length

* @return

*/

public static String[] uploadAcode2OSS(InputStream is, String remotePath,long length) {

String resultStr = null;

String[] fo = new String[] { "", "" };

try {

long start = new Date().getTime();

OSSClient ossClient = getOSSClient();

// 文件大小

// Long fileSize = file.length();

// 创建上传Object的Metadata

ObjectMetadata metadata = new ObjectMetadata();

// 上传的文件的长度

metadata.setContentLength(length);

//System.out.println(is.available());

// 指定该Object被下载时的网页的缓存行为

metadata.setCacheControl("no-cache");

// 指定该Object下设置Header

metadata.setHeader("Pragma", "no-cache");

// 指定该Object被下载时的内容编码格式

metadata.setContentEncoding("utf-8");

// 文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,

// 如果没有扩展名则填默认值application/octet-stream

// metadata.setContentType(getContentType(fileName));

// 指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)

// metadata.setContentDisposition("filename/filesize=" + fileName +

// "/" + fileSize + "Byte.");

// 上传文件 (上传文件流的形式)

PutObjectResult putResult = ossClient.putObject(BACKET_NAME,

remotePath, is, metadata);

// 解析结果

resultStr = putResult.getETag();

fo[1] = remotePath;

fo[0] = resultStr;

// 文件名

logger.info("文件上传成功,上传耗时:"+(new Date().getTime()-start)+"ms,路径为:" + remotePath);

ossClient.shutdown();

} catch (Exception e) {

e.printStackTrace();

logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);

}

return fo;

}

/**

* 上传文件 至 OSS

*

* @param ossClient

* @param is

* @param bucketName

* @param remotePath

* @return

*/

public static String[] uploadObject2OSS(OSSClient ossClient,

InputStream is, String bucketName, String remotePath) {

String resultStr = null;

String[] fo = new String[] { "", "" };

try {

// 文件大小

// Long fileSize = file.length();

// 创建上传Object的Metadata

ObjectMetadata metadata = new ObjectMetadata();

// 上传的文件的长度

metadata.setContentLength(is.available());

// 指定该Object被下载时的网页的缓存行为

metadata.setCacheControl("no-cache");

// 指定该Object下设置Header

metadata.setHeader("Pragma", "no-cache");

// 指定该Object被下载时的内容编码格式

metadata.setContentEncoding("utf-8");

// 文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,

// 如果没有扩展名则填默认值application/octet-stream

// metadata.setContentType("image/jpeg");

// 指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)

// metadata.setContentDisposition("filename/filesize=" + fileName +

// "/" + fileSize + "Byte.");

// 上传文件 (上传文件流的形式)

PutObjectResult putResult = ossClient.putObject(bucketName,

remotePath, is, metadata);

// 解析结果

resultStr = putResult.getETag();

fo[1] = remotePath;

fo[0] = resultStr;

// 文件名

logger.info("文件上传成功,路径为:" + remotePath);

ossClient.shutdown();

} catch (Exception e) {

e.printStackTrace();

logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);

}

return fo;

}

/**

* 上传图片至OSS 文件流

*

* @param ossClient

* oss连接

* @param file

* 上传文件(文件全路径如:D:\\image\\cake.jpg)

* @param bucketName

* 存储空间

* @param folder

* 模拟文件夹名 如"qj_nanjing/"

* @return String 返回的唯一MD5数字签名

*/

public static String[] uploadObject2OSS(OSSClient ossClient, File file,

String bucketName, String folder) {

String resultStr = null;

String[] fo = new String[] { "", "" };

try {

// 以输入流的形式上传文件

InputStream is = new FileInputStream(file);

// 文件名

String timefile = FORMATS;

String fileName = file.getName();

fileName = timefile + fileName.substring(fileName.lastIndexOf("."));

logger.info("上传到路径" + folder + fileName);

// 文件大小

Long fileSize = file.length();

// 创建上传Object的Metadata

ObjectMetadata metadata = new ObjectMetadata();

// 上传的文件的长度

metadata.setContentLength(is.available());

// 指定该Object被下载时的网页的缓存行为

metadata.setCacheControl("no-cache");

// 指定该Object下设置Header

metadata.setHeader("Pragma", "no-cache");

// 指定该Object被下载时的内容编码格式

metadata.setContentEncoding("utf-8");

// 文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,

// 如果没有扩展名则填默认值application/octet-stream

metadata.setContentType(getContentType(fileName));

// 指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)

metadata.setContentDisposition("filename/filesize=" + fileName

+ "/" + fileSize + "Byte.");

// 上传文件 (上传文件流的形式)

PutObjectResult putResult = ossClient.putObject(bucketName, folder

+ fileName, is, metadata);

// 解析结果

resultStr = putResult.getETag();

fo[1] = folder + fileName;

fo[0] = resultStr;

ossClient.shutdown();

} catch (Exception e) {

e.printStackTrace();

logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);

}

return fo;

}

/**

* 获取阿里云OSS客户端对象

*

* @return ossClient

*/

public static OSSClient getOSSClient() {

return new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

}

/**

* 获取阿里云OSS客户端对象

*

* @param endPoint

* @param accessKeyId

* @param accessKeySecret

* @return

*/

public static OSSClient getOSSClient(String endPoint, String accessKeyId,

String accessKeySecret) {

return new OSSClient(endPoint, accessKeyId, accessKeySecret);

}

/**

* 创建存储空间

*

* @param ossClient

* OSS连接

* @param bucketName

* 存储空间

* @return

*/

pubhttp://lic static String createBucket(OSSClient ossClient, String bucketName) {

// 存储空间

String bucketNames = bucketName;

if (!ossClient.doesBucketExist(bucketName)) {

// 创建存储空间

Bucket bucket = ossClient.createBucket(bucketName);

logger.info("创建存储空间成功");

return bucket.getName();

} else {

logger.info("名为 " + bucketName + " 存储空间已经存在");

}

return bucketNames;

}

/**

* 删除存储空间buckName

*

* @param ossClient

* oss对象

* @param bucketName

* 存储空间

*/

public static void deleteBucket(OSSClient ossClient, String bucketName) {

ossClient.deleteBucket(bucketName);

logger.info("删除" + bucketName + "Bucket成功");

}

/**

* 删除存储空间buckName

*

* @param bucketName

* 存储空间

*/

public static void deleteBucket(String bucketName) {

getOSSClient().deleteBucket(bucketName);

logger.info("删除" + bucketName + " Bucket成功");

}

/**

* 创建模拟文件夹

*

* @param ossClient

* oss连接

* @param bucketName

* 存储空间

* @param folder

* 模拟文件夹名如"anhui/hefei/"

* @return 文件夹名

*/

public static String createFolder(OSSClient ossClient, String bucketName,

String folder) {

// 文件夹名

String keySuffixWithSlash = folder;

// 判断文件夹是否存在,不存在则创建

if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {

// 创建文件夹

ossClient.putObject(bucketName, keySuffixWithSlash,

new ByteArrayInputStream(new byte[0]));

logger.info("创建文件夹成功");

// 得到文件夹名

OSSObject object = ossClient.getObject(bucketName,

keySuffixWithSlash);

String fileDir = object.getKey();

return fileDir;

}

return keySuffixWithSlash;

}

/**

* 根据key删除OSS服务器上的文件

*

* @param ossClient

* oss连接

* @param bucketName

* 存储空间

* @param folder

* 模拟文件夹名 如"anhui/hefei/"

* @param key

* Bucket下的文件的路径名+文件名 如:"demo.jpg"

*/

public static void deleteFile(OSSClient ossClient, String bucketName,

String folder, String key) {

ossClient.deleteObject(bucketName, folder + key);

logger.info("删除" + bucketName + "下的文件" + folder + key + "成功");

}

/**

* 根据key删除OSS服务器上的文件

*

* @param ossClient

* oss连接

* @param bucketName

* 存储空间

* @param filePath

* Bucket下的文件的路径名+文件名 如:"beijing/demo.jpg"

*/

public static void deleteFile(OSSClient ossClient, String bucketName,

String filePath) {

ossClient.deleteObject(bucketName, filePath);

logger.info("删除" + bucketName + "下的文件 " + filePath + " 成功");

}

/**

* 获得url链接

*

* @param key

* @return

*/

public static String getUrl(OSSClient ossClient, String bucketName,

String fileName) {

// 设置URL过期时间为10年 3600l*60*24*365*10

Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24

* 365 * 10);

// 生成URL

// ossClient.gen

URL url = ossClient.generatePresignedUrl(bucketName, fileName,

expiration);

if (url != null) {

return url.toString();

}

return "获网址路径出错";

}

/**

* 通过文件名判断并获取OSS服务文件上传时文件的contentType

*

* @param fileName

* 文件名

* @return 文件的contentType

*/

public static String getContentType(String fileName) {

// 文件的后缀名

String fileExtension = fileName.substring(fileName.lastIndexOf("."));

if (".bmp".equalsIgnoreCase(fileExtension)) {

return "image/bmp";

}

if (".gif".equalsIgnoreCase(fileExtension)) {

return "image/gif";

}

if (".jpeg".equalsIgnoreCase(fileExtension)

|| ".jpg".equalsIgnoreCase(fileExtension)

|| ".png".equalsIgnoreCase(fileExtension)) {

return "image/jpeg";

}

if (".html".equalsIgnoreCase(fileExtension)) {

return "text/html";

}

if (".txt".equalsIgnoreCase(fileExtension)) {

return "text/plain";

}

if (".vsd".equalsIgnoreCase(fileExtension)) {

return "application/vnd.visio";

}

if (".ppt".equalsIgnoreCase(fileExtension)

|| "pptx".equalsIgnoreCase(fileExtension)) {

return "application/vnd.ms-powerpoint";

}

if (".doc".equalsIgnoreCase(fileExtension)

|| "docx".equalsIgnoreCase(fileExtension)) {

return "application/msword";

}

if (".xml".equalsIgnoreCase(fileExtension)) {

return "text/xml";

}

if (".mp4".equalsIgnoreCase(fileExtension)) {

return "video/mp4";

}

// 默认返回类型

return "image/jpeg";

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:阿里云服务器buff/cache占用内存过高问题
下一篇:sentinel-1.8版本找不到UrlBlockHandler接口,如何自定义错误页面?
相关文章

 发表评论

暂时没有评论,来抢沙发吧~