微信公眾號開發之新增臨時素材(八)


一、新增臨時素材

公眾號經常有需要用到一些臨時性的多媒體素材的場景,例如在使用接口特別是發送消息時,對多媒體文件、多媒體消息的獲取和調用等操作,是通過media_id來進行的。素材管理接口對所有認證的訂閱號和服務號開放。通過本接口,公眾號可以新增臨時素材(即上傳臨時多媒體文件)。

注意點:

1、臨時素材media_id是可復用的。

2、媒體文件在微信后台保存時間為3天,即3天后media_id失效。

3、上傳臨時素材的格式、大小限制與公眾平台官網一致。

圖片(image): 2M,支持PNG\JPEG\JPG\GIF格式

語音(voice):2M,播放長度不超過60s,支持AMR\MP3格式

視頻(video):10MB,支持MP4格式

縮略圖(thumb):64KB,支持JPG格式

4、需使用https調用本接口。

接口調用請求說明

http請求方式:POST/FORM,使用https https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE 調用示例(使用curl命令,用FORM表單方式上傳一個多媒體文件): curl -F media=@test.jpg "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"

參數說明

參數 是否必須 說明
access_token 調用接口憑證
type 媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb)
media form-data中媒體文件標識,有filename、filelength、content-type等信息

返回說明

正確情況下的返回JSON數據包結果如下:

{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
參數 描述
type 媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb,主要用於視頻與音樂格式的縮略圖)
media_id 媒體文件上傳后,獲取標識
created_at 媒體文件上傳時間戳

錯誤情況下的返回JSON數據包示例如下(示例為無效媒體類型錯誤):

{"errcode":40004,"errmsg":"invalid media type"}

根據上面的接口,我們定義了一個上傳臨時素材的方法,包含文件目錄和文件類型這兩個參數,我們這里依然采用RestTemplate工具類進行文件上傳

 

/**
     * 上傳臨時素菜
     * 1、臨時素材media_id是可復用的。
     * 2、媒體文件在微信后台保存時間為3天,即3天后media_id失效。
     * 3、上傳臨時素材的格式、大小限制與公眾平台官網一致。
     * @param filePath
     * @param type
     * @return
     */
    public String uploadFile(String filePath,String type) {

        String accessToken = accessTokenUtil.getAccessToken();
        if (accessToken != null) {
            String url = URIConstant.MEDIA_UPLOAD_URL.replace("ACCESS_TOKEN", accessToken)
                    .replace("TYPE", type);
            log.info("MEDIA_UPLOAD_URL:{}",url);

            //設置請求體,注意是LinkedMultiValueMap
            MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
            FileSystemResource fileSystemResource = new FileSystemResource(filePath);
            form.add("media", fileSystemResource);

            //設置請求頭
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            //用HttpEntity封裝整個請求報文
            HttpEntity<MultiValueMap<String, Object>> data = new HttpEntity<>(form, headers);
            try{
                //這里RestTemplate請求返回的字符串直接轉換成JSONObject會報異常,后續深入找一下原因
                String resultString = restTemplate.postForObject(url, data, String.class);
                log.info("上傳返回的信息是:{}",resultString);
                if(!StringUtils.isEmpty(resultString)){
                    JSONObject jsonObject = JSONObject.parseObject(resultString);
                    return jsonObject.getString("media_id");
                }
            }catch (Exception e){
                log.error(e.getMessage());
            }

        }
        return null;
    }

我們在swagger中新建一個Controller用以提交我們的上傳請求,並測試我們的代碼是否正確

@ApiOperation(value = "上傳臨時素材")
    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name="filePath",value="文件位置", paramType="query",dataType="String"),
            @ApiImplicitParam(name="type",value="媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb)", paramType="query",dataType="String"),

    })
    public Object upload(String filePath, String type) throws Exception{

        String result = uploadUtil.uploadFile(filePath,type);
        return result;
    }

