• 微信公众号开发(六)素材管理 微信公众号在使用的接口的时候是通过media_id来进行的,所以在使用的接口的时候我们往往需要先上传素材,支持上传素材的格式和限制如下 图片(image): 2M,支持PNG\JPEG\JPG\GIF...

    微信公众号开发(六)素材管理

     

    微信公众号在使用的接口的时候是通过media_id来进行的,所以在使用的接口的时候我们往往需要先上传素材,支持上传素材的格式和限制如下

    1. 图片(image): 2M,支持PNG\JPEG\JPG\GIF格式。
    2. 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式。
    3. 视频(video):10MB,支持MP4格式。
    4. 缩略图(thumb):64KB,支持JPG格式。

    1、上传临时素材

    媒体文件在微信后台保存时间为3天,即3天后media_id失效。详细文档请查看上传临时文件素材文档

    请求接口:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE

    add_tmp_media.php,这里要注意PHP各版本间上传文件的差异。

    <?php
    require_once("Utils.php");
    
    if (class_exists('CURLFile')) {
        //PHP5.5及以上
        //realpath返回绝对路径
        $filedata = array('media' => new CURLFile(realpath("images/img1.jpg")));
    } else {
        //PHP5.4及以下
        $filedata = array('media' => '@'.realpath("images/img1.jpg"));
    }
    
    $url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=".Utils::get_access_token()."&type=image";
    $result = Utils::https_request($url, $filedata);
    echo $result;


    返回结果如下:

     

    2、获取临时素材消息

    请求接口:https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID

    视频文件不能直接使用本接口下载。

    get_tmp_media.php

    <?php
    @header('Content-type: text/plain;charset=UTF-8');
    require_once("Utils.php");
    
    $media_id = "F11GfZC5zzC5XjJ3v1ORqay5pMrrtzv5bREF7-7f_ohjwxfXAZ-vjO3VRaEaOu0f";
    $url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token="
        .Utils::get_access_token()."&media_id=".$media_id;
    
    $fileInfo = https_request($url);
    $filename = "gg.jpg";
    //$fileInfo["body"]保存了图片的内容
    save_weixin_file($filename, $fileInfo["body"]);
    var_dump($fileInfo);
    
    //保存图片到本地
    function save_weixin_file($filename, $fileConent)
    {
        $local_file = fopen($filename, "w");
        if (false !== $local_file){
            if (false !== fwrite($local_file, $fileConent)){
                fclose($local_file);
            }
        }
    }
    
    function https_request($url)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_NOBODY, 0); //只取body头
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //$package是返回的图片
        $package = curl_exec($ch);
        //$httpinfo 响应头
        $httpinfo = curl_getinfo($ch);
        curl_close($ch);
        //将body和响应头合并到一个数组
        $imageAll = array_merge(array("header"=>$httpinfo), array("body"=> $package));
        return $imageAll;
    }

    返回的响应头如下:


     

    访问服务器上下载的文件,结果如下:

     

    3、新增永久素材

    对于常用的素材,开发者可通过本接口上传到微信服务器,永久使用。新增的永久素材也可以在公众平台官网素材管理模块中查询管理。

    除了可以上传以上提到的4种素材外,还可以上传图文素材。

    以下是一些说明:

    1. 公众号的素材库保存总数量有上限:图文消息素材、图片素材上限为5000,其他类型为1000。
    2. 图文消息的具体内容中,微信后台将过滤外部的图片链接,图片url需通过"上传图文消息内的图片获取URL"接口上传图片获取。
    3. "上传图文消息内的图片获取URL"接口所上传的图片,不占用公众号的素材库中图片数量的5000个的限制,图片仅支持jpg/png格式,大小必须在1MB以下。
    4. 图文消息支持正文中插入自己帐号和其他公众号已群发文章链接的能力。

    上传图文消息内的图片

    本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制。图片仅支持jpg/png格式,大小必须在1MB以下。这里的图片是在图文消息的content字段里面使用的。

    接口:https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN

    add_news_img.php

    <?php
    require_once("Utils.php");
    
    $url= "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=".Utils::get_access_token();
    $pathArr = array("images/img1.jpg", "images/img2.jpg", "images/img3.jpg");
    $result = uploa_imgs($url, $pathArr);
    var_dump($result);
    
    //上传多张图片
    function uploa_imgs($url, $pathArr)
    {
        $resultArr = array();
        forEach ($pathArr as $path)
        {
            if (class_exists('CURLFile')) {
                //PHP5.5及以上
                //realpath返回绝对路径
                $filedata = array('media' => new CURLFile(realpath($path)));
            } else {
                //PHP5.4及以下
                $filedata = array('media' => '@'.realpath($path));
            }
            $result = Utils::https_request($url, $filedata);
            array_push($resultArr, $result);
        }
    
        return $resultArr;
    }


    返回结果如下:

    array(3) { [0]=> string(138) "{"url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoql6CW1Mp9kN0ARibjyWGqCD6w8AgcHUcN7iaRKmEIcVMBXzcicibEzw31w\/0"}" [1]=> string(135) "{"url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoK46dGsp7SJbWnDlrhaSC9ogrTC88KbXuibO8MEhCHwbxd006OmYQUxg\/0"}" [2]=> string(138) "{"url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoSzCu2VqqL6icnbf5Uq2b86wLOzUJCO9oyOYsyh2lnEzgicibHUdeicMGoQ\/0"}" }

     

    上传图文消息

    上传图文消息的接口是:https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=ACCESS_TOKEN。有关字段含义可以参考新增永久图文消息素材,此接口在测试号中一天只能调用10次。

    add_news.php

    <?php
    //<img src=\"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoql6CW1Mp9kN0ARibjyWGqCD6w8AgcHUcN7iaRKmEIcVMBXzcicibEzw31w\/0\"/>
    require_once("Utils.php");
    $newsjson = '{
        "articles": [
    		{
                "title": "第一个图文永久素材",
    			"thumb_media_id": "FrsRJ3g3BHR-pIkuFLARnHjI9Cq9lDFas4Kp8otlAUQ",
    			"author": "Perter",
    			"digest": "第一个图文永久素材摘要",
    			"show_cover_pic": 1,
    			"content": "123",
    			"content_source_url": "http://www.baidu.com"
    		}
    	]
    }';
    $url = "https://api.weixin.qq.com/cgi-bin/material/add_news?"
        ."access_token=".Utils::get_access_token();
    Utils::logger($url);
    $result = Utils::https_request($url, $newsjson);
    echo $result;

    返回如下:

    {"media_id":"FrsRJ3g3BHR-pIkuFLARnAwGsFjf8Rckbd63rFBsE4o"}


    注意这里的thumb_media_id要使用永久素材接口上传接口获得,并将type设为thumb,,有时可能会返回{"errcode":40007,"errmsg":"invalid media_id hint: [UNi0871e541]"}

    网上有一些解决方案是换成临时素材接口,但是这在最新版中是不正确的,原因是永久图文的json字符串错误,找到就可以了。

     

    上传其他素材消息

    其他素材包括图片(image)、语音(voice)、视频(video)和缩略图(thumb),图片素材将进入公众平台官网素材管理模块中的默认分组。视频消息还要多post一个description表单过去,description格式如下:

    {
     "title":VIDEO_TITLE,
     "introduction":INTRODUCTION
    }


    发送图片

    add_material.php

    <?php
    require_once("Utils.php");
    
    $url= "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=".Utils::get_access_token()."&type=image";
    $pathArr = array("images/img1.jpg", "images/img2.jpg", "images/img3.jpg");
    $result = uploa_imgs($url, $pathArr);
    var_dump($result);
    
    //上传多张图片
    function uploa_imgs($url, $pathArr)
    {
        $resultArr = array();
        forEach ($pathArr as $path)
        {
            if (class_exists('CURLFile')) {
                //PHP5.5及以上
                //realpath返回绝对路径
                $filedata = array('media' => new CURLFile(realpath($path)));
            } else {
                //PHP5.4及以下
                $filedata = array('media' => '@'.realpath($path));
            }
            $result = Utils::https_request($url, $filedata);
            array_push($resultArr, $result);
        }
    
        return $resultArr;
    }


    结果如下,仅图片才有url字段返回。

     

    array(3) { [0]=> string(210) "{"media_id":"FrsRJ3g3BHR-pIkuFLARnPz6IegQ220nYBKW4KIjzWo","url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoUPZ1Bdf9W7ncib8AB0AQaa0LUibWYicLJ1ZbiacUdDQian9us7E5p2Rxiaiaw\/0?wx_fmt=jpeg"}" [1]=> string(205) "{"media_id":"FrsRJ3g3BHR-pIkuFLARnAte6HkrmV3Ll7zhmoGyZwE","url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkolMOlXOZazUNdDXaxTiabEB8xHDBa3lfjupHWn2vxicToxEVcfk5vRmxg\/0?wx_fmt=jpeg"}" [2]=> string(204) "{"media_id":"FrsRJ3g3BHR-pIkuFLARnDyvPgsg0lz6TKJvRMCaIhg","url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoEXUXh2653R0tIZCdsoMq2KPvENbOGWAt0qUL9LzyqsWR2TibjKB9vVA\/0?wx_fmt=jpeg"}" }

     

    发送视频

    修改add_material.php如下:

    <?php
    require_once("Utils.php");
    
    $url= "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=".Utils::get_access_token()."&type=video";
    $pathArr = array("movie/aa.mp4");
    $result = uploa_imgs($url, $pathArr);
    var_dump($result);
    
    //上传多张图片
    function uploa_imgs($url, $pathArr)
    {
        $resultArr = array();
        forEach ($pathArr as $path)
        {
            if (class_exists('CURLFile')) {
                //PHP5.5及以上
                //realpath返回绝对路径
                //$filedata = array('media' => new CURLFile(realpath($path)));
                $filedata = array('media' => new CURLFile(realpath($path)),
                    "description"=>'{"title": "111", "introduction":INTRODUCTION}');
            } else {
                //PHP5.4及以下
                //$filedata = array('media' => '@'.realpath($path));
                $filedata = array('media' => '@'.realpath($path)
                ,"description"=>'{"title": "111", "introduction":INTRODUCTION}');
            }
            $result = Utils::https_request($url, $filedata);
            array_push($resultArr, $result);
        }
    
        return $resultArr;
    }


    返回结果如下:

    array(1) { [0]=> string(58) "{"media_id":"FrsRJ3g3BHR-pIkuFLARnMPNEDjZn0upTAeXrqBGP5k"}" }

     


    4、获取永久素材

    在新增了永久素材后,开发者可以根据media_id通过本接口下载永久素材。公众号在公众平台官网素材管理模块中新建的永久素材,可通过"获取素材列表"获知素材的media_id。此接口不能获取临时素材。

    接口:https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=ACCESS_TOKEN

    get_material.php

    <?php
    @header('Content-type: text/plain;charset=UTF-8');
    require_once("Utils.php");
    $mediaId = '{"media_id": "FrsRJ3g3BHR-pIkuFLARnAwGsFjf8Rckbd63rFBsE4o"}';
    $url = "https://api.weixin.qq.com/cgi-bin/material/get_material?"
        ."access_token=".Utils::get_access_token();
    $result = Utils::https_request($url, $mediaId);
    echo $result;
    


    返回永久图文素材如下:

    {
        "news_item": [
            {
                "title": "第一个图文永久素材",
                "author": "Perter",
                "digest": "第一个图文永久素材摘要",
                "content": "123",
                "content_source_url": "http://www.baidu.com",
                "thumb_media_id": "FrsRJ3g3BHR-pIkuFLARnHjI9Cq9lDFas4Kp8otlAUQ",
                "show_cover_pic": 1,
                "url": "http://mp.weixin.qq.com/s?__biz=MzUzMzI2OTQ3Mw==&mid=100000013&idx=1&sn=a6d09fe2e87c320b69a284b1dee01c4b&chksm=7aa7df834dd05695e0dfa4108fee82f8734d52430f93f4e24b0077de2e1712345e7d87f25fda#rd",
                "thumb_url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75ANDqb5Ud7WdHqo3oWodmOtCBPxaicWWs4Gg7kwmqx2vb3NkkuzM8iczib4qltC8GQYib4xHqXu7SwZRrw/0?wx_fmt=jpeg",
                "need_open_comment": 0,
                "only_fans_can_comment": 0
            }
        ],
        "create_time": 1505139219,
        "update_time": 1505139219
    }

    返回永久视频素材如下:

    {
        "title": "111",
        "description": "",
        "down_url": "http://125.39.7.29/vweixinp.tc.qq.com/1007_12f949a80e4e4271bd6763dd76d00931.f10.mp4?vkey=4C0541D9528CE21BACCE2CE8ED46405ABBE24922EBCF5CB40682B1DB1923DD2F103E6C8C4BB2E364191CE9E338874FC69ADB754B69944E03F66B5FC423F228FEB7F7FA42CF83C94EBEDB0ECE1C58C0ADA32497EA2308510B&sha=0&save=1"
    }

    返回永久图片素材如下,直接返回图片:

    5、删除永久素材

    在新增了永久素材后,开发者可以根据本接口来删除不再需要的永久素材,节省空间。请谨慎操作本接口,因为它可以删除公众号在公众平台官网素材管理模块中新建的图文消息、语音、视频等素材(但需要先通过获取素材列表来获知素材的media_id)。临时素材无法通过本接口删除。

    删除接口:https://api.weixin.qq.com/cgi-bin/material/del_material?access_token=ACCESS_TOKEN

    del_material.php

    <?php
    @header('Content-type: text/plain;charset=UTF-8');
    require_once("Utils.php");
    $mediaId = '{"media_id": "FrsRJ3g3BHR-pIkuFLARnDyvPgsg0lz6TKJvRMCaIhg"}';
    $url = "https://api.weixin.qq.com/cgi-bin/material/del_material?"
        ."access_token=".Utils::get_access_token();
    $result = Utils::https_request($url, $mediaId);
    echo $result;
    

    返回接口如下:

    {"errcode":0,"errmsg":"ok"}


    6、修改永久图文素材

    开发者可以通过本接口对永久图文素材进行修改。也可以修改在公众平台官网素材管理模块中保存的图文消息(永久图文素材)。

    接口:https://api.weixin.qq.com/cgi-bin/material/update_news?access_token=ACCESS_TOKEN

    update_news.php

    <?php
    //<img src=\"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoql6CW1Mp9kN0ARibjyWGqCD6w8AgcHUcN7iaRKmEIcVMBXzcicibEzw31w\/0\"/>
    require_once("Utils.php");
    $newsjson = '{
        "media_id": "FrsRJ3g3BHR-pIkuFLARnAwGsFjf8Rckbd63rFBsE4o",
        "index": 0,
        "articles":
        {
            "title": "第一个图文永久素材",
            "thumb_media_id": "FrsRJ3g3BHR-pIkuFLARnHjI9Cq9lDFas4Kp8otlAUQ",
            "author": "Perter",
            "digest": "第一个图文永久素材摘要",
            "show_cover_pic": 1,
            "content": "123",
            "content_source_url": "http://www.baidu.com"
        }
    }';
    $url = "https://api.weixin.qq.com/cgi-bin/material/update_news?"
        ."access_token=".Utils::get_access_token();
    $result = Utils::https_request($url, $newsjson);
    echo $result;

    返回结果如下:

    {"errcode":0,"errmsg":"ok"}

     

    7、获取素材总数

    开发者可以根据本接口来获取永久素材的列表,需要时也可保存到本地,永久素材的总数,也会计算公众平台官网素材管理中的素材,图片和图文消息素材(包括单图文和多图文)的总数上限为5000,其他素材的总数上限为1000。

    接口:https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN

    get_materialcount.php

    <?php
    @header('Content-type: text/plain;charset=UTF-8');
    require_once("Utils.php");
    $url = "https://api.weixin.qq.com/cgi-bin/material/get_materialcount?"
        ."access_token=".Utils::get_access_token();
    $result = Utils::https_request($url);
    echo $result;
    

    返回结果如下:

    {
        "voice_count": 0,
        "video_count": 1,
        "image_count": 9,
        "news_count": 1
    }

     

    8、获取素材列表

    在新增了永久素材后,开发者可以分类型获取永久素材的列表。获取永久素材的列表,也包含公众号在公众平台官网素材管理模块中新建的图文消息、语音、视频等素材。临时素材无法通过本接口获取。

    接口:https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN

    batchget_material.php

    <?php
    @header('Content-type: text/plain;charset=UTF-8');
    require_once("Utils.php");
    $data = '{
        "type":"news",
        "offset":0,
        "count":10
    }';
    $url = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?"
        ."access_token=".Utils::get_access_token();
    Utils::logger($url);
    $result = Utils::https_request($url, $data);
    echo $result;

     

    返回图片结果如下:

    {
        "item": [
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnHjI9Cq9lDFas4Kp8otlAUQ",
                "name": "/home/bae/app/images/img1.jpg",
                "update_time": 1505139076,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75ANDqb5Ud7WdHqo3oWodmOtCBPxaicWWs4Gg7kwmqx2vb3NkkuzM8iczib4qltC8GQYib4xHqXu7SwZRrw/0?wx_fmt=jpeg"
            },
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnPV3S3ztUJSSA5BTlACflIw",
                "name": "/home/bae/app/images/img3.jpg",
                "update_time": 1505034665,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoEXUXh2653R0tIZCdsoMq2KPvENbOGWAt0qUL9LzyqsWR2TibjKB9vVA/0?wx_fmt=jpeg"
            },
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnGfOKWyYscHpu4GuP6zrbxM",
                "name": "/home/bae/app/images/img2.jpg",
                "update_time": 1505034663,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkolMOlXOZazUNdDXaxTiabEB8xHDBa3lfjupHWn2vxicToxEVcfk5vRmxg/0?wx_fmt=jpeg"
            },
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnFQDGg4wLF0SE78VErWMwoU",
                "name": "/home/bae/app/images/img1.jpg",
                "update_time": 1505034662,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoUPZ1Bdf9W7ncib8AB0AQaa0LUibWYicLJ1ZbiacUdDQian9us7E5p2Rxiaiaw/0?wx_fmt=jpeg"
            },
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnGmjlQO3rC7Wg4qXVzYDydY",
                "name": "/home/bae/app/images/img3.jpg",
                "update_time": 1505034395,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoEXUXh2653R0tIZCdsoMq2KPvENbOGWAt0qUL9LzyqsWR2TibjKB9vVA/0?wx_fmt=jpeg"
            },
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnBQJiN0m3xA7G6AvPfrPmHg",
                "name": "/home/bae/app/images/img2.jpg",
                "update_time": 1505034394,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkolMOlXOZazUNdDXaxTiabEB8xHDBa3lfjupHWn2vxicToxEVcfk5vRmxg/0?wx_fmt=jpeg"
            },
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnHxkKn2u0OoAYlg7eXiUbVI",
                "name": "/home/bae/app/images/img1.jpg",
                "update_time": 1505034392,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoUPZ1Bdf9W7ncib8AB0AQaa0LUibWYicLJ1ZbiacUdDQian9us7E5p2Rxiaiaw/0?wx_fmt=jpeg"
            },
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnAte6HkrmV3Ll7zhmoGyZwE",
                "name": "/home/bae/app/images/img2.jpg",
                "update_time": 1505031096,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkolMOlXOZazUNdDXaxTiabEB8xHDBa3lfjupHWn2vxicToxEVcfk5vRmxg/0?wx_fmt=jpeg"
            },
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnPz6IegQ220nYBKW4KIjzWo",
                "name": "/home/bae/app/images/img1.jpg",
                "update_time": 1505031094,
                "url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75APxcWy4fPrtqYxJfTKgnQkoUPZ1Bdf9W7ncib8AB0AQaa0LUibWYicLJ1ZbiacUdDQian9us7E5p2Rxiaiaw/0?wx_fmt=jpeg"
            }
        ],
        "total_count": 9,
        "item_count": 9
    }

    返回图文结果如下:

    {
        "item": [
            {
                "media_id": "FrsRJ3g3BHR-pIkuFLARnAwGsFjf8Rckbd63rFBsE4o",
                "content": {
                    "news_item": [
                        {
                            "title": "第一个图文永久素材",
                            "author": "Perter",
                            "digest": "第一个图文永久素材摘要",
                            "content": "123",
                            "content_source_url": "http://www.baidu.com",
                            "thumb_media_id": "FrsRJ3g3BHR-pIkuFLARnHjI9Cq9lDFas4Kp8otlAUQ",
                            "show_cover_pic": 1,
                            "url": "http://mp.weixin.qq.com/s?__biz=MzUzMzI2OTQ3Mw==&mid=100000013&idx=1&sn=a6d09fe2e87c320b69a284b1dee01c4b&chksm=7aa7df834dd05695e0dfa4108fee82f8734d52430f93f4e24b0077de2e1712345e7d87f25fda#rd",
                            "thumb_url": "http://mmbiz.qpic.cn/mmbiz_jpg/rE2vM1t75ANDqb5Ud7WdHqo3oWodmOtCBPxaicWWs4Gg7kwmqx2vb3NkkuzM8iczib4qltC8GQYib4xHqXu7SwZRrw/0?wx_fmt=jpeg",
                            "need_open_comment": 0,
                            "only_fans_can_comment": 0
                        }
                    ],
                    "create_time": 1505139219,
                    "update_time": 1505142464
                },
                "update_time": 1505142464
            }
        ],
        "total_count": 1,
        "item_count": 1
    }

    相关博客

    微信公众号开发(一)服务器及接口的配置

    微信公众号开发(二)基础接口

    微信公众号开发(三)获取access_token

    微信公众号开发(四)自定义菜单

    微信公众号开发(五)个性化菜单

    微信公众号开发(六)素材管理

    微信公众号开发(七)发送客服消息

    微信公众号开发(八)用户管理

    微信公众号开发(九)群发消息接口

    微信公众号开发(十)模板消息

    微信公众号开发(十一)生成带参数二维码

    微信公众号开发(十二)OAuth2.0网页授权

     

     

    展开全文
  • 微信开发素材管理是子恒老师《微信公众平台开发》视频教程的第三部。详细讲解了用php开发微信,对微信公众平台中的素材管理开发。内容包含微信临时素材,永久素材的上传,删除,获取素材的media_id等等。欢迎反馈...
  • 关键字:curl、微信开发、上传永久素材前言微信开发,需要使用的素材(如图片、视频)必须先上传到微信服务器,通过微信服务器返回的meida_id在腾讯系域名内使用。当然可以直接使用代码来实现上传请求,获取微信...

    关键字:curl、微信开发、上传永久素材

    前言

    微信开发,需要使用的素材(如图片、视频)必须先上传到微信服务器,通过微信服务器返回的meida_id在腾讯系域名内使用。当然可以直接使用代码来实现上传请求,获取微信服务器返回的media_id,但是这样的方式略显麻烦,幸亏微信开发可以通过curl命令直接上传素材获取返回的url。

    curl下载安装

    curl是一种命令行工具,作用是发出网络请求,得到和提取返回的数据。在curl工具下载页根据系统下载相应的版本,比如Windows系统下载win32版本,需要注意的是,如果没有使用ssl协议(https),直接下载无ssl版本即可,比如curl-7.16.0-win32-nossl.zip。如果使用了ssl协议(https),就得下载ssl版本,比如curl-7.16.0-win32-ssl.zip,使用ssl版本还需要下载OpenSSL软件(安装exe即可)实现SSL协议。

    curl上传素材

    下载完成的curl压缩包解压之后,打开dos命令行工具(cmd),从dos进入curl根目录(cd..)。输入curl命令即可上传素材到微信服务器。命令如下:

    curl  -F media=@1.jpg -F type=image "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=LJLJ3oEHi8rcuJnUv6RryYHpiVybevrtR4upY_W5_gqXLDhtAHj2-qaxYzfMKe2gSQtO4mPsmoWmu9LUPvLv7cNtnmtC1ezZj2lxwqd9U1eY35rTeuhoyufpcfmf4XgLLXZdAAACOQ"

    命令需要注意两点:①上传素材的地址相对于curl目录,路径要确认无误,否则curl会找不到素材,一般把素材放在curl目录中。②什么微信公众号使用该素材,就得用该微信公众号的appid和appsecret生成的access_token,否则在微信公众号中无法使用该素材。

    在dos中返回的字符串

    {"media_id":"1YTbzmBpzu9_MDbee6yPlfvtqNbJufAbqJmsb3kkFA","url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/gMreo1rjy9LIGD9GVeNyWmPHV2nzmiaBXhs8qVaDloQ4iaIhHhIwJAu4ZnmuyIPFqvGCZDacTn748eq4iaBmYXj3Q\/0?wx_fmt=jpeg"}
    
    其中的media_id就可以在微信中唯一标记我们上传的永久素材。
    展开全文
  • 微信上传图片到本地服务器的...3.前端将serviceid传给后台,后台通过serviceid微信下载临时素材保存到服务器 4.保存成功告诉前台保存成功 此处展示后台通过前台给的serviceid下载临时素材 /** * 微信下载临时...
    微信上传图片到本地服务器的流程
    1.前端通过微信jssdk里面的图片上传功能,找到本地图片生成localid
    2.将图片上传到微信临时素材中,是有有效期的生成serviceid
    3.前端将serviceid传给后台,后台通过serviceid去微信下载临时素材保存到服务器
    4.保存成功告诉前台保存成功
    
    
    此处展示后台通过前台给的serviceid下载临时素材
    /**
         * 微信下载临时素材  serviceid 为微信服务器上存放临时素材的标识
         */
        public function DownImage($serviceid){
            //获取临时素材
            $imageAll = $this->test($serviceid);
            $savename = md5(microtime(true));
            $savename = $savename.mt_rand(1,9999).".jpg";
            //图片保存到服务器
            $imgurl = $this->saveWeixinFile($savename,$imageAll['body']);
            return $imgurl;
        }
        /**
         * 从微信下载图片
         */
        public function test($serviceid){
            $wx = $this->getCacheToken();
            $url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=".$wx['value']."&media_id=".$serviceid;
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_HEADER, 0);    
            curl_setopt($ch, CURLOPT_NOBODY, 0);    //只取body头
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $package = curl_exec($ch);
            $httpinfo = curl_getinfo($ch);
            curl_close($ch);
            $imageAll = array_merge(array('header' => $httpinfo), array('body' => $package)); 
            return $imageAll;
        }
    
        //获取access_token   我的access_token存在了数据库里面,具体方法在文章jssdk里面
        private function getCacheToken()
        {
            $time = time();
            $where['name'] = ['=','access_token'];
            $where['expire_time'] = ['>',$time];
            $result = model('wx')->WxFind($where);
            return $result;
        }
    
        /**
         * 保存图片
         * @param  [type] $filename    [description]
         * @param  [type] $filecontent [description]
         * @return [type]              [description]
         */
        private function saveWeixinFile($filename,$filecontent)
        { 
            $path = "uploads/".date('Ymd');//路径
            $a = is_dir($path);
            if (!$a) {
                mkdir($path,0777,true);
            }
            $imageSrc = $path."/".$filename; //图片名字
            $imgpath = ROOT_PATH."public/".$imageSrc;
            $imgpath = str_replace("\\","/",$imgpath);
            $local_file = fopen($imgpath, 'w');
            if (false !== $local_file){
                if (false !== fwrite($local_file, $filecontent)) {
                    $imageSrc = config('http_url')."/".$path."/".$filename;
                    fclose($local_file);
                    return $imageSrc;
                }
            }
    
        }

     

    展开全文
  • 一、本节要点 1.获取临时素材接口 请求方式:GET(HTTPS) 请求地址:...media_id=MEDIA_ID 2.获取临时素材接口的返回结果 企业微信官方开发文档中说明的返回结果如下: 若你以为这就...

    一、本节要点

    1.获取临时素材接口

    请求方式:GET(HTTPS)

    请求地址:https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID

    2.获取临时素材接口的返回结果

    企业微信官方开发文档中说明的返回结果如下:

    若你以为这就是返回结果,然后跟之前一样,先访问接口,从http连接的输入流中的获取回结果的文本内容,你会发现你接收到的结果是一堆乱码。

    这是为何?

    以图片为例,此处千万要注意,微信返回的结果是一个文件流形式的图片,当我们从http连接的输入流中的获取回结果的文本内容,也就是获取图片的文本内容时,当然就是一堆乱码了。

    这就好比你用记事本打开一张图片,然后发现内容是一片乱码。这再正常不过。所以我们接受图片的时候不能只接收文本数据,而是要接收流。

     

    千万得注意:获取临时素材时,微信返回的结果是一个流形式的临时素材。

    我们需要做的就是调用接口,获取http连接的输入流中数据,再将输入流中的数据写入到输出流,再通过输出流生成一张图片。这张图片就是微信返回的临时素材了。

     

    3.下载文件时的文件路径

    request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")

    将获取路径:%TOMCAT_HOME%/webapp/工程名。若不是这个路径就请参考:Eclipse中的Web项目自动部署到Tomcat

     

    String savePath=request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")+"/img/";

    将获取路径:%TOMCAT_HOME%/webapp/工程名/img/

    即从微信服务器下载的图片都保存在这个路径下。

     

    二、代码实现

    这里承接上一节。在上一节中我们完成了JSSDK的配置,并且用图片上传接口将图片上传到了微信服务器。这一节我们需要做的就是在图片上传到微信服务器后,根据微信服务器返回的serverId(即mediaId)来调用获取临时素材的接口,进行临时素材的下载,并保存到本地指定的路径下。

    2.1 UploadExpenseAccaoutServlet

    package com.ray.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.ray.service.TempMaterialService;
    import com.ray.util.WeiXinParamesUtil;
    import com.ray.util.WeiXinUtil;
    
    /**
     * Servlet implementation class UploadExpenseAccaoutServlet
     */
    @WebServlet("/UploadExpenseAccaoutServlet")
    public class UploadExpenseAccaoutServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        /**
         * @see HttpServlet#HttpServlet()
         */
        public UploadExpenseAccaoutServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
    
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
    
            String mediaId=request.getParameter("serverId");
            System.out.println("serverId:"+mediaId);
    
            String accessToken= WeiXinUtil.getAccessToken(WeiXinParamesUtil.corpId, WeiXinParamesUtil.contactsSecret).getToken();
            System.out.println("accessToken:"+accessToken);
    
            //String savePath=System.getProperty("user.dir").replaceAll("\\\\", "/")+"/WebContent/img/"+mediaId+".png"; 
            String savePath=request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/")+"/img/"; 
            System.out.println("savePath:"+savePath);
    
            //2.调用业务类,获取临时素材
            TempMaterialService tms=new TempMaterialService();
            tms.getTempMaterial(accessToken, mediaId,savePath);
    
    
            PrintWriter out = response.getWriter(); 
            out.print("HHHHHHHHHH");  
            out.close();  
            out = null;  
        }
    
    }
    View Code

     

    在此servlet中

    (1)接收serverId

    (2)调用临时素材业务类的方法TempMaterialService.getTempMaterial(accessToken, mediaId,savePath),获取临时素材。

     

    2.2 临时素材业务类—TempMaterialService

    package com.ray.service;
    
    import java.io.File;
    import java.io.UnsupportedEncodingException;
    
    import com.ray.util.WeiXinUtil;
    
    import net.sf.json.JSONObject;
    
    /**@desc  : 临时素材业务类
     * 
     * @author: shirayner
     * @date  : 2017-8-18 下午2:07:25
     */
    public class TempMaterialService {
        
        //上传临时素材url
        public String uploadTempMaterial_url="https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
    
        //获取临时素材url
        public String getTempMaterial_url="https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
    
        /**
         * @desc :上传临时素材
         *  
         * @param accessToken   接口访问凭证 
         * @param type   媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file) 
         * @param fileUrl  本地文件的url。例如 "D/1.img"。
         * @return JSONObject   上传成功后,微信服务器返回的参数,有type、media_id    、created_at
         */
        public JSONObject uploadTempMaterial(String accessToken,String type,String fileUrl){
            //1.创建本地文件
            File file=new File(fileUrl);
    
            //2.拼接请求url
            uploadTempMaterial_url = uploadTempMaterial_url.replace("ACCESS_TOKEN", accessToken)
                    .replace("TYPE", type);
    
            //3.调用接口,发送请求,上传文件到微信服务器
            String result=WeiXinUtil.httpRequest(uploadTempMaterial_url, file);
    
            //4.json字符串转对象:解析返回值,json反序列化
            result = result.replaceAll("[\\\\]", "");
            System.out.println("result:" + result);
            JSONObject resultJSON = JSONObject.fromObject(result);
    
            //5.返回参数判断
            if (resultJSON != null) {
                if (resultJSON.get("media_id") != null) {
                    System.out.println("上传" + type + "临时素材成功:"+resultJSON.get("media_id"));
                    return resultJSON;
                } else {
                    System.out.println("上传" + type + "临时素材成功失败");
                }
            }
            return null;
        }
    
        /** 2.获取临时素材
         * 
         * @param accessToken
         * @param mediaId
         * @return
         * @throws UnsupportedEncodingException 
         */
        public void getTempMaterial(String accessToken,String mediaId,String savePath) throws UnsupportedEncodingException{
    
            //String savePath=System.getProperty("user.dir").replaceAll("\\\\", "/")+"/WebContent/img/"+mediaId+".png"; 
            //System.out.println("service savePath:"+savePath);
            
            //1.拼接请求url
            getTempMaterial_url=getTempMaterial_url.replace("ACCESS_TOKEN", accessToken)
                    .replace("MEDIA_ID", mediaId);
    
            savePath=savePath+mediaId;
            //2.调用接口,发送请求,获取临时素材
            File file=null;
            try {
                file = WeiXinUtil.getFile(getTempMaterial_url,savePath);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            System.out.println("file:"+file.getName());
    
        
        }
    
        
        
    
    
    }
    View Code

    在此类的获取临时素材方法中:

    (1)拼接微信获取临时素材的接口url

    (2)调用WeiXinUtil.getFile(getTempMaterial_url,savePath),向微信发起https请求,并将接收到的图片下载到savePath指定的路径下

     

    2.3 微信工具类—WeiXinUtil

    package com.ray.util;
    
    import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.ConnectException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Formatter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.servlet.http.HttpServletRequest;
    
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.ray.pojo.AccessToken;
    
    
    
    
    import net.sf.json.JSONException;
    import net.sf.json.JSONObject;
    
    public class WeiXinUtil {
    
        private static Logger log = LoggerFactory.getLogger(WeiXinUtil.class);  
        //微信的请求url
        //获取access_token的接口地址(GET) 限200(次/天)  
        public final static String access_token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={corpsecret}";  
        //获取jsapi_ticket的接口地址(GET) 限200(次/天)  
        public final static String jsapi_ticket_url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESSTOKEN";  
    
    
    
        /**
         * 1.发起https请求并获取结果 
         *  
         * @param requestUrl 请求地址 
         * @param requestMethod 请求方式(GET、POST) 
         * @param outputStr 提交的数据 
         * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) 
         */  
        public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {  
            JSONObject jsonObject = null;  
            StringBuffer buffer = new StringBuffer();  
            try {  
                // 创建SSLContext对象,并使用我们指定的信任管理器初始化  
                TrustManager[] tm = { new MyX509TrustManager() };  
                SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");  
                sslContext.init(null, tm, new java.security.SecureRandom());  
                // 从上述SSLContext对象中得到SSLSocketFactory对象  
                SSLSocketFactory ssf = sslContext.getSocketFactory();  
    
                URL url = new URL(requestUrl);  
                HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();  
                httpUrlConn.setSSLSocketFactory(ssf);  
    
                httpUrlConn.setDoOutput(true);  
                httpUrlConn.setDoInput(true);  
                httpUrlConn.setUseCaches(false);  
                // 设置请求方式(GET/POST)  
                httpUrlConn.setRequestMethod(requestMethod);  
    
                if ("GET".equalsIgnoreCase(requestMethod))  
                    httpUrlConn.connect();  
    
                // 当有数据需要提交时  
                if (null != outputStr) {  
                    OutputStream outputStream = httpUrlConn.getOutputStream();  
                    // 注意编码格式,防止中文乱码  
                    outputStream.write(outputStr.getBytes("UTF-8"));  
                    outputStream.close();  
                }  
    
                // 将返回的输入流转换成字符串  
                InputStream inputStream = httpUrlConn.getInputStream();  
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");  
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
    
                String str = null;  
                while ((str = bufferedReader.readLine()) != null) {  
                    buffer.append(str);  
                }  
                bufferedReader.close();  
                inputStreamReader.close();  
                // 释放资源  
                inputStream.close();  
                inputStream = null;  
                httpUrlConn.disconnect();  
                jsonObject = JSONObject.fromObject(buffer.toString());  
            } catch (ConnectException ce) {  
                log.error("Weixin server connection timed out.");  
            } catch (Exception e) {  
                log.error("https request error:{}", e);  
            }  
            return jsonObject;  
        }  
    
       /**
         * 2.发送https请求之获取临时素材 
         * @param requestUrl
         * @param savePath  文件的保存路径,此时还缺一个扩展名
         * @return
         * @throws Exception
         */
        public static File getFile(String requestUrl,String savePath) throws Exception {  
            //String path=System.getProperty("user.dir")+"/img//1.png";
        
            
                // 创建SSLContext对象,并使用我们指定的信任管理器初始化  
                TrustManager[] tm = { new MyX509TrustManager() };  
                SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");  
                sslContext.init(null, tm, new java.security.SecureRandom());  
                // 从上述SSLContext对象中得到SSLSocketFactory对象  
                SSLSocketFactory ssf = sslContext.getSocketFactory();  
    
                URL url = new URL(requestUrl);  
                HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();  
                httpUrlConn.setSSLSocketFactory(ssf);  
    
                httpUrlConn.setDoOutput(true);  
                httpUrlConn.setDoInput(true);  
                httpUrlConn.setUseCaches(false);  
                // 设置请求方式(GET/POST)  
                httpUrlConn.setRequestMethod("GET");  
    
                httpUrlConn.connect();  
    
                //获取文件扩展名
                String ext=getExt(httpUrlConn.getContentType());
                savePath=savePath+ext;
                System.out.println("savePath"+savePath);
                //下载文件到f文件
                File file = new File(savePath);
    
                
                // 获取微信返回的输入流
                InputStream in = httpUrlConn.getInputStream(); 
                
                //输出流,将微信返回的输入流内容写到文件中
                FileOutputStream out = new FileOutputStream(file);
                 
                int length=100*1024;
                byte[] byteBuffer = new byte[length]; //存储文件内容
                
                int byteread =0;
                int bytesum=0;
                
                while (( byteread=in.read(byteBuffer)) != -1) {  
                    bytesum += byteread; //字节数 文件大小 
                    out.write(byteBuffer,0,byteread);  
                    
                }  
                System.out.println("bytesum: "+bytesum);
                
                in.close();  
                // 释放资源  
                out.close();  
                in = null;  
                out=null;
                
                httpUrlConn.disconnect();  
    
                
                return file;
        }  
        
        
    
        /**
         * @desc :2.微信上传素材的请求方法
         *  
         * @param requestUrl  微信上传临时素材的接口url
         * @param file    要上传的文件
         * @return String  上传成功后,微信服务器返回的消息
         */
        public static String httpRequest(String requestUrl, File file) {  
            StringBuffer buffer = new StringBuffer();  
    
            try{
                //1.建立连接
                URL url = new URL(requestUrl);
                HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  //打开链接
    
                //1.1输入输出设置
                httpUrlConn.setDoInput(true);
                httpUrlConn.setDoOutput(true);
                httpUrlConn.setUseCaches(false); // post方式不能使用缓存
                //1.2设置请求头信息
                httpUrlConn.setRequestProperty("Connection", "Keep-Alive");
                httpUrlConn.setRequestProperty("Charset", "UTF-8");
                //1.3设置边界
                String BOUNDARY = "----------" + System.currentTimeMillis();
                httpUrlConn.setRequestProperty("Content-Type","multipart/form-data; boundary="+ BOUNDARY);
    
                // 请求正文信息
                // 第一部分:
                //2.将文件头输出到微信服务器
                StringBuilder sb = new StringBuilder();
                sb.append("--"); // 必须多两道线
                sb.append(BOUNDARY);
                sb.append("\r\n");
                sb.append("Content-Disposition: form-data;name=\"media\";filelength=\"" + file.length()
                + "\";filename=\""+ file.getName() + "\"\r\n");
                sb.append("Content-Type:application/octet-stream\r\n\r\n");
                byte[] head = sb.toString().getBytes("utf-8");
                // 获得输出流
                OutputStream outputStream = new DataOutputStream(httpUrlConn.getOutputStream());
                // 将表头写入输出流中:输出表头
                outputStream.write(head);
    
                //3.将文件正文部分输出到微信服务器
                // 把文件以流文件的方式 写入到微信服务器中
                DataInputStream in = new DataInputStream(new FileInputStream(file));
                int bytes = 0;
                byte[] bufferOut = new byte[1024];
                while ((bytes = in.read(bufferOut)) != -1) {
                    outputStream.write(bufferOut, 0, bytes);
                }
                in.close();
                //4.将结尾部分输出到微信服务器
                byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
                outputStream.write(foot);
                outputStream.flush();
                outputStream.close();
    
    
                //5.将微信服务器返回的输入流转换成字符串  
                InputStream inputStream = httpUrlConn.getInputStream();  
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
    
                String str = null;  
                while ((str = bufferedReader.readLine()) != null) {  
                    buffer.append(str);  
                }  
    
                bufferedReader.close();  
                inputStreamReader.close();  
                // 释放资源  
                inputStream.close();  
                inputStream = null;  
                httpUrlConn.disconnect();  
    
    
            } catch (IOException e) {
                System.out.println("发送POST请求出现异常!" + e);
                e.printStackTrace();
            } 
            return buffer.toString();
        }
    
        /** 
         * 2.发起http请求获取返回结果 
         *  
         * @param requestUrl 请求地址 
         * @return 
         */  
        public static String httpRequest(String requestUrl) {  
            StringBuffer buffer = new StringBuffer();  
            try {  
                URL url = new URL(requestUrl);  
                HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  
    
                httpUrlConn.setDoOutput(false);  
                httpUrlConn.setDoInput(true);  
                httpUrlConn.setUseCaches(false);  
    
                httpUrlConn.setRequestMethod("GET");  
                httpUrlConn.connect();  
    
                // 将返回的输入流转换成字符串  
                InputStream inputStream = httpUrlConn.getInputStream();  
                //InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);  
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
    
                String str = null;  
                while ((str = bufferedReader.readLine()) != null) {  
                    buffer.append(str);  
    
                }  
                bufferedReader.close();  
                inputStreamReader.close();  
                // 释放资源  
                inputStream.close();  
                inputStream = null;  
                httpUrlConn.disconnect();  
    
            } catch (Exception e) {  
            }  
            return buffer.toString();  
        }  
    
    
        /** 
         * 3.获取access_token 
         *  
         * @param appid 凭证 
         * @param appsecret 密钥 
         * @return 
         */  
        public static AccessToken getAccessToken(String appid, String appsecret) {  
            AccessToken accessToken = null;  
    
            String requestUrl = access_token_url.replace("{corpId}", appid).replace("{corpsecret}", appsecret);  
            JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  
            // 如果请求成功  
            if (null != jsonObject) {  
                try {  
                    accessToken = new AccessToken();  
                    accessToken.setToken(jsonObject.getString("access_token"));  
                    accessToken.setExpiresIn(jsonObject.getInt("expires_in"));  
                } catch (JSONException e) {  
                    accessToken = null;  
                    // 获取token失败  
                    log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));  
                }  
            }  
            return accessToken;  
        }  
    
        /**
         * 4. 获取JsapiTicket
         * @param accessToken
         * @return
         */
        public static String getJsapiTicket(String accessToken){
    
    
            String requestUrl = jsapi_ticket_url.replace("ACCESSTOKEN", accessToken);  
            JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  
    
            String  jsapi_ticket="";
            // 如果请求成功  
            if (null != jsonObject) {  
                try {  
                    jsapi_ticket=jsonObject.getString("ticket");  
    
                } catch (JSONException e) {  
    
                    // 获取token失败  
                    log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));  
                }  
            }  
            return jsapi_ticket;  
        }
    
        /**
         * 3.获取企业微信的JSSDK配置信息
         * @param request
         * @return
         */
        public static Map<String, Object> getWxConfig(HttpServletRequest request) {
            Map<String, Object> ret = new HashMap<String, Object>();
            //1.准备好参与签名的字段
    
            String nonceStr = UUID.randomUUID().toString(); // 必填,生成签名的随机串
            //System.out.println("nonceStr:"+nonceStr);
            String accessToken=WeiXinUtil.getAccessToken(WeiXinParamesUtil.corpId, WeiXinParamesUtil.agentSecret).getToken();
            String jsapi_ticket =getJsapiTicket(accessToken);// 必填,生成签名的H5应用调用企业微信JS接口的临时票据
            //System.out.println("jsapi_ticket:"+jsapi_ticket);
            String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳
            //System.out.println("timestamp:"+timestamp);
            String url=request.getRequestURL().toString();
            //System.out.println("url:"+url);
            
            //2.字典序           ,注意这里参数名必须全部小写,且必须有序
            String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "&timestamp=" + timestamp + "&url=" + url;
    
            //3.sha1签名
            String signature = "";
            try {
                MessageDigest crypt = MessageDigest.getInstance("SHA-1");
                crypt.reset();
                crypt.update(sign.getBytes("UTF-8"));
                signature = byteToHex(crypt.digest());
                //System.out.println("signature:"+signature);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            ret.put("appId", WeiXinParamesUtil.corpId);
            ret.put("timestamp", timestamp);
            ret.put("nonceStr", nonceStr);
            ret.put("signature", signature);
            return ret;
        }
    
    
        /**
         * 方法名:byteToHex</br>
         * 详述:字符串加密辅助方法 </br>
         * 开发人员:souvc  </br>
         * 创建时间:2016-1-5  </br>
         * @param hash
         * @return 说明返回值含义
         * @throws 说明发生此异常的条件
         */
        private static String byteToHex(final byte[] hash) {
            Formatter formatter = new Formatter();
            for (byte b : hash) {
                formatter.format("%02x", b);
            }
            String result = formatter.toString();
            formatter.close();
            return result;
    
        }
        
        
        
        private static String getExt(String contentType){
            if("image/jpeg".equals(contentType)){
                return ".jpg";
            }else if("image/png".equals(contentType)){
                return ".png";
            }else if("image/gif".equals(contentType)){
                return ".gif";
            }
            
            return null;
        }
    }
    View Code

     

    获取临时素材的方法为:WeiXinUtil.getFile(String requestUrl,String savePath)

    在此方法中:

    (1)发起https请求,获取输入流

    (2)从输入流中获取文件类型,与savePath一起组成图片最终的路径(或者说是文件名A)

    (3)根据文件名A创建输出流

    (4)将输入流中的数据写入到输出流中,这样图片就保存到了文件A中。

    (5)返回文件A

     

    展开全文
  • 微信素材分为临时素材和永久素材两种 新增临时素材 公众号经常有需要用到一些临时性的多媒体素材的场景,例如在使用接口特别是发送消息时,对多媒体文件、多媒体消息的获取和调用等操作,是通过media_id来...

    简介

    微信素材分为临时素材和永久素材两种

    • 新增临时素材
      公众号经常有需要用到一些临时性的多媒体素材的场景,例如在使用接口特别是发送消息时,对多媒体文件、多媒体消息的获取和调用等操作,是通过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格式

    • 新增永久素材
      对于常用的素材,开发者可通过本接口上传到微信服务器,永久使用。新增的永久素材也可以在公众平台官网素材管理模块中查询管理。
      请注意:
      1、最近更新:永久图片素材新增后,将带有URL返回给开发者,开发者可以在腾讯系域名内使用(腾讯系域名外使用,图片将被屏蔽)。
      2、公众号的素材库保存总数量有上限:图文消息素材、图片素材上限为5000,其他类型为1000。
      3、素材的格式大小等要求与公众平台官网一致:
      图片(image): 2M,支持bmp/png/jpeg/jpg/gif格式
      语音(voice):2M,播放长度不超过60s,mp3/wma/wav/amr格式
      视频(video):10MB,支持MP4格式
      缩略图(thumb):64KB,支持JPG格式
      4、图文消息的具体内容中,微信后台将过滤外部的图片链接,图片url需通过”上传图文消息内的图片获取URL”接口上传图片获取。
      5、”上传图文消息内的图片获取URL”接口所上传的图片,不占用公众号的素材库中图片数量的5000个的限制,图片仅支持jpg/png格式,大小必须在1MB以下。
      6、图文消息支持正文中插入自己帐号和其他公众号已群发文章链接的能力。
      PS:=============请查阅JAVA微信公众号开发第1篇之环境配置与开发接入进行基本微信接入配置============

    上传微信素材

    使用wxService.mediaUpload(mediaType, fileType, inputStream)方法

    /**
        * <p>Title: addImgMaterial</p>
        * <p>Description: 上传我的二维码(永久)</p>
        * @param headurl 头像
        * @param wxqr    二维码
        * @return
        * @throws WxErrorException
        * @throws IOException
        */
        public WxMediaUploadResult addImgMaterial(String nickname,String openid,String headurl,String wxqr) throws WxErrorException, IOException{
            WxMediaUploadResult wxMediaUploadResult=wxService.mediaUpload(WxConsts.MEDIA_IMAGE,WxConsts.FILE_JPG,PictureMerge.getImageStream(PictureMerge.myQr(nickname,openid,headurl, wxqr)));
            return wxMediaUploadResult;
        }

    博主这是通过头像、带参二维码和系统背景图生成用户针对本公众号的专属二维码,具体生成方法请查阅JAVA工具类之多图片合成与图片添加文字博文

    总结

    本文博主通过引入微信jar的方式,使用封装的方法进行素材上传,详细读者可以查阅微信jar源码,了解详细开发步骤。
    这里写图片描述

    效果

    这里写图片描述
    这里写图片描述

    展开全文
  • 因公司项目需求,需要开发一套微信公众后台管理系统,因为个人能力和时间限制,这里选择了SDK开发。 选用的SDK是:Gaoming13/wechat-php-sdk github地址:https://github.com/gaoming13/wechat-php-sdk (之后...
  • 小易Smalle博文:微信公众平台开发素材管理】获取临时素材http://blog.csdn.net/oldinaction/article/details/47955557 所用代码
  • 微信公众号
  • 微信开发第七篇发送素材(图文)信息 2015年08月31日 16:00:29 主沉浮 阅读数:6979 https://blog.csdn.net/u010773333/article/details/48135043 最近产品经理要做每天推送图文信息的功能,哎,还要超链接传递...
  • 写这个方法肯定也是根据微信开发文档说明总结出获取的方法,首先先看微信开发文档给出的内容获取方法接口提示: 先给个链接地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738734 首先...
  • 最近公司要做微信方面的开发,今天说下,如何使用微信素材管理的接口,这里主要讲下素材的上传接口,下载之类的比较简单(就是解析json而已),今天会把所有的素材上传写道一个方法里供大家参考,关于上传的接口...
  • 微信公众号在使用的接口的时候是通过media_id来进行的,所以在使用的接口的时候我们往往需要先上传素材素材管理分为临时素材和永久素材 1)、临时素材媒体文件在微信后台保存时间为3天,即3天后media_id失效,详细...
  • 手把手教你springboot企业微信开发(二)1、企业微信开发第一步2、weixin-java-cp-demo-master1)、引入thymeleaf改造项目2)增加Configuration3)回到企业号4)穿透内外网5)完善 从这一篇开始,开始从实际项目探索...
  • 微信公众平台开发——新增永久素材请求接口接口使用 接口详情:微信公众平台新增永久素材 新增永久图文素材请求接口,POST数据就能实现,这里主要记录下C#如何通过通过Form表单上传文件(图片,音频,视频等) 请求...
  • 微信素材管理和群发这块文档对Java很不友好。本文只对新增临时素材,新增永久素材做介绍,其余获取、删除、修改自行补充 公众号经常有需要用到一些临时性的多媒体素材的场景,例如在使用接口特别是发送消息时,对...
  • //转载 记录一下这些都是测试过后可以使用的代码!本博文是记录一下。怎么上传临时的素材后获取id然后进行... php 微信开发之新增上传/获取下载临时素材 代码 define("AppID","");//你的id define("AppSecret", "");
  • * 上传永久素材 * @param file * @param type * @param title type为video时需要,其他类型设null * @param introduction type为video时需要,其他类型设null * @return {"media_id":MEDIA_ID,"url":URL} ...
  • 1.企业微信获取临时素材,此处为主要部分代码,加群:372319250,咨询企业微信其他相关问题,或者下载文件“企业微信开发”,查看demo2.php不同框架大同小异,一定要根据文档要求写!&lt;?php//media_id为微信...
1 2 3 4 5 ... 20
收藏数 2,600
精华内容 1,040