使用微信JS-SDK上传图片,下载

使用微信js-sdk,请先详细阅读微信开发文档

JSSDK使用步骤

步骤一:绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

备注:登录后可在“开发者中心”查看对应的接口权限。

步骤二:引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js

备注:支持使用 AMD/CMD 标准模块加载方法加载

步骤三:通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名
    jsApiList: [] // 必填,需要使用的JS接口列表
});

签名算法见文末的附录1,所有JS接口列表见文末的附录2

步骤四:通过ready接口处理成功验证

wx.ready(function(){
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

步骤五:通过error接口处理失败验证

wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});

接口调用说明

所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:

1.success:接口调用成功时执行的回调函数。

2.fail:接口调用失败时执行的回调函数。

3.complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。

4.cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。

5.trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。

备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。

以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:

调用成功时:"xxx:ok" ,其中xxx为调用的接口名

用户取消时:"xxx:cancel",其中xxx为调用的接口名

调用失败时:其值为具体错误信息

图像接口

拍照或从手机相册中选图接口

wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
}
});

预览图片接口

wx.previewImage({
current: '', // 当前显示图片的http链接
urls: [] // 需要预览的图片http链接列表
});

上传图片接口

wx.uploadImage({
localId: '', // 需要上传的图片的本地ID,由chooseImage接口获得
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function (res) {
var serverId = res.serverId; // 返回图片的服务器端ID
}
});

备注:上传图片有效期3天,可用微信多媒体接口下载图片到自己的服务器,此处获得的 serverId 即 media_id。

下载图片接口

wx.downloadImage({
serverId: '', // 需要下载的图片的服务器端ID,由uploadImage接口获得
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function (res) {
var localId = res.localId; // 返回图片下载后的本地ID
}
});

想了解更多接口请阅读微信开发者文档,下面开始码代码

1,所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用,

注入配置信息:

var URIstring=location.href.split('#')[0];//获取当前页面的全路径
var url="/zf/ConfigParam?Rurl="+encodeURIComponent(URIstring);//将路径传入后台加密时使用
$(document).ready(function(){
$.ajax({
url :encodeURI(url),// encodeURI(encodeURI(url)),
type : 'POST',
async: false,
dataType : 'json',
timeout : 5000,
    error: function(XMLHttpRequest, textStatus, errorThrown) {
    alert("不好意思,出了点小问题");
    },
    success : function(req) {
wx.config({
   debug: false,//开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: req.appid, // 必填,公众号的唯一标识
                    timestamp:req.timestamp, // 必填,生成签名的时间戳
   nonceStr: req.nonceStr, // 必填,生成签名的随机串
   signature:req.signature,// 必填,签名,见附录1
   jsApiList:['chooseImage','previewImage','uploadImage','downloadImage',]// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
}); 
}
});

2,使用拍照或从手机相册中选图接口,并上传到微信服务器,然后下载到自己服务器

function updoadpic() {
wx.chooseImage({
count : 3, // 最多能选择多少张图片,默认9
sizeType : [ 'original', 'compressed' ], // 可以指定是原图还是压缩图,默认二者都有
sourceType : [ 'album', 'camera' ], // 可以指定来源是相册还是相机,默认二者都有
success : function(res) {
var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
// 上传图片接口
syncUpload(localIds);
}
});

}

var syncUpload = function(localIds) {
var localId = localIds.pop();
wx.uploadImage({
localId : localId,
isShowProgressTips : 1,
success : function(res) {
var serverId = res.serverId; // 返回图片的服务器端ID
server.push(serverId);
if (localIds.length > 0) {
syncUpload(localIds);
} else {
downloadImage(server);//下载到自己服务器
}
}
});

};


function downloadImage(serverId) {
$.web.AddLoading("上传中...");
var uu ="/zf/UplodWxpic/mediaId=" + serverId;
$.ajax({
url : uu,
async : true,
cache : false,
dataType : 'json',
type : 'GET',
data : {},
success : function(req) {

              server.splice(0, server.length);//删除,清空

                      //上传成功之后的操作

$.web.RemoveLoading();
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
$.web.RemoveLoading();
mui.alert("不好意思,出了点小问题","提示","确定");
}


});

}
后台代码

ConfigParam.java


import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;

public class ConfigParam extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");  
       PrintWriter out = response.getWriter();  

String Rurl=java.net.URLDecoder.decode(request.getParameter("Rurl"),"utf-8");
//System.out.println(Rurl);
Map ret= WeixinUtil.getJSSDKData(Rurl,WechatUtil.appId,WechatUtil.appSecret);
JSONObject json=JSONObject.fromObject(ret);
       //System.out.println(json.toString());
       out.print(json);
}
}
WeixinUtil.java  和AccessToken.java


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 公众平台通用接口工具类
 * 
 * 
 * 
 */
