1. 程式人生 > >微信公眾號上傳媒體檔案

微信公眾號上傳媒體檔案

公眾號在使用介面時,對多媒體檔案、多媒體訊息的獲取和呼叫等操作,是通過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<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 [email protected]
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());
    }

測試結果:



相關推薦

公眾媒體檔案

公眾號在使用介面時,對多媒體檔案、多媒體訊息的獲取和呼叫等操作,是通過media_id來進行的。通過本介面,公眾號可以上傳或下載多媒體檔案。但請注意,每個多媒體檔案(media_id)會在上傳、使用者傳送到微信伺服器3天后自動刪除,以節省伺服器資源。 公眾號可呼叫本介面來

基於 vant-ui 封裝一個公眾插件

公眾 font upload style vue asset splice computed img 1 Vue.component(‘my-wx-upload‘, { 2 template: ` 3 <mu-grid-list :col

java接收小程式檔案

用微信小程式上傳檔案,微信會生成一個wx://開頭的臨時地址,很多人看到這個臨時地址直接懵逼了,檔案在哪裡啊,怎麼取檔案,其實檔案流就在請求頭裡面,需要自己去讀取.一開始我也走了很多彎路,查閱了幾篇帖子,其實都有一些坑沒有指出來.為了方便以後大家程式碼複用,我在此做一個整合.避免後人掉坑. 1.首

小程式圖片檔案 小程式+Java

小程式程式碼: chooseImage(){ wx.chooseImage({ success: function (res) { var tempFilePaths = res.tempFilePaths wx.up

C# 呼叫公眾介面送客服訊息示例

客服訊息傳送比較簡單 注:指定openid和訊息內容使用Post傳送就可以,很多時候需要在觸發事件或相應的情況下發送 1.獲取傳送地址 /// <summary> /// 客服傳送訊息-

如何判斷某一個公眾面的文章的閱讀量是不是刷上來的?

仔細看這3張圖閱讀來源分佈裡的“公眾號會話”和“歷史訊息”所佔比例,你會發現一個問題,為什麼前面兩個閱讀來源都是“公眾號會話”佔了大部分的比例,第三個卻是閱讀來源卻是“歷史訊息”佔了大部分比例呢? 我們可以這樣分析一下:當一篇文章從公眾號發出去之後,使用者是從“公眾號會話”介面看文章的多,還是從“歷史訊息”

Yii框架使用Curl進行檔案(公眾)

public function actionUpload(){ $type = Yii::$app->request->post('type'); //獲取token $token = Yii::$app->cache->get($this->t

tp5圖片添加永久素材到公眾

ken 傳參數 connect url lena www num 框架 替換 $file = request()->file(‘image‘);if(!$file){ $res[‘status‘] = false; $res[‘msg‘] = ‘必

公眾開發---臨時素材到公眾遇到的問題:"errcode":41005,"errmsg":"media data missing

ack lds com strpos als word ring 默認 field 1、上傳臨時素材到公眾號遇到的問題:"errcode":41005,"errmsg":"media data missing 解決辦法:因為php版本的原因,上傳素材一直保錯。php的cur

公眾開發圖文素材帶有卡片小程序報錯:errcode=45166,errmsg = invalid content hint

src 時間 技術 微信公眾號 微信公眾 align 試圖 這樣的 情況   微信公眾號開發自從支持允許在群發圖文中插入小程序,方便了小程序的運營及推廣。最近在三方服務開發中,要支持圖文素材插入小程序遇到了一個很是棘手的問題。官方給出的插入小程序的示例支持文字、圖片、卡片。

實現公眾頭像

這次我們做的專案需要實現一個微信公眾號頭像上傳並且剪裁的功能,實在沒有頭緒,之後通過網上搜索和自己的修改實現了一個適合我們這個框架的方法。 首先本次專案我們的頁面用的事velocity框架,頁面程式碼是: <li> <span class="ti

公眾 IOS多圖片只儲存一張

wx.chooseImage({ count:imgCount, needResult: 1, sizeType:['original', 'compressed'], sourceType:['album', 'camera'], success:function(res){ ShowOKbt(false

Java開發公眾系列教程(一):js-sdk照片相容IOS和安卓裝置

很多開發者朋友在進行微信公眾號開發時,遇到微信js-sdk上傳手機相簿照片時IOS裝置無法正常預覽的情況,今天筆者結合多年的開發經驗,把相容IOS的解決方案分享給廣大微信開發者朋友。 微信最新版本JSSDK文件 地址https://mp.weixin.qq.com/advanced/wiki

python 公眾開發 django 實現圖片

廢話不多說,直接上碼,有問題請留言。該專案基於 python2.7 + django 1.11.3 url.py #coding:utf8 from django.conf.urls import url from app.views import * urlpatterns = [

公眾開發之選擇圖片,圖片,下載圖片,顯示圖片

function clickImg(that){ wx.chooseImage({ count: 1, needResult: 1, sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓

Java開發公眾系列教程(一):js-sdk手機相簿照片相容IOS和安卓裝置

很多開發者朋友在進行微信公眾號開發時,遇到微信js-sdk上傳手機相簿照片時IOS裝置無法正常預覽的情況,今天筆者結合多多年的開發經驗,把相容IOS的解決方案分享給廣大微信開發者朋友。 一、首先申明一點筆者本案例用的微信JSSDK版本是1.2.0的,官方文件給出的最

asp原始碼公眾拍照或從手機相簿中選圖介面上jdk程式碼

'設定引數值 Public Sub setParameter(parameter, parameterValue) If parameters.Exists(parameter) = True Then parameters.Remove(parameter)

公眾如何視訊

第一步:在微信公眾號新建圖文中,選擇右側的視訊; 第二步:新建視訊; 第三步:若視訊小於20MB,上傳即可,否則點選騰訊視訊的連結,進入騰訊視訊網頁版(個人認為小於20MB的視訊很小);

THINKPHP5+公眾多圖片預覽

THINKPHP5+微信公眾號多圖片上傳預覽 1.首先整合JSSDK 在extend目錄下建立org/wechant資料夾,新建Jssdk.php,將下面的程式碼放進去,在統計目錄下建立access_token.php和jsapi_ticket.php,用來存放微信accesstok

公眾開發的時候,進行多張手機相簿圖片時候只第一張其他圖片沒解決方案

微信端的這個方法在使用的在你進行迴圈呼叫的時候他只接受第一張圖片,其他圖片就沒有了所以解決的方法就是一串串執行而不是並行 wx.uploadImage({ localId: '', // 需要上傳的圖片的本地ID,由chooseImage介面獲得 isSh