Java微信公众平台之素材管理
微信素材管理和群发这块文档对Java很不友好。本文只对新增临时素材,新增永久素材做介绍,其余获取、删除、修改自行补充
公众号经常有需要用到一些临时性的多媒体素材的场景,例如在使用接口特别是发送消息时,对多媒体文件、多媒体消息的获取和调用等操作,是通过media_id来进行的。素材管理接口对所有认证的订阅号和服务号开放。
素材的限制
图片(image):2M,支持PNG\JPEG\JPG\GIF格式
语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式
视频(video):10MB,支持MP4格式
缩略图(thumb):64KB,支持JPG格式
一、新增临时素材
接口:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE,再传一个媒体文件类型,可以是图片(image)、语音(voice)、视频(video)和缩略图(thumb)。
1、订阅号和服务号要通过认证
2、临时素材media_id是可复用的
3、媒体文件在微信后台保存时间为3天,即3天后media_id失效。
/** *上传临时素材(本地) * *@paramaccessToken *@paramtype *媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) *@parampath *图片路径 *@return */ publicstaticUploadMediasResultuploadTempMediaFile(StringaccessToken,Stringtype,Stringpath){ UploadMediasResultresult=null; TreeMapparams=newTreeMap<>(); params.put("access_token",accessToken); params.put("type",type); try{ Stringjson=HttpsUploadMediaFile(SystemConfig.POST_METHOD,WechatConfig.UPLOAD_TEMP_MEDIA_TYPE_URL, params,path); result=JsonUtil.fromJsonString(json,UploadMediasResult.class); }catch(Exceptione){ e.printStackTrace(); } returnresult; } /** *上传临时素材(网络) * *@paramaccessToken *@paramtype *媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) *@parampath *图片路径 *@return */ publicstaticUploadMediasResultuploadTempMedia(StringaccessToken,Stringtype,Stringpath){ UploadMediasResultresult=null; TreeMap params=newTreeMap<>(); params.put("access_token",accessToken); params.put("type",type); try{ Stringjson=HttpsUploadMedia(SystemConfig.POST_METHOD,WechatConfig.UPLOAD_TEMP_MEDIA_TYPE_URL,params, path,0,0); result=JsonUtil.fromJsonString(json,UploadMediasResult.class); }catch(Exceptione){ e.printStackTrace(); } returnresult; }
二、新增永久素材
接口:https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE,媒体文件类型,分别有图片(image)、语音(voice)、视频(video,例外)和缩略图(thumb)
/** *上传永久素材(本地) * *@paramaccessToken *@paramtype *媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) *@return */ publicstaticUploadMediasResultuploadForeverMediaFile(StringaccessToken,Stringtype,Stringpath){ UploadMediasResultresult=null; TreeMapparams=newTreeMap<>(); params.put("access_token",accessToken); params.put("type",type); try{ Stringjson=HttpsUploadMediaFile(SystemConfig.POST_METHOD,WechatConfig.UPLOAD_FOREVER_MEDIA_TYPE_URL, params,path); result=JsonUtil.fromJsonString(json,UploadMediasResult.class); }catch(Exceptione){ e.printStackTrace(); } returnresult; } /** *上传永久素材(网络) * *@paramaccessToken *@paramtype *媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) *@return */ publicstaticUploadMediasResultuploadForeverMedia(StringaccessToken,Stringtype,Stringpath){ UploadMediasResultresult=null; TreeMap params=newTreeMap<>(); params.put("access_token",accessToken); params.put("type",type); try{ Stringjson=HttpsUploadMedia(SystemConfig.POST_METHOD,WechatConfig.UPLOAD_FOREVER_MEDIA_TYPE_URL,params, path,0,0); result=JsonUtil.fromJsonString(json,UploadMediasResult.class); }catch(Exceptione){ e.printStackTrace(); } returnresult; }
新增永久视频素材需特别注意,在上传视频素材时需要POST另一个表单,id为description,包含素材的描述信息title和introduction,内容格式为JSON
/** *上传永久素材(video) * *@paramaccessToken *@return */ publicstaticStringuploadForeverMediaFile(StringaccessToken,Stringtitle,Stringintroduction,Stringpath){ TreeMapparams=newTreeMap<>(); params.put("access_token",accessToken); params.put("type","video"); StringmediaId=null; try{ Stringjson=HttpsUploadVideoMediaFile(SystemConfig.POST_METHOD, WechatConfig.UPLOAD_FOREVER_MEDIA_TYPE_URL,params,path,title,introduction); mediaId=JsonUtil.fromJsonString(json,"media_id"); }catch(Exceptione){ e.printStackTrace(); } returnmediaId; } /** *上传永久素材(video,网络) * *@paramaccessToken *@return */ publicstaticStringuploadForeverMedia(StringaccessToken,Stringtitle,Stringintroduction,Stringpath){ TreeMap params=newTreeMap<>(); params.put("access_token",accessToken); params.put("type","video"); StringmediaId=null; try{ Stringjson=HttpsUploadVideoMedia(SystemConfig.POST_METHOD,WechatConfig.UPLOAD_FOREVER_MEDIA_TYPE_URL, params,path,title,introduction,0,0); mediaId=JsonUtil.fromJsonString(json,"media_id"); }catch(Exceptione){ e.printStackTrace(); } returnmediaId; }
三、新增永久图文素材
接口:https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=ACCESS_TOKEN,post信息参见UploadNewsMedia实体类
对于常用的素材,开发者可通过本接口上传到微信服务器,永久使用.
1、永久图片素材新增后,将带有URL返回给开发者,开发者可以在腾讯系域名内使用(腾讯系域名外使用,图片将被屏蔽)。
2、公众号的素材库保存总数量有上限:图文消息素材、图片素材上限为5000,其他类型为1000。
3、图文消息的具体内容中,微信后台将过滤外部的图片链接,图片url需通过"上传图文消息内的图片获取URL"接口上传图片获取。
4、"上传图文消息内的图片获取URL"接口所上传的图片,不占用公众号的素材库中图片数量的5000个的限制,图片仅支持jpg/png格式,大小必须在1MB以下。
5、图文消息支持正文中插入自己帐号和其他公众号已群发文章链接的能力。
/** *上传永久图文消息的素材 * *@paramaccessToken *授权token *@paramentity *图文消息对象 *@return */ publicstaticUploadMediasResultuploadNewsMedia(StringaccessToken,Listentity){ UploadMediasResultresult=null; TreeMap params=newTreeMap<>(); params.put("access_token",accessToken); //post提交的参数 TreeMap >dataParams=newTreeMap >(); dataParams.put("articles",entity); Stringdata=JsonUtil.toJsonString(dataParams); Stringjson=HttpReqUtil.HttpsDefaultExecute(SystemConfig.POST_METHOD, WechatConfig.UPLOAD_FOREVER_NEWS_MEDIA_URL,params,data); result=JsonUtil.fromJsonString(json,UploadMediasResult.class); returnresult; }
四、上传图文消息内的图片获取URL
接口:https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制。图片仅支持jpg/png格式,大小必须在1MB以下,此接口返回的url就是上传图片的URL,可放置图文消息中使用。
/** *上传图文消息内的图片获取URL(本地) * *@paramaccessToken *@parampath *@return */ publicstaticStringuploadImgMediaFile(StringaccessToken,Stringpath){ TreeMapparams=newTreeMap<>(); params.put("access_token",accessToken); Stringurl=null; try{ Stringjson=HttpsUploadMediaFile(SystemConfig.POST_METHOD,WechatConfig.UPLOAD_IMG_MEDIA_URL,params, path); url=JsonUtil.fromJsonString(json,"url"); }catch(Exceptione){ e.printStackTrace(); } returnurl; } /** *上传图文消息内的图片获取URL(网络) * *@paramaccessToken *@parampath *@return */ publicstaticStringuploadImgMedia(StringaccessToken,Stringpath){ TreeMap params=newTreeMap (); params.put("access_token",accessToken); Stringurl=null; try{ Stringjson=HttpsUploadMedia(SystemConfig.POST_METHOD,WechatConfig.UPLOAD_IMG_MEDIA_URL,params,path,0, 0); url=JsonUtil.fromJsonString(json,"url"); }catch(Exceptione){ e.printStackTrace(); } returnurl; }
五、部分工具类
配置类
publicstaticfinalStringUPLOAD_IMG_MEDIA_URL="https://api.weixin.qq.com/cgi-bin/media/uploadimg"; publicstaticfinalStringUPLOAD_FOREVER_NEWS_MEDIA_URL="https://api.weixin.qq.com/cgi-bin/material/add_news"; publicstaticfinalStringUPLOAD_TEMP_MEDIA_TYPE_URL="https://api.weixin.qq.com/cgi-bin/media/upload"; publicstaticfinalStringUPLOAD_FOREVER_MEDIA_TYPE_URL="https://api.weixin.qq.com/cgi-bin/material/add_material";
上传图文消息素材返回类
packagecom.phil.wechat.msg.model.media; /** *上传图文消息素材返回的结果 *@authorphil *@date2017年9月20日 * */ publicclassUploadMediasResult{ privateStringtype;//媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb),次数为news,即图文消息 privateStringmedia_id;//媒体文件/图文消息上传后获取的唯一标识 privateStringcreated_at;//媒体文件上传时间 }
上传图文消息素材实体类
packagecom.phil.wechat.msg.model.media; importjava.io.Serializable; /** *上传图文消息素材实体类 *@authorphil *@date2017年9月20日 */ publicclassUploadNewsMediaimplementsSerializable{ privatestaticfinallongserialVersionUID=6551817058101753854L; privateStringthumb_media_id;//图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得 privateStringauthor;//图文消息的作者 privateStringtitle;//图文消息的标题 privateStringcontent_source_url;//图文消息点击阅读原文的链接 privateStringcontent;//图文消息页面的内容,支持HTML标签 privateStringdigest;//图文消息的描述 privateintshow_conver_pic;//是否显示为封面1表示显示为封面0不显示为封面 }
上传方法
/** *上传媒体文件(本地) * *@parammethod *请求方法GET/POST *@parampath *api的路径 *@paramparam *api参数 *@parammediaPath *待上传的image/music的path *@return *@throwsException */ publicstaticStringHttpsUploadMediaFile(Stringmethod,Stringpath,Mapparam,StringmediaPath) throwsException{ Stringresult=null; URLurl=newURL(setParmas(param,path,"")); OutputStreamoutput=null; DataInputStreaminputStream=null; try{ Filefile=newFile(mediaPath); if(!file.isFile()||!file.exists()){ thrownewIOException("fileisnotexist"); } HttpURLConnectioncon=(HttpURLConnection)url.openConnection(); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); con.setRequestMethod(SystemConfig.POST_METHOD); //设置请求头信息 con.setRequestProperty("Connection","Keep-Alive"); con.setRequestProperty("Charset",SystemConfig.DEFAULT_CHARACTER_ENCODING); //设置边界 Stringboundary="----------"+System.currentTimeMillis(); con.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary); //请求正文信息 //第一部分 output=newDataOutputStream(con.getOutputStream()); IOUtils.write(("--"+boundary+"\r\n").getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write(("Content-Disposition:form-data;name=\"media\";filename=\""+file.getName()+"\"\r\n") .getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write( "Content-Type:application/octet-stream\r\n\r\n".getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING), output); //IOUtils.write(("Content-Type:"+fileExt+"\r\n\r\n").getBytes(),output); //文件正文部分 //把文件已流文件的方式推入到url中 inputStream=newDataInputStream(newFileInputStream(file)); IOUtils.copy(inputStream,output); //结尾部分 IOUtils.write(("\r\n--"+boundary+"--\r\n").getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); output.flush(); result=inputStreamToString(con.getInputStream()); }catch(MalformedURLExceptione){ e.printStackTrace(); }catch(ProtocolExceptione){ e.printStackTrace(); }catch(IOExceptione){ thrownewIOException("readdataerror"); }finally{ IOUtils.closeQuietly(output); IOUtils.closeQuietly(inputStream); } returnresult; } /** *上传媒体文件(不能本地) * *@parammethod *请求方法GET/POST *@parampath *api的路径 *@paramparam *api参数 *@parammediaPath *待上传的image/music的path *@paramconnTime *连接时间默认为5000 *@paramreadTime *读取时间默认为5000 *@return *@throwsException */ publicstaticStringHttpsUploadMedia(Stringmethod,Stringpath,Map param,StringmediaPath, intconnTime,intreadTime)throwsException{ Stringresult=""; URLurl=newURL(setParmas(param,path,"")); OutputStreamoutput=null; BufferedInputStreaminputStream=null; try{ Stringboundary="----"; HttpURLConnectionconn=getConnection(method,url); conn.setConnectTimeout(connTime==0?DEFAULT_CONNTIME:connTime); conn.setReadTimeout(readTime==0?DEFAULT_UPLOAD_READTIME:readTime); conn.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary); output=conn.getOutputStream(); URLmediaUrl=newURL(mediaPath); if(mediaUrl!=null){ HttpURLConnectionmediaConn=(HttpURLConnection)mediaUrl.openConnection(); mediaConn.setDoOutput(true); mediaConn.setUseCaches(false); mediaConn.setRequestMethod(SystemConfig.GET_METHOD); mediaConn.setConnectTimeout(connTime==0?DEFAULT_CONNTIME:connTime); mediaConn.setReadTimeout(readTime==0?DEFAULT_UPLOAD_READTIME:readTime); StringconnType=mediaConn.getContentType(); //获得文件扩展 StringfileExt=getFileExt(connType); IOUtils.write(("--"+boundary+"\r\n").getBytes(),output); IOUtils.write(("Content-Disposition:form-data;name=\"media\";filename=\""+getFileName(mediaPath) +"\"\r\n").getBytes(),output); IOUtils.write(("Content-Type:"+fileExt+"\r\n\r\n").getBytes(),output); inputStream=newBufferedInputStream(mediaConn.getInputStream()); IOUtils.copy(inputStream,output); IOUtils.write(("\r\n----"+boundary+"--\r\n").getBytes(),output); mediaConn.disconnect(); //获取输入流 result=inputStreamToString(conn.getInputStream()); } }catch(MalformedURLExceptione){ e.printStackTrace(); }catch(ProtocolExceptione){ e.printStackTrace(); }catch(IOExceptione){ e.printStackTrace(); }finally{ IOUtils.closeQuietly(output); IOUtils.closeQuietly(inputStream); } returnresult; } /** *上传Video媒体文件(本地) * *@parammethod *请求方法GET/POST *@parampath *api的路径 *@paramparam *api参数 *@parammediaPath *待上传的voide的path *@paramtitle *视频标题 *@paramintroduction *视频描述 *@return *@throwsException */ publicstaticStringHttpsUploadVideoMediaFile(Stringmethod,Stringpath,Map param, StringmediaPath,Stringtitle,Stringintroduction)throwsException{ Stringresult=null; URLurl=newURL(setParmas(param,path,"")); OutputStreamoutput=null; DataInputStreaminputStream=null; try{ Filefile=newFile(mediaPath); if(!file.isFile()||!file.exists()){ thrownewIOException("fileisnotexist"); } HttpURLConnectioncon=(HttpURLConnection)url.openConnection(); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); con.setRequestMethod(SystemConfig.POST_METHOD); //设置请求头信息 con.setRequestProperty("Connection","Keep-Alive"); con.setRequestProperty("Charset",SystemConfig.DEFAULT_CHARACTER_ENCODING); //设置边界 Stringboundary="----------"+System.currentTimeMillis(); con.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary); //请求正文信息 //第一部分 output=newDataOutputStream(con.getOutputStream()); IOUtils.write(("--"+boundary+"\r\n").getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write(("Content-Disposition:form-data;name=\"media\";filename=\""+file.getName()+"\"\r\n") .getBytes(),output); IOUtils.write("Content-Type:video/mp4\r\n\r\n".getBytes(),output); //文件正文部分 //把文件已流文件的方式推入到url中 inputStream=newDataInputStream(newFileInputStream(file)); IOUtils.copy(inputStream,output); //结尾部分 IOUtils.write(("--"+boundary+"\r\n").getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write("Content-Disposition:form-data;name=\"description\";\r\n\r\n" .getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write(("{\"title\":\""+title+"\",\"introduction\":\""+introduction+"\"}") .getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write(("\r\n--"+boundary+"--\r\n\r\n").getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING), output); output.flush(); result=inputStreamToString(con.getInputStream()); }catch(MalformedURLExceptione){ e.printStackTrace(); }catch(ProtocolExceptione){ e.printStackTrace(); }catch(IOExceptione){ thrownewIOException("readdataerror"); }finally{ IOUtils.closeQuietly(output); IOUtils.closeQuietly(inputStream); } returnresult; } /** *上传Video媒体文件(网络) * *@parammethod *请求方法GET/POST *@parampath *api的路径 *@paramparam *api参数 *@parammediaPath *待上传的voide的path *@paramtitle *视频标题 *@paramintroduction *视频描述 *@paramconnTime *连接时间默认为5000 *@paramreadTime *读取时间默认为5000 *@return *@throwsException */ publicstaticStringHttpsUploadVideoMedia(Stringmethod,Stringpath,Map param,StringmediaPath, Stringtitle,Stringintroduction,intconnTime,intreadTime)throwsException{ Stringresult=null; URLurl=newURL(setParmas(param,path,"")); OutputStreamoutput=null; BufferedInputStreaminputStream=null; try{ Stringboundary="----"; HttpURLConnectionconn=getConnection(method,url); conn.setConnectTimeout(connTime==0?DEFAULT_CONNTIME:connTime); conn.setReadTimeout(readTime==0?DEFAULT_UPLOAD_READTIME:readTime); conn.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary); output=conn.getOutputStream(); URLmediaUrl=newURL(mediaPath); if(mediaUrl!=null){ HttpURLConnectionmediaConn=(HttpURLConnection)mediaUrl.openConnection(); mediaConn.setDoOutput(true); mediaConn.setUseCaches(false); mediaConn.setRequestMethod(SystemConfig.GET_METHOD); mediaConn.setConnectTimeout(connTime==0?DEFAULT_CONNTIME:connTime); mediaConn.setReadTimeout(readTime==0?DEFAULT_UPLOAD_READTIME:readTime); IOUtils.write(("--"+boundary+"\r\n").getBytes(),output); IOUtils.write(("Content-Disposition:form-data;name=\"media\";filename=\""+getFileName(mediaPath) +"\"\r\n").getBytes(),output); IOUtils.write("Content-Type:video/mp4\r\n\r\n".getBytes(),output); inputStream=newBufferedInputStream(mediaConn.getInputStream()); IOUtils.copy(inputStream,output); //结尾部分 IOUtils.write(("--"+boundary+"\r\n").getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write("Content-Disposition:form-data;name=\"description\";\r\n\r\n" .getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write(("{\"title\":\""+title+"\",\"introduction\":\""+introduction+"\"}") .getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING),output); IOUtils.write(("\r\n--"+boundary+"--\r\n\r\n").getBytes(SystemConfig.DEFAULT_CHARACTER_ENCODING), output); mediaConn.disconnect(); //获取输入流 result=inputStreamToString(conn.getInputStream()); } }catch(MalformedURLExceptione){ e.printStackTrace(); }catch(ProtocolExceptione){ e.printStackTrace(); }catch(IOExceptione){ thrownewIOException("readdataerror"); }finally{ IOUtils.closeQuietly(output); IOUtils.closeQuietly(inputStream); } returnresult; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。