微信小程序 获取二维码(小程序码)并将图片保存到本地遇到的生成文件无法打开的问题

_Slience_ 2018-03-06 04:50:59
用的是微信的B接口https://api.weixin.qq.com/wxa/getwxacodeunlimit
返回的东西直接输出到控制台是乱码,就像用记事本打开一张图片一样,用普通FileOutputStream out... out.write(byt)那套生成的图片无法打开,请问应该如何才能将图片保存到本地
在PostMan中用代码中的参数是可以正确生成并显示小程序码的
附上微信的开发文档链接:https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html
...全文
9435 1 收藏 20
写回复
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
感谢楼主和正解
回复
VitoYi 2020-06-10
感谢楼主,9楼正解
回复
洛川 gitku.cn 2020-06-10
加入了 创建 文件夹,和 图片命名 ,放到自己的项目里,调用 getQrcode 传参就可以了

package mygirl.com.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HTTP;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;

public class CreateQrcode {

    /**
     * 生成带参小程序二维码
     * @param access_token
     * @param params
     * @param filePath
     * @return
     * @throws Exception
     */
    public static String getQrcode(String access_token, Map params,String filePath) throws Exception {
            long time=System.currentTimeMillis();
            File dirFile = new File(filePath+ymdString());
            if (!dirFile.exists()) {
                dirFile.mkdirs(); //如果目录不存在则创建此目录
            }
            String newFilePath = filePath+ymdString()+time+".JPG";
            saveQrcode(access_token,params,newFilePath);
            return newFilePath;
    }

    //获取当前日期 2019/10/12 建立三级目录
    public static String ymdString() {
        LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
        String year = String.valueOf(ldt.getYear());
        String month = String.valueOf(ldt.getMonthValue());
        String day = String.valueOf(ldt.getDayOfMonth());
        return year + "\\" + month + "\\" + day+"\\";
    }
    /**
     *  二进制生成二维码图片
     * @param access_token
     * @param params
     * @throws Exception
     */
    public static void saveQrcode(String access_token, Map params,String filePath) throws Exception{

        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token);
        httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
        String body = JSON.toJSONString(params);
        StringEntity entity;
        entity = new StringEntity(body);
        entity.setContentType("image/png");

        httpPost.setEntity(entity);
        HttpResponse response;

        response = httpClient.execute(httpPost);
        InputStream inputStream = response.getEntity().getContent();

//        File targetFile = new File(filePath);
//        if(!targetFile.exists()){
//            targetFile.mkdirs();
//        }
        FileOutputStream out = new FileOutputStream(filePath);

        byte[] buffer = new byte[8192];
        int bytesRead = 0;
        while((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
            out.write(buffer, 0, bytesRead);
        }

        out.flush();
        out.close();
    }
}


回复
洛川 gitku.cn 2020-06-10
回复
洛川 gitku.cn 2020-06-10
我用了,可以了打正常生成,小程序没有发布,page 里不要写东西,填空,线上的发布了就可以了填了,
回复
zmnkdyw 2020-04-27
生成的图片无法打开,‘暂不支持打开此图片’,是因为小程序没有发布吗?
回复
lydiajia 2019-11-22
昨天搞了一晚上,看上面的这个方法终于搞定了。十分感谢~~
回复
Emws 2019-07-30
引用 9 楼 _Slience_ 的回复:
已解决,最后用以下方法进行处理可以达到效果

package com.wx.scooter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HTTP;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wx.scooter.tool.CheckTool;
import com.wx.scooter.tool.Constant;
import com.wx.scooter.tool.HttpTool;

public class TestQR {
	public static void main(String[] args) throws Exception {
		//获取token
		String result1 = HttpTool.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+Constant.NATIVE_APP_ID+"&secret="+Constant.NATIVE_APP_SECRET);
		String access_token = JSONObject.parseObject(result1).getString("access_token");
		if(CheckTool.isString(access_token)) {
			System.out.println("token为");
			System.out.println(access_token);
			Map<String, Object> params = new HashMap<>();
			params.put("scene", "test");
			params.put("page", "pages/index/index");
			params.put("width", 430);

			CloseableHttpClient  httpClient = HttpClientBuilder.create().build();

			HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token);
			httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
			String body = JSON.toJSONString(params);
			StringEntity entity;
			entity = new StringEntity(body);
			entity.setContentType("image/png");

			httpPost.setEntity(entity);
			HttpResponse response;
			
			response = httpClient.execute(httpPost);
			InputStream inputStream = response.getEntity().getContent();

			File targetFile = new File("D:\\");  
			if(!targetFile.exists()){    
				targetFile.mkdirs();    
			}       
			FileOutputStream out = new FileOutputStream("D:\\upload\\5.png");

			byte[] buffer = new byte[8192];
			int bytesRead = 0;
			while((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
				out.write(buffer, 0, bytesRead);
			}

			out.flush();
			out.close();
		} else {
			System.out.println("获取access_token错误");
		}
	}
}