public class WeixinUtil {
private static Log log = LogFactory.getLog(WeixinUtil.class);
// 获取access_token的接口地址(GET) 限200(次/天)
public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?            grant_type=client_credential&appid=APPID&secret=APPSECRET";
private static Map  tokenMap = new HashMap();

/**
* 获取access_token

* @param appid 凭证
* @param appsecret 密钥
* @param flag 是否重新获取
* @return
*/
public static AccessToken getAccessToken(String appid, String appsecret,boolean flag) {

AccessToken accessToken = null;
log.info("=================getAccessToken-start");
if(!flag){
accessToken = tokenMap.get(appid);
}
long now = System.currentTimeMillis();

if(accessToken != null && !flag){

long lastTime = accessToken.getCreateTime();
//当accessToken还在有效期内
if(now <= (lastTime + accessToken.getExpiresIn() * 1000) ){
log.info("读取缓存accessToken=="+accessToken);
return accessToken;
}
}
String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken = new AccessToken();
accessToken.setCreateTime(now);
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInt("expires_in") - 300);
log.info("重新获取accessToken=="+accessToken);
} catch (JSONException e) {
accessToken = null;
// 获取token失败
log.error("获取token失败 errcode:"+jsonObject.getInt("errcode")+" errmsg:{"+ jsonObject.getString("errmsg")+"}" );
}
}
log.info("=================getAccessToken-end");
tokenMap.put(appid, accessToken);

return accessToken;

}

/**
* 获取access_token

* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static AccessToken getAccessToken(String appid, String appsecret ) {
log.info("getAccessToken:重新获取AccessToken");
return getAccessToken(appid, appsecret, true);

}

public static String JS_API_URL =  "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";

 
/**

* @param accessToken
* @return
*/
public static String getJsapi_ticket(String accessToken){
log.info("=====================getJsapi_ticket:start");
    String url = JS_API_URL.replace("ACCESS_TOKEN", accessToken);
    JSONObject json = httpRequest(url, "GET", null);
    log.info("getJsapi_ticket:"+json);
        String jsapi_ticket = "";
        try {
jsapi_ticket = json.getString("ticket");

} catch (Exception e) {
log.error("=====================getJsapi_ticket:error"+json);
e.printStackTrace();
}
    log.info("=====================getJsapi_ticket:end");
        return jsapi_ticket;
    }
//JS SDK  中需要的相关的数据
private  static Map JsSDKMap = new HashMap();

public static String getJsapi_ticket_cache(String accessToken ){


String jsapi = JsSDKMap.get(accessToken);

if(jsapi != null){
log.info("读取jsapi_ticket缓存"+jsapi );
return jsapi;

}else{
jsapi = getJsapi_ticket(accessToken);
log.info("刷新Jsapi_ticket:"+jsapi+"===="+accessToken );
JsSDKMap.put(accessToken, jsapi);
}

        return jsapi;
    }