啟動我們的項目,在swagger中輸入一個有效的文件路徑(這里假如是圖片類型),type設置為image

 

可以看到,我們成功上傳了臨時文件,並獲取到了該文件的media_id(這個后續很重要!!!)

 

二、獲取臨時素材

臨時素材主要分為三類(圖片、音頻,視頻),圖片和音頻文件支持下載到本地,視頻文件支持獲取視頻的URL地址

(1)獲取臨時圖片

 

/**
     * 公眾號可以使用本接口獲取臨時素材(即下載臨時的多媒體文件)
     * 1、如果是圖片,則下載圖片
     */
    public ResponseEntity<byte[]> getImage(String mediaId){

        String accessToken = accessTokenUtil.getAccessToken();
        if(accessToken != null) {
            String url = URIConstant.MEDIA_GET_URL.replace("ACCESS_TOKEN", accessToken)
                    .replace("MEDIA_ID", mediaId);
            log.info("MEDIA_GET_URL:{}", url);

            String fileName = mediaId+ ".jpg";
            HttpHeaders headers = new HttpHeaders();
            try {
                fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            headers.setContentDispositionFormData("attachment", fileName);// 文件名稱
            ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), byte[].class);
            return responseEntity;
        }
        return null;
    }

(2)獲取臨時音頻

/**
     * 公眾號可以使用本接口獲取臨時素材(即下載臨時的多媒體文件)
     * 1、如果是聲音,則下載聲音
     */
    public ResponseEntity<byte[]> getVoice(String mediaId){

        String accessToken = accessTokenUtil.getAccessToken();
        if(accessToken != null) {
            String url = URIConstant.MEDIA_GET_URL.replace("ACCESS_TOKEN", accessToken)
                    .replace("MEDIA_ID", mediaId);
            log.info("MEDIA_GET_URL:{}", url);

            String fileName = mediaId+ ".speex";
            HttpHeaders headers = new HttpHeaders();
            try {
                fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            headers.setContentDispositionFormData("attachment", fileName);// 文件名稱
            ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), byte[].class);
            return responseEntity;
        }
        return null;
    }

 (3)獲取視頻素材地址

/**
     * 公眾號可以使用本接口獲取臨時素材(即下載臨時的多媒體文件)
     * 2、如果是視頻,則返回視頻的地址
     */
    public String getVedio(String mediaId){

        String accessToken = accessTokenUtil.getAccessToken();
        if(accessToken != null) {
            String url = URIConstant.MEDIA_GET_URL.replace("ACCESS_TOKEN", accessToken)
                    .replace("MEDIA_ID", mediaId);
            log.info("MEDIA_GET_URL:{}", url);

            String responseString = restTemplate.getForObject(url,String.class);
            return responseString;
        }
        return null;
    }

 三、測試

這里我們僅以上傳臨時圖片素材並下載臨時圖片素材為例,我們在我們的Controller中新增一個根據media_id獲取臨時圖片類型素材的方法

我們把我們剛才上傳臨時素材成功返回的media_id傳給我們的方法

 

可以看到我們的swagger返回帶有Download file的超級鏈接,點擊即可下載我們的圖片,當然我們可以直接在瀏覽器直接輸入我們的完整請求地址

http://localhost/material/getFile?mediaId=C3Vd7uR-MKY5bOkyT5hWGaS-icl3av7GahjM9E9Hx9i8nonxg4PNtE-s7TbYSseV

點擊這個Download File,我們成功的下載到這個上傳的臨時圖片

​ 試着打開這個文件,我們可以看到,這個確實是我們上傳的圖片

 這里貼出完整的代碼,自行修改以獲得其他類型的臨時文件,不做贅述

UploadUtil.java
package com.xu.wemall.components.weixin;

import com.alibaba.fastjson.JSONObject;
import com.xu.wemall.commons.constants.URIConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;

/**
 * 功能:臨時素材工具類
 */
@Slf4j
@Component
public class UploadUtil {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private AccessTokenUtil accessTokenUtil;

