背景:
项目里需要做图片识别,图片来自于微信用户的上传
为什么不让用户直接上传到后台服务器:
答:微信开发主要以网页开发的方式为主,但是微信对原生html上传并不友好,目前微信版本中只有iphone版本支持使用原生上传,
微信提供了一个微信上传图片资源的方式,微信js上传到微信官方服务器,并对所有机型都支持
(吐槽一下!支持一下原生不行吗?就非要这几张图片过个手)
本文所讲的是获取零时素材,具体的临时素材限制可以参考微信方,本文主讲资源的获取,无论是图片还是媒体文件,原理是相通的
参数:
mediaId和accessToken
mediaId是微信端上传图片到微信服务器返回的用于定位文件资源的一种标识字符串
accessToken有两种,一种是网页授权accessToken,指的是来自于用户访问的accessToken
第二种是接口调用accessToken,是开发者(服务器)通过appid和secret获取的accessToken
本处使用的是第二种accessToken
微信资源获取地址:
http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
http://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
目前这两个地址都可以使用
代码:
1.从微信服务器获取资源,requestUrl复制到浏览器,能够以图片形式打开或者下载图片成功即可(所以是不是来自于微信,都不重要)
public ImgBean getImg(String requestUrl) {
try {
// 建立链接
URL url = new URL(requestUrl);
HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
// 连接指定的资源
httpUrl.connect();
String contentType = httpUrl.getContentType();
if(!"image/jpeg".equals(contentType)) {
System.out.println("contentType:"+contentType);
//刷新access_token
accessTokenRedisService.delAccessToken(APP_ID);
return null;
}
// 获取网络输入流
//String contentDisposition = new String(httpUrl.getHeaderField("Content-Disposition").getBytes("ISO-8859-1"), "GBK");
//String fileType = contentDisposition.substring(contentDisposition.indexOf("."), contentDisposition.lastIndexOf("\""));
InputStream inputStream = httpUrl.getInputStream();
String contentDisposition = new String(httpUrl.getHeaderField("Content-Disposition").getBytes("ISO-8859-1"), "GBK");
String suffix=contentDisposition.substring(contentDisposition.indexOf("."), contentDisposition.lastIndexOf("\""));
ImgBean img = new ImgBean();
System.out.println("contentType:"+contentType);
System.out.println("suffix:"+suffix);
img.setSuffix(suffix);
img.setInputStream(inputStream);
return img;
}catch (Exception e) {
System.out.println("error:"+e.getMessage());
}
return null;
}
2.资源访问失败
微信图片的访问,并不是直接访问静态资源,而是通过微信服务器的判断,如果权限不够,或者mediaId失效,均会以json的形式返回,
所以如果再浏览器打开,遇到的是json返回,就说明你的mediaId或者accessToken有问题
{"errcode":40004,"errmsg":"invalid media type"}
3.资源接收的实体
public class ImgBean {
private String suffix;
private InputStream inputStream;
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
}
4.传参调用
//从微信获取流
AccessToken accessToken = authService.getAccessToken();
String requestUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID".replace("MEDIA_ID", mediaId).replace("ACCESS_TOKEN", accessToken.getToken());
System.out.println("downloadUrl:"+requestUrl);
ImgBean img = authService.getImg(requestUrl);
5.流的处理
流可以直接以图片文件的形式储存在本地服务器,也可以转发到远端服务器
下一篇会讲java通过http请求直接发送资源流到另外一台服务器
总结:
从代码中不难理解,无论是图片还是视频,音频其实都可以直接请求url获取到资源,转换成流的形式(方便处理)