longdengpan
2015-04-18 09:56
采纳率: 50%
浏览 32.1k

微信公众号上传多媒体文件接口用JAVA怎么实现

图片说明

根据图片的描述是通过发送https请求上传图片。微信公众号提供的文档是通过curl命令来实现发送https post请求,但是我现在的程序是通过java程序来发送https post请求。以下是我的3个问题:

1、既然是发送https post请求上传图片,java应该也可以实现,我只实现过java https post的简单请求,没有实现过java https post图片上传。有大神能帮帮我吗?

2、既然微信公众号文档上说是通过curl来发送请求,那java是否提供模拟curl来发送https post请求来实现图片上传。如果java提供,有大神能帮帮我吗?

3、或者有没有谁实现过微信公众号以上截图描述的用java实现的多媒体文件上传功能,有实现过的话,共享以下代码啊!本人感激不尽!。
求大神帮帮忙!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • 毕小宝 2015-04-18 11:40
    已采纳

    这个类,刚忘了一个方法httpsRequestToString,补充如下:

     /**
         * 发送请求以https方式发送请求并将请求响应内容以String方式返回
         * @param path   请求路径
         * @param method 请求方法
         * @param body   请求数据体
         * @return 请求响应内容转换成字符串信息
         */
        public static String httpsRequestToString(String path, String method, String body) {
            if(path==null||method==null){
                return null;
            }
    
            String response = null;
            InputStream inputStream = null;
            InputStreamReader inputStreamReader = null;
            BufferedReader bufferedReader = null;
            HttpsURLConnection conn = null;
            try {
                TrustManager[] tm = { new JEEWeiXinX509TrustManager() };
                SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
                sslContext.init(null, tm, new java.security.SecureRandom());
                SSLSocketFactory ssf = sslContext.getSocketFactory();
                System.out.println(path);
                URL url = new URL(path);
                conn = (HttpsURLConnection) url.openConnection();
                conn.setSSLSocketFactory(ssf);
    
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setUseCaches(false);
                conn.setRequestMethod(method);
                if (null != body) {
                    OutputStream outputStream = conn.getOutputStream();
                    outputStream.write(body.getBytes("UTF-8"));
                    outputStream.close();
                }
    
                inputStream = conn.getInputStream();
                inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
                bufferedReader = new BufferedReader(inputStreamReader);
                String str = null;
                StringBuffer buffer = new StringBuffer();
                while ((str = bufferedReader.readLine()) != null) {
                    buffer.append(str);
                }
    
                response = buffer.toString();
            } catch (Exception e) {
                logger.error(e);
            }finally{
                if(conn!=null){
                    conn.disconnect();
                }
                try {
                    bufferedReader.close();
                    inputStreamReader.close();
                    inputStream.close();
                } catch (IOException execption) {
                    logger.error(execption);
                }
            }
            return response;
        }
    

    此外,还有一个证书实现类,发送https请求用的,也要定义的。

     class JEEWeiXinX509TrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
    
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
    
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
    
    点赞 评论
  • 毕小宝 2015-04-18 11:34

    可以的。这个接口岁说是https的,但是用http仍然能上传资源的。我以前开发公众号的时候文档还是http协议上传的。今天试了,还是可以的。
    我给你上传、下载的例子。你修改appId和appSecret测试上传下载图片文件看看。上传文件使用HttpClient类完成,需要net.sf.json和httpclient的jar。
    API实现类代码如下,你修改上传文件路径和开发者账户直接运行试试。祝好!

     public class WeChatApiUtil {
        // token 接口(GET)
        private static final String ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
        // 素材上传(POST)
        private static final String UPLOAD_MEDIA = "http://file.api.weixin.qq.com/cgi-bin/media/upload";
        // 素材下载:不支持视频文件的下载(GET)
        private static final String DOWNLOAD_MEDIA = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";
    
        public static String getTokenUrl(String appId, String appSecret) {
            return String.format(ACCESS_TOKEN, appId, appSecret);
        }
    
        public static String getDownloadUrl(String token, String mediaId) {
            return String.format(DOWNLOAD_MEDIA, token, mediaId);
        }
    
        /**
         * 通用接口获取Token凭证
         * @param appId
         * @param appSecret
         * @return
         */
        public static String getToken(String appId, String appSecret) {
            if(appId==null||appSecret==null){
                return null;
            }
    
            String token = null;
            String tockenUrl = WeChatApiUtil.getTokenUrl(appId, appSecret);
            String response = httpsRequestToString(tockenUrl, "GET", null);
            JSONObject jsonObject = JSONObject.fromObject(response);
            if (null != jsonObject) {
                try {
                    token =jsonObject.getString("access_token");
                } catch (JSONException e) {
                    token = null;// 获取token失败
                    logger.error(e);
                }
            }
            return token;
        }
    
        /**
         * 微信服务器素材上传
         * @param file  表单名称media
         * @param token access_token
         * @param type  type只支持四种类型素材(video/image/voice/thumb)
         */
        public static JSONObject uploadMedia(File file, String token, String type) {
            if(file==null||token==null||type==null){
                return null;
            }
    
            if(!file.exists()){
                logger.info("上传文件不存在,请检查!");
                return null;
            }
    
            String url = UPLOAD_MEDIA;
            JSONObject jsonObject = null;
            PostMethod post = new PostMethod(url);
            post.setRequestHeader("Connection", "Keep-Alive");
            post.setRequestHeader("Cache-Control", "no-cache");
            FilePart media = null;
            HttpClient httpClient = new HttpClient();
            //信任任何类型的证书
            Protocol myhttps = new Protocol("https", new MySSLProtocolSocketFactory(), 443); 
            Protocol.registerProtocol("https", myhttps);
    
            try {
                media = new FilePart("media", file);
                Part[] parts = new Part[] { new StringPart("access_token", token),
                        new StringPart("type", type), media };
                MultipartRequestEntity entity = new MultipartRequestEntity(parts,
                        post.getParams());
                post.setRequestEntity(entity);
                int status = httpClient.executeMethod(post);
                if (status == HttpStatus.SC_OK) {
                    String text = post.getResponseBodyAsString();
                    jsonObject = JSONObject.fromObject(text);
                } else {
                    logger.info("upload Media failure status is:" + status);
                }
            } catch (FileNotFoundException execption) {
                logger.error(execption);
            } catch (HttpException execption) {
                logger.error(execption);
            } catch (IOException execption) {
                logger.error(execption);
            }
            return jsonObject;
        }
    
        /**
         * 多媒体下载接口
         * @comment 不支持视频文件的下载
         * @param fileName  素材存储文件路径
         * @param token     认证token
         * @param mediaId   素材ID(对应上传后获取到的ID)
         * @return 素材文件
         */
        public static File downloadMedia(String fileName, String token,
                String mediaId) {
            String url = getDownloadUrl(token, mediaId);
            return httpRequestToFile(fileName, url, "GET", null);
        }
    
        /**
         * 以http方式发送请求,并将请求响应内容输出到文件
         * @param path    请求路径
         * @param method  请求方法
         * @param body    请求数据
         * @return 返回响应的存储到文件
         */
        public static File httpRequestToFile(String fileName,String path, String method, String body) {
            if(fileName==null||path==null||method==null){
                return null;
            }
    
            File file = null;
            HttpURLConnection conn = null;
            InputStream inputStream = null;
            FileOutputStream fileOut = null;
            try {
                URL url = new URL(path);
                conn = (HttpURLConnection) url.openConnection();
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setUseCaches(false);
                conn.setRequestMethod(method);
                if (null != body) {
                    OutputStream outputStream = conn.getOutputStream();
                    outputStream.write(body.getBytes("UTF-8"));
                    outputStream.close();
                }
    
                inputStream = conn.getInputStream();
                if(inputStream!=null){
                    file = new File(fileName);
                }else{
                    return file;
                }
    
                //写入到文件
                fileOut = new FileOutputStream(file);
                if(fileOut!=null){
                    int c = inputStream.read();
                    while(c!=-1){
                        fileOut.write(c);
                        c = inputStream.read();
                    }
                }
            } catch (Exception e) {
                logger.error(e);
            }finally{
                if(conn!=null){
                    conn.disconnect();
                }
    
                /*
                 * 必须关闭文件流
                 * 否则JDK运行时,文件被占用其他进程无法访问
                 */
                try {
                    inputStream.close();
                    fileOut.close();
                } catch (IOException execption) {
                    logger.error(execption);
                }
            }
            return file;
        }
    
        public static void main(String[] args) {
            File f = new File("D:/test.png");
            String appId = "";
            String appSecret = "";
            String token = WeChatApiUtil.getToken(appId, appSecret);
            JSONObject o = WeChatApiUtil.uploadMedia(f, token.getAccessToken(), "image");
            System.out.println(o.toString());
    
            //下载刚刚上传的图片以id命名
            String media_id = o.getString("media_id");
            File t = WeChatApiUtil.downloadMedia("D:/"+media_id+".png", token.getAccessToken(), media_id);
    
        }
    }
    
    
    点赞 评论
  • JimmyHen 2015-09-23 13:08

    楼主我也正在弄这个,能发一下你的代码吗?

    点赞 评论
  • ●杨毅 2016-05-13 02:21

    楼主求助 楼主求助 597392641 望加我, 大恩不言谢啊

    点赞 评论
  • qq_35128032 2016-05-26 08:19

    你好,我现在也在弄这个,求指教

    点赞 评论

相关推荐 更多相似问题