确实解决了,谢谢
回复
惊云丶 2019-07-10
楼主为什么我用你这个方法有时候生成不了
回复
Aaryn30 2018-04-09
楼主为什么我是用你的解决方案还是有问题呢,可以帮忙看一下问题出在哪里吗,是不是因为小程序上线的问题
回复
_Slience_ 2018-03-11
已解决,最后用以下方法进行处理可以达到效果

package com.wx.scooter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HTTP;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wx.scooter.tool.CheckTool;
import com.wx.scooter.tool.Constant;
import com.wx.scooter.tool.HttpTool;

public class TestQR {
	public static void main(String[] args) throws Exception {
		//获取token
		String result1 = HttpTool.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+Constant.NATIVE_APP_ID+"&secret="+Constant.NATIVE_APP_SECRET);
		String access_token = JSONObject.parseObject(result1).getString("access_token");
		if(CheckTool.isString(access_token)) {
			System.out.println("token为");
			System.out.println(access_token);
			Map<String, Object> params = new HashMap<>();
			params.put("scene", "test");
			params.put("page", "pages/index/index");
			params.put("width", 430);

			CloseableHttpClient  httpClient = HttpClientBuilder.create().build();

			HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token);
			httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
			String body = JSON.toJSONString(params);
			StringEntity entity;
			entity = new StringEntity(body);
			entity.setContentType("image/png");

			httpPost.setEntity(entity);
			HttpResponse response;
			
			response = httpClient.execute(httpPost);
			InputStream inputStream = response.getEntity().getContent();

			File targetFile = new File("D:\\");  
			if(!targetFile.exists()){    
				targetFile.mkdirs();    
			}       
			FileOutputStream out = new FileOutputStream("D:\\upload\\5.png");

			byte[] buffer = new byte[8192];
			int bytesRead = 0;
			while((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
				out.write(buffer, 0, bytesRead);
			}

			out.flush();
			out.close();
		} else {
			System.out.println("获取access_token错误");
		}
	}
}

