博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java企业微信开发_08_素材管理之下载微信临时素材到本地服务器
阅读量:5914 次
发布时间:2019-06-19

本文共 21212 字,大约阅读时间需要 70 分钟。

一、本节要点

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/工程名。若不是这个路径就请参考:

 

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
getWxConfig(HttpServletRequest request) { Map
ret = new HashMap
(); //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
* 详述:字符串加密辅助方法
* 开发人员:souvc
* 创建时间:2016-1-5
* @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

 

转载地址:http://lqmpx.baihongyu.com/

你可能感兴趣的文章
Computer Vision 杂志对何恺明 Rethinking ImageNet Pre-training 的最新评论
查看>>
学web前端从哪里开始学起呢-好程序员
查看>>
5G网络数据中心系统需要什么光模块?
查看>>
kinmall分析区块链在去中心化和中心化要思考的问题
查看>>
Eclipse修改log缓冲大小
查看>>
C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件
查看>>
RESTful与网络请求过程
查看>>
.NET Core实战项目之CMS 第五章 入门篇-Dapper的快速入门看这篇就够了
查看>>
vue插槽slot
查看>>
日历类报表可以这样实现
查看>>
CirruScript 写的: 函数式编程另类指南
查看>>
Java 获取文件的上级目录
查看>>
Confluence 6 CSS 编辑快速入门
查看>>
我要做 Android 之消息机制
查看>>
极简的高性能框架 one 1.4.6 发布,新增参数验证器
查看>>
推荐两个漂亮的编程字体
查看>>
Linux系统诊断小技巧(14):启停问题之如何修复initrd损坏
查看>>
Python数据科学分析速查表
查看>>
jmeter测试教程
查看>>
Trie 树内存消耗问题
查看>>