JAVA 微信公众号调用摄像头并上传图片至服务器
来源:互联网 发布:php 返回页面 编辑:程序博客网 时间:2024/05/15 17:17
一、主体思想
1.使用微信JS-SDK工具包。
点击button,调用拍照接口【chooseImage】和上传图片接口【uploadImage】,拿到图片的服务器端ID,即【mediaId】
2.调用【获取临时素材】接口(参数mediaId),拿到返回的流,保存到服务器。
官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455784140&token=&lang=zh_CN
二、实现步骤(为了整体性,部分复制文档)
1.绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
例如:blog.csdn.net
2.在需要调用摄像头页面,引入JS文件
<!-- jquery 非必须 --><script src="<%=request.getContextPath()%>/staticfile/js/jquery.min.js"></script><script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
3.通过config接口注入权限验证配置
<input type="hidden" id="appId" value="${appId }"/><input type="hidden" id="timestamp" value="${timestamp }"/><input type="hidden" id="nonceStr" value="${nonceStr }"/><input type="hidden" id="signature" value="${signature }"/>
<script>$(function(){ wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: $('#appId').val(), // 必填,公众号的唯一标识 timestamp: $('#timestamp').val(), // 必填,生成签名的时间戳 nonceStr: $('#nonceStr').val(), // 必填,生成签名的随机串 signature: $('#signature').val(),// 必填,签名,见附录1 jsApiList: ['chooseImage', 'uploadImage'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 });});</script>
4.JS-SDK使用权限签名算法,生成第三步中 config接口 所需参数
注意:java代码使用jfinal3.1框架,使用到的缓存插件、参数获取等语法不一致,自适应相应修改。
获取access_token(官方:有效期7200秒,开发者必须在自己的服务全局缓存access_token)、jsapi_ticket、签名sign
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;
public class XXX{ private static final Logger log = LoggerFactory.getLogger(XXX.class); private static final String JSAPI_TICKET_CACHE = "jsapiTicketCache"; private static final String JSAPI_TICKET_CACHE_KEY = "jsapi_ticket"; private static final String ACCESS_TOKEN_CACHE = "accessTokenCache"; private static final String ACCESS_TOKEN_CACHE_KEY = "access_token"; /** * 获取config接口 所需参数 */ public void index() { /** * 以下5行代码,是拼接 访问该方法的参数列表。 * * 生成签名sign时,参数url必须是完整的。 * 例如: http://blog.csdn.net?a=1&b=2 */ //request.getParameterMap(); Map paramMap = getParaMap(); String paramUrl = ""; if (!paramMap.isEmpty() && paramMap != null) { paramUrl = getParamsStr(paramMap); } log.info("paramUrl-->{}", paramUrl); /** * 1、获取jsapi_ticket */ String jsapi_ticket = CacheKit.get(JSAPI_TICKET_CACHE, JSAPI_TICKET_CACHE_KEY); if (StrKit.isBlank(jsapi_ticket)) { String access_token = getAccessToken(); log.info("access_token-->{}", access_token); jsapi_ticket = getJsapiTicket(access_token); CacheKit.put(JSAPI_TICKET_CACHE, JSAPI_TICKET_CACHE_KEY, jsapi_ticket); } log.info("jsapi_ticket-->{}", jsapi_ticket); /** * 2、生成签名 */ SortedMap<Object, Object> params = new TreeMap<Object, Object>(); String noncestr = WeixinSignUtil.getNonceStr(); String timestamp = WeixinSignUtil.getTimestamp(); params.put("noncestr", noncestr); params.put("jsapi_ticket", jsapi_ticket); params.put("timestamp", timestamp); if (StrKit.isBlank(paramUrl)) { params.put("url", AppConsts.JSSDKURL); } else { params.put("url", AppConsts.JSSDKURL + "?" + paramUrl); } String sign = WeixinSignUtil.createSignBySha1(params); log.info("sign-->{}", sign); setAttr("appId", AppConsts.APPID); setAttr("timestamp", timestamp); setAttr("nonceStr", noncestr); setAttr("signature", sign); render("jsp/index.jsp"); } private String getParamsStr(Map paramMap) { StringBuffer sb = new StringBuffer(); Set set = paramMap.entrySet(); Iterator it = set.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String[] v = (String[]) entry.getValue(); for (String s : v) { sb.append(k + "=" + s + "&"); } } return sb.toString().substring(0, sb.toString().length() - 1); } private String getAccessToken() { String access_token = CacheKit.get(ACCESS_TOKEN_CACHE, ACCESS_TOKEN_CACHE_KEY); if (StrKit.isBlank(access_token)) { String url = "https://api.weixin.qq.com/cgi-bin/token"; String params = "grant_type=client_credential&appid=" + AppConsts.APPID + "&secret=" + AppConsts.APPSECRET; //http GET方式爬虫 String result = HttpURLContent.sendGet(url, params); JSONObject jo = JSON.parseObject(result); access_token = jo.getString("access_token"); CacheKit.put(ACCESS_TOKEN_CACHE, ACCESS_TOKEN_CACHE_KEY, access_token); } return access_token; } private String getJsapiTicket(String access_token) { String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"; String params = "access_token=" + access_token + "&type=jsapi"; String result = HttpURLContent.sendGet(url, params); JSONObject jo = JSON.parseObject(result); return jo.getString("ticket"); }}
WeixinSignUtil.java
package org.cold.util;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.SortedMap;/** * 微信签名工具类 * @author cold * */public class WeixinSignUtil { @SuppressWarnings("rawtypes") public static String createSignBySha1(SortedMap<Object, Object> params) { StringBuffer sb = new StringBuffer(); Set es = params.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String v = (String) entry.getValue(); if (v != null && !v.equals("")) { sb.append(k + "=" + v + "&"); } } String result = sb.toString().substring(0, sb.toString().length()-1); return Sha1.getSha1(result); } /** * 获取时间戳(秒) */ public static String getTimestamp() { return String.valueOf(System.currentTimeMillis() / 1000); } /** * 取出一个指定长度大小的随机正整数. * @param length * int 设定所取出随机数的长度。length小于11 * @return int 返回生成的随机数。 */ public static int buildRandom(int length) { int num = 1; double random = Math.random(); if (random < 0.1) { random = random + 0.1; } for (int i = 0; i < length; i++) { num = num * 10; } return (int) ((random * num)); } /** * 获取当前时间 yyyyMMddHHmmss */ public static String getCurrTime() { Date now = new Date(); SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String s = outFormat.format(now); return s; } /** * 生成随机字符串 */ public static String getNonceStr() { String currTime = getCurrTime(); String strTime = currTime.substring(8, currTime.length()); String strRandom = buildRandom(4) + ""; return strTime + strRandom; }}
5.调用摄像头,获取 mediaId
<button onclick="takePicture()">拍照</button>
<script>function takePicture(){ wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 success: function (res) { var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 wx.uploadImage({ localId: localIds.toString(), // 需要上传的图片的本地ID,由chooseImage接口获得 isShowProgressTips: 1, // 默认为1,显示进度提示 success: function (res) { var mediaId = res.serverId; // 返回图片的服务器端ID,即mediaId //将获取到的 mediaId 传入后台 方法savePicture $.post("<%=request.getContextPath()%>/savePicture",{mediaId:mediaId},function(res){ if(res.t == 'success'){ }else{ alert(res.msg) } }) }, fail: function (res) { alertModal('上传图片失败,请重试') } }); } });}</script>
6.后台接受参数mediaId,保存图片至服务器
public void savePicture() { // request.getParameter("mediaId") String mediaId = getPara("mediaId", ""); //保存图片 路径 PathKit.getWebRootPath() + "/vehicleupload/" + filename; String filename = saveImageToDisk(mediaId); setAttr("t", "success"); renderJson();}/** * 获取临时素材 */private InputStream getMedia(String mediaId) { String url = "https://api.weixin.qq.com/cgi-bin/media/get"; String access_token = getAccessToken(); String params = "access_token=" + access_token + "&media_id=" + mediaId; InputStream is = null; try { String urlNameString = url + "?" + params; URL urlGet = new URL(urlNameString); HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); http.setRequestMethod("GET"); // 必须是get方式请求 http.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); http.setDoOutput(true); http.setDoInput(true); http.connect(); // 获取文件转化为byte流 is = http.getInputStream(); } catch (Exception e) { e.printStackTrace(); } return is;}/** * 保存图片至服务器 * @param mediaId * @return 文件名 */public String saveImageToDisk(String mediaId){ String filename = ""; InputStream inputStream = getMedia(mediaId); byte[] data = new byte[1024]; int len = 0; FileOutputStream fileOutputStream = null; try { //服务器存图路径 String path = PathKit.getWebRootPath() + "/vehicleupload/"; filename = System.currentTimeMillis() + WeixinSignUtil.getNonceStr() + ".jpg"; fileOutputStream = new FileOutputStream(path + filename); while ((len = inputStream.read(data)) != -1) { fileOutputStream.write(data, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return filename;}
阅读全文
2 0
- JAVA 微信公众号调用摄像头并上传图片至服务器
- 微信公众号上传图片
- 微信公众号上传图片接口
- 微信公众号图片上传至阿里云OSS
- phoneGap API调用摄像头并上传图片
- 微信公众号调用上传永久素材接口
- JAVA微信公众号开发——上传图片,新增永久素材,群发
- 微信公众号上传图片那些问题
- 微信公众号页面调用拍照上传图片,包括预览没文件压缩,还有扫码功能
- Java 微信公众号上传永久素材的方法
- Java 微信公众号上传永久素材的方法
- java微信公众号开发,文件上传
- java调用微信sdk图片选择上传保存到七牛
- 微信公众平台上传图片,自动回复图片
- # iOS 相册图片多选以及类似微信获取相册图片并使用AFN框架上传至服务器
- 微信公众号新浪百度云做服务器 (上传php文件,开发微信公众平台)
- 微信公众号开发JSSDK上传图片(多图上传)
- 微信支付-公众号支付-JSAPI调用(Java)
- 【JavaScript】创建对象的七种方式
- c++数组名是一个指针常量
- git指令
- Android 编译命令
- Oracle dataguard 正常切换和应急切换
- JAVA 微信公众号调用摄像头并上传图片至服务器
- ★ Eclipse Debug 界面应用详解——Eclipse Debug不为人知的秘密
- windows64位下安装TensorFlow(cpu版本)
- 【Arcgis for android】相关教程收集自网络
- 哲学家就餐问题Java版解决案
- Android6.0中的NativeBridge
- Spring+MyBatis问题集锦2
- 设计模式之解释器模式(Interpreter)
- try-catch语句中return和finally执行顺序详解