//获得jsapi_ticket,noncestr,timestamp   
public static  Map getJSSDKData(String requestUrl,String appid,String appsecret){
log.info("=================getJSSDKData-start");
//1)获取access_token
AccessToken accessToken =  getAccessToken(appid, appsecret,false);
String token = accessToken.getToken();
log.info("accessToken:"+accessToken);
//2)获取jsapi_ticket(有效期7200秒
String jsapi_ticket = getJsapi_ticket_cache(token);
log.info("jsapi_ticket:"+jsapi_ticket);
//3)获取//随机字符串 
String noncestr  = Double.toString(Math.random()).substring(2, 15);//随机字符串

//4)获取 随机时间戳
String timeStamp =((int)(new Date().getTime()/1000))+"";//随机时间戳

//5)获取签名
String str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp="+ timeStamp +"&url=" + requestUrl;
log.info("str:" + str);
String signature = SHA1Util.Sha1(str); 
   Map  map =  new HashMap();
   map.put("ticket", jsapi_ticket);
map.put("noncestr", noncestr);
map.put("timestamp", timeStamp);
map.put("signature", signature);
map.put("url", requestUrl);
map.put("appid", appid);
log.info("=================getJSSDKData-end");
return map;

 
/**
* 发起https请求并获取结果

* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
log.error("Weixin server connection timed out.");
} catch (Exception e) {
log.error("https request error:{}", e);
}
return jsonObject;
}

}


/** 
 * 微信通用接口凭证 
 *  
 * 
 * 
 */  
public class AccessToken {  
    // 获取到的凭证  
    private String token;  
    // 凭证有效时间,单位:秒  
    private int expiresIn; 
    
    private long createTime;
  
    public String getToken() {  
        return token;  
    }  
  
    public void setToken(String token) {  
        this.token = token;  
    }  
 
    public int getExpiresIn() {  
        return expiresIn;  
    }  
 
    public void setExpiresIn(int expiresIn) {  
        this.expiresIn = expiresIn;  
    }
public long getCreateTime() {
return createTime;
}


public void setCreateTime(long createTime) {
this.createTime = createTime;
}  

UplodWxpic.java

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");  
       response.setCharacterEncoding("UTF-8");  
       PrintWriter out = response.getWriter(); 
//String mediaId=request.getParameter("mediaId");
Map map = new HashMap();
String mediaId = request.getParameter("mediaId");
String folderName="/app/ss/"+new SimpleDateFormat("yyyy/MMdd/").format(new Date());
try {
File dir = new File(folderName);
if (!dir.exists())
dir.mkdirs();
} catch (Exception ex) {
}
String Str="";
String array[]=mediaId.split(",");//图片可能有多张,每次循环可以将每张上传的图片路径存起来(比如用StringBuilder加逗号),或者直接存入数据库
for (int i = 0; i < array.length; i++) {
String  randstr = UUID.randomUUID().toString().replaceAll("-", "");
String path=folderName+randstr;//绝对路径
String frontName = "" + randstr;//相对路径
String absFileName=path+".jpg";//"D:\\img\\a.jpg";//
String str= DloadImgUtil.downloadMedia(array[i], absFileName,path+"_240.jpg","1");//调用下载接口

}

map.put("status", "1");
map.put("msg",Str);
map.put("path", "");
map.put("photoUrl","");
JSONObject json = JSONObject.fromObject(map);
   out.print(json);
}

DloadImgUtil.java

public class DloadImgUtil {
 
public static String downloadMedia(String mediaId, String savePath,String out,String type) {
String filePath = null;
AccessToken accessToken = WeixinUtil.getAccessToken(WechatUtil.appId,
WechatUtil.appSecret, false);
// 拼接请求地址
String requestUrl = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken.getToken())
.replace("MEDIA_ID", mediaId);
String returnstr="0";
BufferedInputStream bis = null;
FileOutputStream fos = null;
HttpsURLConnection conn = null;
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
// URL url = new URL(null,requestUrl,new
// sun.net.www.protocol.https.Handler());
// URL url = new URL(requestUrl);
URL url = new URL(requestUrl);
conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod("GET");
// 根据内容类型获取扩展名
// String fileExt = DloadImgUtil
// .getFileexpandedName(conn.getHeaderField("Content-Type"));
// 将mediaId作为文件名
filePath = savePath;
bis = new BufferedInputStream(conn.getInputStream());
fos = new FileOutputStream(new File(filePath));
byte[] buf = new byte[8096];
int size = 0;
while ((size = bis.read(buf)) != -1)
fos.write(buf, 0, size);
suof(savePath, out);
  } catch (Exception e) {
  returnstr="-1";
  e.printStackTrace();


} finally {
// 释放资源
conn.disconnect();
try {
// 关闭流,释放资源
if (fos != null) {
fos.close();
}
if (bis != null) {
bis.close();
}


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


}

return returnstr;

}

/**
* 图片缩放                             (thumbnailator.0.4.7.jar)
* @throws IOException 
*/
public static void suof(String inFile, String outFile) throws IOException{
Thumbnails.of(inFile)   
        .size(200, 200)   
        .keepAspectRatio(false)   
        .toFile(outFile);  
}

}

完毕

你可能感兴趣的:(使用微信JS-SDK上传图片,下载)