公众号在使用接口时,对多媒体文件、多媒体消息的获取和调用等操作,是通过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 media=@test.jpg "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<String, String> textParams = new HashMap<String, String>();
- private HashMap<String, File> fileparams = new HashMap<String, File>();
- 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<String> keySet = textParams.keySet();
- for (Iterator<String> 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<String> keySet = fileparams.keySet();
- for (Iterator<String> 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 media=@test.jpg
- post.addParameter("media", file);
- post.send();
- }
上传文件方法封装好后,微信公众号上传文件类调用,此处需要JSON包(json-lib-2.2.3-jdk13.jar):
- import java.io.File;
- import cn.<span style="font-family:FangSong_GB2312;">xx</span>.wechat.model.MdlUpload;
- import cn.<span style="font-family:FangSong_GB2312;">xx</span>.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<MdlUpload> Upload(String accessToken, String type, File file) {
- Result<MdlUpload> result = new Result<MdlUpload>();
- 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;
- }
- }
调用方法需要引用2个Model类(返回结果类和上传文件类型类):
返回结果类:
- package cn.<span style="font-family:FangSong_GB2312;">xx</span>.wechat.model;
- public class Result<T> {
- private T obj;
- private String errcode;
- private String errmsg;
- public T getObj() {
- return obj;
- }
- public void setObj(T obj) {
- this.obj = obj;
- }
- <span style="font-family:FangSong_GB2312;"> </span>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.<span style="font-family:FangSong_GB2312;">xx</span>.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<MdlUpload> result=FileUpload .Upload("image", file);
- System.out.println("Errcode="+result.getErrcode()+"\tErrmsg="+result.getErrmsg());
- System.out.println(result.getObj().toString());
- }
测试结果: