在Java后台获取小程序的小程序码,传递到前端显示图片

8 篇文章 0 订阅
7 篇文章 0 订阅

步骤:

1.需要准备的参数 

accessToken :小程序的临时凭证,需要它才可以任意的调用小程序的各种接口

appid:小程序的ID,微信公众平台上有。为了获取accessToken 而存在

secret:小程序的密匙,微信公众平台上有。为了获取accessToken 而存在

grant_type:获取accessToken时的固定参数。为了获取accessToken 而存在

获取accessToken 的接口:https://api.weixin.qq.com/cgi-bin/token。为了获取accessToken 而存在

获取的代码

import com.alibaba.fastjson.JSONObject;
import java.net.HttpURLConnection;
import java.net.URL


String appid = "";  // 根据不同的小程序appid填写,一下同理
String secret = "";
String accessTokenURL = "";
Map<String, String> requestParam = new HashMap<String,String>();
requestParam.put("grant_type", "client_credential");
requestParam.put("appid", appid);
requestParam.put("secret", secret);
// sendPost 为一个请求各种接口而封装的函数,并转换JSON字符串为JSONObject
JSONObject jsonObject = JSON.parseObject(sendPost(accessTokenURL, requestParam));
String access_token = jsonObject.getString("access_token")


/**
 * 向指定 URL 发送POST方法的请求
 * 
 * @param url 发送请求的 URL
 * @param param 请求参数
 * @return 所代表远程资源的响应结果
 */
public static String sendPost(String url, Map<String, ?> paramMap) {
	//URLConnection conn = null;  // 默认返回 HTTPS
	HttpURLConnection conn = null;  // 默认返回HTTP,用爸爸接收返回数据
	PrintWriter out = null;
	BufferedReader in = null;
	String result = "";
	
	String param = "";
	Iterator<String> it = paramMap.keySet().iterator();
	
	while(it.hasNext()) {
		String key = it.next();
		param += key + "=" + paramMap.get(key) + "&";
	}
	
	try {
		URL realUrl = new URL(url);
		// 打开和URL之间的连接
		conn = (HttpURLConnection) realUrl.openConnection();  // 返回对象为 HttpsURLConnection,儿子的儿子
		// 设置通用的请求属性
		conn.setRequestProperty("accept", "*/*");
		conn.setRequestProperty("connection", "Keep-Alive");
		conn.setRequestProperty("Accept-Charset", "utf-8");
		conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
		// 超时设置,防止 网络异常的情况下,可能会导致程序僵死而不继续往下执行
		conn.setConnectTimeout(3000);
		conn.setReadTimeout(3000);
		// 发送POST请求必须设置如下两行
		conn.setDoOutput(true);
		conn.setDoInput(true);
		// 获取URLConnection对象对应的输出流
		out = new PrintWriter(conn.getOutputStream());
		// 发送请求参数
		out.print(param);
		// flush输出流的缓冲
		out.flush();
		// 定义BufferedReader输入流来读取URL的响应
		in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
		String line;
		while ((line = in.readLine()) != null) {
			result += line;
		}
	} catch (Exception e) {
		logger.error(e.getMessage(), e);
	}
	//使用finally块来关闭输出流、输入流
	finally{
		try{
			if(out!=null){
				out.close();
			}
			if(in!=null){
				in.close();
			}
			if(conn !=null){
				conn.disconnect();
			}
		}
		catch(IOException ex){
			ex.printStackTrace();
		}
	}
	return result;  // 返回的为JSON字符串
}

上面已经获取到 access_token

/**
 * 获取小程序码
 */
