总路线
调用jssdk,先传到微信,再下载到自己的服务器
一、微信 code获取userId(java),作用:获取用户信息
二、前台拍照调用,选择图片,命名图片,上传图片
三、(java) 从微信服务器下载图片到自己的服务器
一、微信 code获取userId(java)
第一点:本人第一次进行OAuth2.0验证的时候用的是ajax,一个错误的用法
引用一下”流浪的狼“这位大大对我说过的话
code换userid不能ajax. 这是权限验证,举个例子说明一下。你是用户要进入一座青楼,但你没有钥匙怎么办? 腾讯面子大,只要它说你是王公子本来就是熟客,青楼看门的立马放你进去;但你得要腾讯认识你才行啊,这就需要你去腾讯大爷的房间验证一下,你拿条你穿过的裤子给腾大爷(AJAX)是不行的,必须你亲自去腾大爷的房间(跳转),让腾大爷感觉满意,并且确认你就是你。它才开个后门把你塞入青楼。 这样你就完成了不用钥匙开门就进楼的整个过程
感谢他的讲解我才明白权限验证不能用ajax,要用跳转
第二点:微信企业号OAuth2.0的原开发文档:
http://qydev.weixin.qq.com/wiki/index.php?title=OAuth%E9%AA%8C%E8%AF%81%E6%8E%A5%E5%8F%A3
第三点:代码环节
原理:a、点击前台url请求微信服务器
b、微信服务器生成code发送到redirect_uri(后台接口),后台接口进行code换取useId,并返回userId
备注:access_token的获取请看 http://blog.youkuaiyun.com/qq_30240219/article/details/62420356
a、点击url换取code
https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的CORPID&redirect_uri=REDIRECT_URI后台接口上&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
b、code换取userId的方法
/**
* 用code换取userId
*
* @param code
* @return
*/
public static String getUserId(String code) {
String access_token = getToken();//access_token建议从数据库中获取,或者全局缓存中获取,这只是个本地的例子,
JSONObject obj = doGet(
"https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" + access_token + "&code=" + code);
return obj.get("UserId").toString();
}
/**
* http GET请求封装
*
* @param url
* @return
*/
public static JSONObject doGet(String url) {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
JSONObject obj = new JSONObject();
try {
HttpResponse response = httpClient.execute(get);
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "utf-8");
obj = JSONObject.parseObject(result);
}
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
二、前台拍照调用,选择图片,命名图片,上传图片
原理解释:
微信企业号开发文档:http://qydev.weixin.qq.com/wiki/index.php?title=%E5%BE%AE%E4%BF%A1JS-SDK%E6%8E%A5%E5%8F%A3#.E6.8B.8D.E7.85.A7.E6.88.96.E4.BB.8E.E6.89.8B.E6.9C.BA.E7.9B.B8.E5.86.8C.E4.B8.AD.E9.80.89.E5.9B.BE.E6.8E.A5.E5.8F.A3
1、获取wx.config配置
2、调用拍照获取照片的微信接口(使用微信自带接口)
3、预览获取的图片,设置图片别名(使用微信自带接口)
4、上传图片到微信服务器(使用微信自带接口)
5、从微信服务器下载图片到自己的服务器
js中的代码,注意必须先引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.1.0.js 和jq文件
备注:js-sdk验签,请看http://blog.youkuaiyun.com/qq_30240219/article/details/62420356
var flag = false;
// ID数组
var localIds = null;
// 上传序号
var idx = 0;
var imgNames = '';
var serverIds = '';
$(document).ready(function() {
signature();
});
wx.ready(function() {
mychooseImg();
});
function signature() {
$.ajax({
url: '你自己验签的地址',
data: { 'url': window.location.href},
type: "get",
dataType: 'json',
success: function(data) {
wx.config({
appId: '你的corpId', // 必填,公众号的唯一标识
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.noncestr, // 必填,生成签名的随机串
signature: data.signature, //必填,签名
jsApiList: ['chooseImage','uploadImage'] // 必填,需要使用的JS接口列表
});
flag = true;
},
error: function(data) {
alert('fail');
}
});
}
//调用拍照获取照片的微信接口
function mychooseImg() {
wx.chooseImage({
success: function(res) {
localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
showImg(localIds);
}
});
}
//预览获取的图片,设置图片别名(使用微信自带接口)
function showImg(localIds) {
var _html = "";
for(var i in localIds) {
var photoSrc = localIds[i];
_html = _html + '<p><img src="' + photoSrc + '" height="200" width="200" /><br><input type="text" class="form_input" placeholder="未命名" width="200px"/></p>';
}
$("#photo").append(_html);
$(".btn").append('</br><button onclick="getUpload()">上传图片</button>');
}
//上传图片到微信服务器(使用微信自带接口),从微信服务器下载图片到自己的服务器
function getUpload() {
wx.uploadImage({ //获取图片媒体ID
localId: localIds[idx].toString(), // 需要上传的图片的本地ID
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function(res) { //获取成功
// 上传序号,上传一张 累计 +1
idx++;
//存储图片媒体ID,用,号分割
serverIds += res.serverId + ';';
if(idx < localIds.length) { //本地图片ID 还没全部获取完图片媒体ID
//调用上传递归函数
getUpload();
} else {
//上传序号归零
idx = 0;
//获取命名的图像名称
var form_input=$(".form_input");
for (i=0;i<form_input.length;i++) {
if(form_input.eq(i).val().length==0){
form_input.eq(i).val("未命名");
}
if(i==0){
imgNames=form_input.eq(i).val();
}else{
imgNames = imgNames + ";" + form_input.eq(i).val();
}
}
var userId=$.getUrlParam('UserId');
$.ajax({
url: "自己从微信服务器下载图片到自己服务器的接口地址",
type: 'POST',
dataType:'json',
data: {serverIds: serverIds,imgNames:imgNames,userId:userId},
success: function(data) {
if(data.message=='success'){
alert("上传成功");
WeixinJSBridge.call('closeWindow');
}
},
error: function(data) {
alert(JSON.stringify(data));
}
});
serverIds = '';
return true;
}
},
fail: function(res) { //获取多媒体id失败 返回错误代码
alert("上传失败,msg:" + JSON.stringify(res));
}
});
}
(function($) {
//扩展方法获取url参数
$.getUrlParam = function(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if(r != null) return unescape(r[2]);
return null; //返回参数值
}
})(jQuery);
页面上的代码
<body>
<div id="photo"></div>
</br>
<div class="btn">
</div>
</body>
三、(java) 从微信服务器下载图片到自己的服务器
微信企业号开放平台下载图片的api:http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6
1.根据前台传递过来的图片的id,去微信服务器下载对应的图片
2.下载的图片进行存储,存储下载的信息
/**
* 获取媒体文件
*
* @param accessToken
* 接口访问凭证
* @param media_id
* 媒体文件id
* @param savePath
* 文件在服务器上的存储路径
*/
public static String downloadMedia(String accessToken, String mediaId, String savePath) {
String filePath = null;
// 拼接请求地址
String requestUrl = "https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("MEDIA_ID", mediaId);
System.out.println(requestUrl);
try {
URL url = new URL(requestUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setRequestMethod("GET");
if (!savePath.endsWith("/")) {
savePath += "/";
}
String contentType = conn.getHeaderField("Content-Type");
// 根据内容类型获取扩展名
String fileExt = getFileEndWitsh(contentType);
File saveFile = new File(savePath);
if (!saveFile.exists()) {
saveFile.mkdirs();
}
// 将mediaId作为文件名
filePath = savePath + mediaId + fileExt;
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
FileOutputStream 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);
fos.close();
bis.close();
conn.disconnect();
String info = String.format("下载媒体文件成功,filePath=" + filePath);
System.out.println(info);
} catch (Exception e) {
filePath = null;
String error = String.format("下载媒体文件失败:%s", e);
System.out.println(error);
}
return filePath;
}
static Map<String, String> map = new HashMap<String, String>();
static {
map.put("image/jpeg", ".jpg");
map.put("audio/mp3", ".mp3");
map.put("video/mpeg4", ".mp4");
}
private static String getFileEndWitsh(String contentType) {
return map.get(contentType);
}
//备注,下面的请根据具体情况进行对应修改
@RequestMapping(value = "/insert.do", method = RequestMethod.POST)
@ResponseBody
public void insert(HttpServletRequest request, HttpServletResponse response,
throws IOException {
JSONObject obj=new JSONObject();
String serverIds=Request.getParameter("serverIds");
String imgNames=Request.getParameter("imgNames");
String userId=Request.getParameter("userId");
String long1=Request.getParameter("long");
String lat=Request.getParameter("lat");
String[] mediaIds=serverIds.split(";");
String[] alias=imgNames.split(";");
String result="fail";
// 获取 access_token
String access_token=xxxxxxx;// 建议从数据库中获取,或者全局缓存中获取,这只是个本地的例子
//以年和月作为附件存盘路径每个月存一个文件夹 如:attachment/201405/
java.text.DateFormat insDateFormat = new SimpleDateFormat("yyyyMM");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
String attachmentFolder="本地存储图片的地址"+"/"+(String) insDateFormat.format(new java.util.Date())+"/";
String savePath=Request.getParameteretAppPath()+attachmentFolder; //获取文件需要上传到的路径
try{
for (int i=0;i<mediaIds.length;i++) {
String filePath=downloadMedia(access_token, mediaIds[i], savePath);
//
//这里进行数据存储
///
}
result="success";
}catch(Exception e){
System.out.println(e);
}
obj.put("message",result);
response.setContentType("text/html;charset=utf-8");
response.getWriter().print(obj.toString());
System.out.println(obj.toString());
}