回复
Sunyiban 2018-03-09
引用 7 楼 u010513756 的回复:
[quote=引用 5 楼 u011594442 的回复:] 把你拼的URL放进去就行了~
参数放进去了,输出出来的是一堆乱码,就像用记事本打开图片似的。 不过生成的文件还是和以前一样打不开,求助,感惜[/quote] 什么样的乱码,发来看看
回复
_Slience_ 2018-03-09
引用 5 楼 u011594442 的回复:
把你拼的URL放进去就行了~
参数放进去了,输出出来的是一堆乱码,就像用记事本打开图片似的。 不过生成的文件还是和以前一样打不开,求助,感惜
回复
_Slience_ 2018-03-09
拼在URL会微信那边报这个错误——{"errcode":44002,"errmsg":"empty post data hint: [3ONdKA06804525]"}
回复
_Slience_ 2018-03-09
引用 3 楼 u011594442 的回复:
[quote=引用 2 楼 u010513756 的回复:] [quote=引用 1 楼 u011594442 的回复:] 你怎么转换的,应该是流处理写的 有问题吧
我是这样获取转换的
//获取token
		String result1 = HttpTool.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+Constant.NATIVE_APP_ID+"&secret="+Constant.NATIVE_APP_SECRET);
		String access_token = JSONObject.parseObject(result1).getString("access_token");
		if(CheckTool.isString(access_token)) {
			System.out.println(access_token);
			Map<String, Object> params = new HashMap<>();
			params.put("scene", "test");
			params.put("page", "pages/index/index");
			params.put("width", 430);
			StringHttpMessageConverter m = new StringHttpMessageConverter(Charset.forName("UTF-8"));
			RestTemplate restTemplate=new RestTemplateBuilder().additionalMessageConverters(m).build();
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.IMAGE_JPEG);
			HttpEntity<String> entity = new HttpEntity<String>(JSON.toJSONString(params), headers);
			ResponseEntity<String> result = restTemplate.exchange("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token, HttpMethod.POST, entity, String.class);
			
			
			try {
//				System.out.println(result);
				//将返回的数据保存到本地
		        File targetFile = new File("D:\\");  
		        if(!targetFile.exists()){    
		            targetFile.mkdirs();    
		        }       
		        FileOutputStream out = new FileOutputStream("D:\\upload\\1.png");
		        out.write(result.getBody().getBytes());
		        out.flush();
		        out.close();
		        
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			System.out.println("获取access_token错误");
		}
[/quote]
URL url = null;
        HttpURLConnection connection = null;
        try {
            url = new URL( "");
            System.out.println(url);
            connection = (HttpURLConnection) url.openConnection();// 新建连接实例
            connection.setConnectTimeout(2000);// 设置连接超时时间,单位毫秒
            connection.setReadTimeout(2000);// 设置读取数据超时时间,单位毫秒
            connection.setDoInput(true);// 是否打开输出 true|false
            connection.setRequestMethod("POST");// 提交方法POST|GET
            connection.setUseCaches(false);// 是否缓存true|false
            connection.connect();// 打开连接端口
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            reader.close();
            System.out.println(buffer.toString());

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            if (connection != null) {
                connection.disconnect();// 关闭连接
            }
        }
你试试这种写法,我的微信没有授权,所以图片那个请求过不去~你可以输出下看看他的返回内容格式[/quote] 问一下,这种方法怎么传参?
回复
Sunyiban 2018-03-09
把你拼的URL放进去就行了~
回复
Sunyiban 2018-03-09
引用 2 楼 u010513756 的回复:
[quote=引用 1 楼 u011594442 的回复:] 你怎么转换的,应该是流处理写的 有问题吧
我是这样获取转换的
//获取token
		String result1 = HttpTool.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+Constant.NATIVE_APP_ID+"&secret="+Constant.NATIVE_APP_SECRET);
		String access_token = JSONObject.parseObject(result1).getString("access_token");
		if(CheckTool.isString(access_token)) {
			System.out.println(access_token);
			Map<String, Object> params = new HashMap<>();
			params.put("scene", "test");
			params.put("page", "pages/index/index");
			params.put("width", 430);
			StringHttpMessageConverter m = new StringHttpMessageConverter(Charset.forName("UTF-8"));
			RestTemplate restTemplate=new RestTemplateBuilder().additionalMessageConverters(m).build();
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.IMAGE_JPEG);
			HttpEntity<String> entity = new HttpEntity<String>(JSON.toJSONString(params), headers);
			ResponseEntity<String> result = restTemplate.exchange("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token, HttpMethod.POST, entity, String.class);
			
			
			try {
//				System.out.println(result);
				//将返回的数据保存到本地
		        File targetFile = new File("D:\\");  
		        if(!targetFile.exists()){    
		            targetFile.mkdirs();    
		        }       
		        FileOutputStream out = new FileOutputStream("D:\\upload\\1.png");
		        out.write(result.getBody().getBytes());
		        out.flush();
		        out.close();
		        
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			System.out.println("获取access_token错误");
		}
[/quote]
URL url = null;
        HttpURLConnection connection = null;
        try {
            url = new URL( "");
            System.out.println(url);
            connection = (HttpURLConnection) url.openConnection();// 新建连接实例
            connection.setConnectTimeout(2000);// 设置连接超时时间,单位毫秒
            connection.setReadTimeout(2000);// 设置读取数据超时时间,单位毫秒
            connection.setDoInput(true);// 是否打开输出 true|false
            connection.setRequestMethod("POST");// 提交方法POST|GET
            connection.setUseCaches(false);// 是否缓存true|false
            connection.connect();// 打开连接端口
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            reader.close();
            System.out.println(buffer.toString());

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            if (connection != null) {
                connection.disconnect();// 关闭连接
            }
        }
你试试这种写法,我的微信没有授权,所以图片那个请求过不去~你可以输出下看看他的返回内容格式
回复
_Slience_ 2018-03-09
引用 1 楼 u011594442 的回复:
你怎么转换的,应该是流处理写的 有问题吧
我是这样获取转换的
//获取token
		String result1 = HttpTool.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+Constant.NATIVE_APP_ID+"&secret="+Constant.NATIVE_APP_SECRET);
		String access_token = JSONObject.parseObject(result1).getString("access_token");
		if(CheckTool.isString(access_token)) {
			System.out.println(access_token);
			Map<String, Object> params = new HashMap<>();
			params.put("scene", "test");
			params.put("page", "pages/index/index");
			params.put("width", 430);
			StringHttpMessageConverter m = new StringHttpMessageConverter(Charset.forName("UTF-8"));
			RestTemplate restTemplate=new RestTemplateBuilder().additionalMessageConverters(m).build();
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.IMAGE_JPEG);
			HttpEntity<String> entity = new HttpEntity<String>(JSON.toJSONString(params), headers);
			ResponseEntity<String> result = restTemplate.exchange("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token, HttpMethod.POST, entity, String.class);
			
			
			try {
//				System.out.println(result);
				//将返回的数据保存到本地
		        File targetFile = new File("D:\\");  
		        if(!targetFile.exists()){    
		            targetFile.mkdirs();    
		        }       
		        FileOutputStream out = new FileOutputStream("D:\\upload\\1.png");
		        out.write(result.getBody().getBytes());
		        out.flush();
		        out.close();
		        
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			System.out.println("获取access_token错误");
		}
回复
Sunyiban 2018-03-07
你怎么转换的,应该是流处理写的 有问题吧
回复
发动态
发帖子
Java EE
创建于2007-09-28

6.6w+

社区成员

J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
申请成为版主
社区公告
暂无公告