@SuppressWarnings("restriction")
@Override
public String getWXQrcode(String access_token, String page, String scene, Integer width) {
        String qrcodeUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";  // 获取小程序码的接口头部
	String url = qrcodeUrl+"?access_token="+access_token;  // 拼接完整的URl
	Map<String, Object> requestParam = new HashMap<String,Object>();  // 小程序的参数可查看官方文档
	if(page!= null) requestParam.put("page", page);  // 扫码后需要跳转的页面
	if(scene!= null) requestParam.put("scene", scene);  // 携带的参数
	if(width!= null) requestParam.put("width", width);  // 二维码的宽度
	String param = JSON.toJSONString(requestParam);
	
    // 使用 RestTemplate 出现的问题,用该类代码会更简洁
	// rest debugger发过来的content-type为application/json,而jq的多了charset=utf-8
	// Could not read document: Invalid UTF-8 middle byte 0xff
	/*JSONObject jsonObject = 
			restTemplate.postForObject(url, param, JSONObject.class);
	System.out.println(jsonObject.toJSONString());*/
	
	HttpURLConnection conn = null;
	BufferedReader bufferedReader = null;
	PrintWriter out = null;
	InputStream in = null;
	ByteArrayOutputStream bos = null;
	String base64String = "";
	try {
		URL realUrl = new URL(url);
		// 打开和URL之间的连接
		conn = (HttpURLConnection) realUrl.openConnection();
		// 设置通用的请求属性
		conn.setRequestProperty("accept", "*/*");
		conn.setRequestProperty("connection", "Keep-Alive");
		conn.setRequestProperty("Accept-Charset", "UTF-8");
		conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
		// 超时设置,防止 网络异常的情况下,可能会导致程序僵死而不继续往下执行
		conn.setConnectTimeout(3000);
		conn.setReadTimeout(3000);
		// 发送POST请求必须设置如下两行
		conn.setDoOutput(true);
		conn.setDoInput(true);
		// 获取URLConnection对象对应的输出流
		out = new PrintWriter(conn.getOutputStream());
		// 发送请求参数
		out.print(param);
		// flush输出流的缓冲
		out.flush();
		
		in = conn.getInputStream();  // 得到图片的二进制内容
		int leng = in.available();  // 获取二进制流的长度,该方法不准确
		if(leng < 1000){  // 出现错误时,获取字符长度就一百不到,图片的话有几万的长度
			// 定义BufferedReader输入流来读取URL的响应
			bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			String line;
			String result = "";
			while ((line = bufferedReader.readLine()) != null) {
				result += line;
			}
			logger.debug("获取access_token出错:"+result);
			// 清空 access_token 缓存
			CacheManagerImpl cacheManagerImpl = CacheManagerImpl.getInstance();
			cacheManagerImpl.clearByKey("access_token");
			return result;
		}
		
		// 修改图片的分辨率,分辨率太大打印纸不够大
		//BufferedInputStream in2 = new BufferedInputStream(conn.getInputStream());
		// 将文件二进制流修改为图片流
		Image srcImg = ImageIO.read(in);
		// 构建图片流
		BufferedImage buffImg = new BufferedImage(width, width, BufferedImage.TYPE_INT_RGB);
		//绘制改变尺寸后的图
		buffImg.getGraphics().drawImage(srcImg.getScaledInstance(width, width, Image.SCALE_SMOOTH), 0, 0, null);
		// 将图片流修改为文件二进制流
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		ImageIO.write(buffImg, "png", os);
		in = new ByteArrayInputStream(os.toByteArray());
		// 刷新,将重置为类似于首次创建时的状态
		buffImg.flush();
		srcImg.flush();
		// 设null是告诉jvm此资源可以回收
		buffImg = null;  // 该io流不存在关闭函数
		srcImg = null;  // 该io流不存在关闭函数
		os.close();
		
		bos = new ByteArrayOutputStream();
		byte[] b1 = new byte[1024];
		int len = -1;
		while((len = in.read(b1)) != -1) {
			bos.write(b1, 0, len);
		}
		byte[] fileByte = bos.toByteArray();  // 转换为字节数组,方便转换成base64编码
		
		//BASE64Encoder encoder = new BASE64Encoder();   // import sun.misc.BASE64Encoder;  该类包为内部专用以后可能会删除,sun公司
		// 对字节数组转换成Base64字符串
		//base64String = encoder.encode(fileByte);
		
		base64String = Base64.encodeBase64String(fileByte);  // import org.apache.commons.codec.binary.Base64;
	} catch (Exception e) {
		logger.error(e.getMessage(), e);
	}
	//使用finally块来关闭输出流、输入流
	finally{
		try {
			if(bufferedReader != null){
				bufferedReader.close();
			}
			if(out!=null){
				out.close();
			}
			if(in!=null){
				in.close();
			}
			if(bos != null){
				bos.close();
			}
			if(conn !=null){
				conn.disconnect();
				conn = null;
			}
			//让系统回收资源,但不一定是回收刚才设成null的资源,可能是回收其他没用的资源。
			System.gc();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	return base64String;  // 将base64格式的图片发送到前端
}

2.前端的页面:

HTML:

<img id="imgQRcode">

Javascript:

let srcData = "data:image/png;base64,"+base64String;  // base64String 为后台传递过来的base64格式的图片,拼接上图片头部即可正常显示
$('#imgQRcode').attr("src", srcData);  // 为img标签的src地址赋值

3.微信扫码后:

在填写的page,进入页面的onLoad生命周期可接受到传递参数

/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
    console.log(options)
}

然后就可以根据等到的参数为所欲为了。

当然了也可以下载二维码的电子图片:参考另一篇文章:https://blog.csdn.net/LZD30/article/details/80783952

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值