公众号在使用接口时,对多媒体文件、多媒体消息的获取和调用等操作,是通过media_id来进行的。通过本接口,公众号可以上传或下载多媒体文件。但请注意,每个多媒体文件(media_id)会在上传、用户发送到微信服务器3天后自动删除,以节省服务器资源。
公众号可调用本接口来上传图片、语音、视频等文件到微信服务器,上传后服务器会返回对应的media_id,公众号此后可根据该media_id来获取多媒体。请注意,media_id是可复用的,调用该接口需http协议。
接口调用请求说明
http请求方式: POST/FORM
http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
调用示例(使用curl命令,用FORM表单方式上传一个多媒体文件):
curl -F [email protected] "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"
首先封装一个HttpPostUtil类,专门负责文件上传请求及一些参数的设置(此处可以理解为上传文件表单参数设置和connection的一些必须设置)、字符编码,文件类型等。
HttpPostUtil类代码:
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
/**
*
* @author Sunlight
*
*/
public class HttpPostUtil {
private URL url;
private HttpURLConnection conn;
private String boundary = "--------httppost123";
private HashMap textParams = new HashMap();
private HashMap fileparams = new HashMap();
private DataOutputStream outputStream;
public HttpPostUtil(String url) throws Exception {
this.url = new URL(url);
}
/**
* 重新设置要请求的服务器地址,即上传文件的地址。
*
* @param url
* @throws Exception
*/
public void setUrl(String url) throws Exception {
this.url = new URL(url);
}
/**
* 增加一个普通字符串数据到form表单数据中
*
* @param name
* @param value
*/
public void addParameter(String name, String value) {
textParams.put(name, value);
}
/**
* 增加一个文件到form表单数据中
*
* @param name
* @param value
*/
public void addParameter(String name, File value) {
fileparams.put(name, value);
}
/**
* 清空所有已添加的form表单数据
*/
public void clearAllParameters() {
textParams.clear();
fileparams.clear();
}
/**
* 发送数据到服务器,返回一个字节包含服务器的返回结果的数组
*
* @return
* @throws Exception
*/
public String send() throws Exception {
initConnection();
conn.connect();
outputStream = new DataOutputStream(conn.getOutputStream());
writeFileParams();
writeStringParams();
paramsEnd();
int code = conn.getResponseCode();
if (code == 200) {
InputStream in = conn.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024 * 8];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
conn.disconnect();
String s = new String(out.toByteArray(), "utf-8");
return s;
}
return null;
}
/**
* 文件上传的connection的一些必须设置
*
* @throws Exception
*/
private void initConnection() throws Exception {
conn = (HttpURLConnection) this.url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(10000); // 连接超时为10秒
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
}
/**
* 普通字符串数据
*
* @throws Exception
*/
private void writeStringParams() throws Exception {
Set keySet = textParams.keySet();
for (Iterator it = keySet.iterator(); it.hasNext();) {
String name = it.next();
String value = textParams.get(name);
outputStream.writeBytes("--" + boundary + "\r\n");
outputStream.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"\r\n");
outputStream.writeBytes("\r\n");
outputStream.writeBytes(encode(value) + "\r\n");
}
}
/**
* 文件数据
*
* @throws Exception
*/
private void writeFileParams() throws Exception {
Set keySet = fileparams.keySet();
for (Iterator it = keySet.iterator(); it.hasNext();) {
String name = it.next();
File value = fileparams.get(name);
outputStream.writeBytes("--" + boundary + "\r\n");
outputStream.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + encode(value.getName()) + "\"\r\n");
outputStream.writeBytes("Content-Type: " + getContentType(value) + "\r\n");
outputStream.writeBytes("\r\n");
outputStream.write(getBytes(value));
outputStream.writeBytes("\r\n");
}
}
/**
* 获取文件的上传类型,图片格式为image/png,image/jpeg等。非图片为application /octet-stream
*
* @param f
* @return
* @throws Exception
*/
private String getContentType(File f) throws Exception {
return "application/octet-stream";
}
/**
* 把文件转换成字节数组
*
* @param f
* @return
* @throws Exception
*/
private byte[] getBytes(File f) throws Exception {
FileInputStream in = new FileInputStream(f);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while ((n = in.read(b)) != -1) {
out.write(b, 0, n);
}
in.close();
return out.toByteArray();
}
/**
* 添加结尾数据
*
* @throws Exception
*/
private void paramsEnd() throws Exception {
outputStream.writeBytes("--" + boundary + "--" + "\r\n");
outputStream.writeBytes("\r\n");
}
/**
* 对包含中文的字符串进行转码,此为UTF-8。服务器那边要进行一次解码
*
* @param value
* @return
* @throws Exception
*/
private String encode(String value) throws Exception {
return URLEncoder.encode(value, "UTF-8");
}
}
上传测试方法(可以在自己项目中上传文件到一些第三方提供的平台):
/**
* 使用方法示例
* 此方法需要修改成自己上传地址才可上传成功
* @param args
* @throws Exception
*/
public static void test(String[] args) throws Exception {
File file=new File("D\\up.jpg");
//此处修改为自己上传文件的地址
HttpPostUtil post = new HttpPostUtil("http://www.omsdn.cn");
//此处参数类似 curl -F [email protected]
post.addParameter("media", file);
post.send();
}
上传文件方法封装好后,微信公众号上传文件类调用,此处需要JSON包(json-lib-2.2.3-jdk13.jar):
import java.io.File;
import cn.xx.wechat.model.MdlUpload;
import cn.xx.wechat.model.Result;
import net.sf.json.JSONObject;
/**
*
* @author Sunlight
*
*/
public class FileUpload {
private static final String upload_url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
/**
* 上传文件
*
* @param accessToken
* @param type
* @param file
* @return
*/
public static Result Upload(String accessToken, String type, File file) {
Result result = new Result();
String url = upload_url.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type);
JSONObject jsonObject;
try {
HttpPostUtil post = new HttpPostUtil(url);
post.addParameter("media", file);
String s = post.send();
jsonObject = JSONObject.fromObject(s);
if (jsonObject.containsKey("media_id")) {
MdlUpload upload=new MdlUpload();
upload.setMedia_id(jsonObject.getString("media_id"));
upload.setType(jsonObject.getString("type"));
upload.setCreated_at(jsonObject.getString("created_at"));
result.setObj(upload);
result.setErrmsg("success");
result.setErrcode("0");
} else {
result.setErrmsg(jsonObject.getString("errmsg"));
result.setErrcode(jsonObject.getString("errcode"));
}
} catch (Exception e) {
e.printStackTrace();
result.setErrmsg("Upload Exception:"+e.toString());
}
return result;
}
}
返回结果类:
package cn.xx.wechat.model;
public class Result {
private T obj;
private String errcode;
private String errmsg;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
public String getErrcode() {
return errcode;
}
public void setErrcode(String errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
package cn.xx.wechat.model;
public class MdlUpload {
private String type;
private String media_id;
private String created_at;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMedia_id() {
return media_id;
}
public void setMedia_id(String mediaId) {
media_id = mediaId;
}
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String createdAt) {
created_at = createdAt;
}
public MdlUpload() {
super();
}
@Override
public String toString() {
return "MdlUpload [created_at=" + created_at + ", media_id=" + media_id + ", type=" + type + "]";
}
}
@Test
public void testUpload() {
File file=new File("E:\\Tulips.jpg");
System.err.println(file.getName());
Result result=FileUpload .Upload("image", file);
System.out.println("Errcode="+result.getErrcode()+"\tErrmsg="+result.getErrmsg());
System.out.println(result.getObj().toString());
}
本人微信公众号:http://www.omsdn.cn 点击二维码关注!