java公众号开发-上传微信素材-图片到微信服务器

为什么写这篇博客?

领导要求公众号自动回复需要支持图片(之前的版本只支持文本和图文),而支持图片就需要先把图片上传到微信素材库,于是我就开始读文档,查资料,发现还真不好找。尤其是步骤2中上传的参数问题——我试着把前端的MultipartFile转为InputStream再转InputStreamBody,但是失败了。如果直接转File再转FileBody的话,可以上传,但是就比较复杂,微信必须先把MultipartFile保存为本地的File,然后再把这个File读取出来,这就有点恶心了。于是我又找到了一种两全的办法MultipartFile转InputStream再转byte[],这样就方便了很多。话说多了......直接上源码----》》》

1.Controller层(从前端接收要上传的文件)

 

package com.wxpub.controller.enterprise;




import com.youliantong.wxpub.config.Resources;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;

/**
 * @Description 图片上传controller
 * @Author BigBird
 * @Date 2018/11/27 19:15
 **/

@RestController("fileController")
@RequestMapping("/enterprise")
@Slf4j

public class FileController {

    // 上传微信永久素材的url
    private static final String UPLOAD_FOREVER_MEDIA_URL = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE";


    private static final long MAX_SIZE = 1024 * 1024 * 2;

    private static final String SUPPORTED_FORMAT = "bmp,png,jpeg,jpg,gif";




    /**
     * 上传素材到微信素材库
     * @param file
     */
    @RequestMapping(value = "uploadMediaToWechat", method = RequestMethod.POST)
    @ResponseBody
    public  String uploadMediaToWechat(@RequestParam("media") @ApiParam(name = "media", value = "待上传素材图片文件", required = true) MultipartFile file) throws Exception{

        String[] split = file.getOriginalFilename().split("\\.");
        String suffixName = split[split.length-1];
        boolean validPic = this.isValidPic(file.getSize(), suffixName);

        if (!validPic) {
            return "上传失败";
        }


        // 获取access_token,如果你不会获取,那么这篇博客不适合你。       
        // 这步在你的IDE上会提示报错,请修改为你自己获取access_token的方式
        String token = TokenUtil.getToken(account);
        String replacedUrl = UPLOAD_FOREVER_MEDIA_URL
                    .replace("ACCESS_TOKEN", token)
                    .replace("TYPE", "image");
        JSONObject jsonObject = CommonUtil.uploadFile(replacedUrl,  
                       file.getResource().getInputStream(),file.getOriginalFilename());

        log.info("微信素材上传结果:[{}]", jsonObject.toString());
        if (jsonObject != null && jsonObject.containsKey("media_id")) {
              
                return jsonObject.getString("media_id") ;
            }
 
        return "素材图片上传失败";
    }


    /**
     * 图片是否符合微信规范
     * @param size
     * @param suffixName
     * @return
     */
    public Boolean isValidPic(long size, String suffixName) {

        if (size > MAX_SIZE) {
            log.info("文件太大,文件的大小最大为2M,请重新上传!");
            return false;
        }

        if (!Arrays.asList(SUPPORTED_FORMAT.split(",")).contains(suffixName)) {
            log.info("图片格式不支持,请选择bmp/png/jpeg/jpg/gif的任意一种!");
            return false;
        }
        return true;

    }



}

2.把文件上传到微信服务器

package com.wxpub.util;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;

/**
 * http通用工具类
 *
 */
public class CommonUtil {



    private static Logger log = LoggerFactory.getLogger(CommonUtil.class);


    /**
     * 把文件上传到指定url上去
     * @param url 上传地址
     * @param file 待上传文件
     */
    public static JSONObject uploadFile(String url, InputStream file,String fileName) throws IOException{
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost(url);

            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(200000).setSocketTimeout(200000).build();
            httppost.setConfig(requestConfig);

            /**
             * 这一步最关键:
       *调用addBinaryBody("media",input2byte(file),ContentType.DEFAULT_BINARY, fileName),
             * fileName可以为任意值,但不能为null,如果为null则上传失败。
             * input2byte(file):把inputstream转为byte[],
             * 如果直接调用addPart用FileBody做参数,则MultifilePart不好转换;
             * 如果直接调用addPart用InpustreamBody做参数,则因为没有fileName会造成上传失败
             */
            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addBinaryBody("media", input2byte(file), ContentType.DEFAULT_BINARY, 
                                    fileName).build();

            httppost.setEntity(reqEntity);
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    String responseEntityStr = EntityUtils.toString(response.getEntity());
                    log.info("responseEntityStr=[{}]",responseEntityStr);
                    return  JSONObject.fromObject(responseEntityStr);
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }


    private static final byte[] input2byte(InputStream inStream)
            throws IOException {
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while ((rc = inStream.read(buff, 0, 100)) > 0) {
            swapStream.write(buff, 0, rc);
        }
        byte[] in2b = swapStream.toByteArray();
        return in2b;
    }


}

 

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值