    /**
     * 上傳臨時素菜
     * 1、臨時素材media_id是可復用的。
     * 2、媒體文件在微信后台保存時間為3天,即3天后media_id失效。
     * 3、上傳臨時素材的格式、大小限制與公眾平台官網一致。
     * @param filePath
     * @param type
     * @return
     */
    public String uploadFile(String filePath,String type) {

        String accessToken = accessTokenUtil.getAccessToken();
        if (accessToken != null) {
            String url = URIConstant.MEDIA_UPLOAD_URL.replace("ACCESS_TOKEN", accessToken)
                    .replace("TYPE", type);
            log.info("MEDIA_UPLOAD_URL:{}",url);

            //設置請求體,注意是LinkedMultiValueMap
            MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
            FileSystemResource fileSystemResource = new FileSystemResource(filePath);
            form.add("media", fileSystemResource);

            //設置請求頭
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            //用HttpEntity封裝整個請求報文
            HttpEntity<MultiValueMap<String, Object>> data = new HttpEntity<>(form, headers);
            try{
                //這里RestTemplate請求返回的字符串直接轉換成JSONObject會報異常,后續深入找一下原因
                String resultString = restTemplate.postForObject(url, data, String.class);
                log.info("上傳返回的信息是:{}",resultString);
                if(!StringUtils.isEmpty(resultString)){
                    JSONObject jsonObject = JSONObject.parseObject(resultString);
                    return jsonObject.getString("media_id");
                }
            }catch (Exception e){
                log.error(e.getMessage());
            }

        }
        return null;
    }

    /**
     * 公眾號可以使用本接口獲取臨時素材(即下載臨時的多媒體文件)
     * 1、如果是圖片,則下載圖片
     */
    public ResponseEntity<byte[]> getImage(String mediaId){

        String accessToken = accessTokenUtil.getAccessToken();
        if(accessToken != null) {
            String url = URIConstant.MEDIA_GET_URL.replace("ACCESS_TOKEN", accessToken)
                    .replace("MEDIA_ID", mediaId);
            log.info("MEDIA_GET_URL:{}", url);

            String fileName = mediaId+ ".jpg";
            HttpHeaders headers = new HttpHeaders();
            try {
                fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            headers.setContentDispositionFormData("attachment", fileName);// 文件名稱
            ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), byte[].class);
            return responseEntity;
        }
        return null;
    }

    /**
     * 公眾號可以使用本接口獲取臨時素材(即下載臨時的多媒體文件)
     * 1、如果是聲音,則下載聲音
     */
    public ResponseEntity<byte[]> getVoice(String mediaId){

        String accessToken = accessTokenUtil.getAccessToken();
        if(accessToken != null) {
            String url = URIConstant.MEDIA_GET_URL.replace("ACCESS_TOKEN", accessToken)
                    .replace("MEDIA_ID", mediaId);
            log.info("MEDIA_GET_URL:{}", url);

            String fileName = mediaId+ ".speex";
            HttpHeaders headers = new HttpHeaders();
            try {
                fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            headers.setContentDispositionFormData("attachment", fileName);// 文件名稱
            ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), byte[].class);
            return responseEntity;
        }
        return null;
    }

    /**
     * 公眾號可以使用本接口獲取臨時素材(即下載臨時的多媒體文件)
     * 2、如果是視頻,則返回視頻的地址
     */
    public String getVedio(String mediaId){

        String accessToken = accessTokenUtil.getAccessToken();
        if(accessToken != null) {
            String url = URIConstant.MEDIA_GET_URL.replace("ACCESS_TOKEN", accessToken)
                    .replace("MEDIA_ID", mediaId);
            log.info("MEDIA_GET_URL:{}", url);

            String responseString = restTemplate.getForObject(url,String.class);
            return responseString;
        }
        return null;
    }



}


謝謝各位,我們下回繼續再說!

如果您覺得此文有幫助,可以小小打賞一下,持續更新更有動力喲!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM