您的位置:首页 > 移动开发 > 微信开发

JAVA 微信公众号调用摄像头并上传图片至服务器

2017-06-15 09:24 411 查看

一、主体思想

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息