zoukankan      html  css  js  c++  java
  • 慕课网-图片消息的自动回复

    微信公众号开发者文档里面发送消息-被动回复消息,右边可以点击回复图片消息。

    如果是第一次开发微信公众号的小伙伴第一次看到这么短一段说明文字的时候可能一下子就懵逼了,因为根本就不知道如何去获取这个MediaId。这也是微信公众号开发文档的一个比较坑爹的地方,因为单纯看这一页根本就不知道如何去获取这个参数,而且开发文档有些地方

    的参数还是有错误的。

         这个时候就需要点击素材管理-新增临时素材那里去看一下相关接口的地址和调用方法。

         

         如果对文件的上传和下载不是很熟的朋友,可以参考慕课网中的文件上传和下载的课程

     这个课程里面有讲文件上传需要设置的一些什么像头文件啊分界符啊

    运行测试类WeixinTest.java之后控制台打印出错误信息

    得知此错误之后返回去看微信公众号开发文档里面的接口返回码说明,看一看全局返回码说明

    找到48001错误。原来是

     

    因为我这个微信公众号是个人订阅号,所以没有获得该接口的权限。

    然后就需要使用我们之前讲过的测试号了,需要把测试号的开发者ID和开发者密钥替换掉程序中的个人订阅号的微信开发者ID和开发者密钥

    假如说你手上有一套微信公众号的代码,你只需要替换掉appid和appsecret以及tocken。这三个地方代码里面和后台配置只要一致的话就可以了。

    再次运行测试类WeixinTest.java,可以得到返回结果media_id

    顺便把JS接口安全域名也给修改了,填上百度云服务器上面本应用的域名

     提交代码之后报错

    估计是token票据失效了,重新获取token票据和MediaId

    还是报错。。。

    票据可以有效两个小时,媒体文件可以在微信后台保存3天,即3天后MediaId失效。如果这样都还是报报错,那应该是最复杂的上传本地媒体文件到微信后台服务器的代码有错误,图片根本就没有发送到微信后台那里去。

    发现了这一个代码有错,把请求头信息Keep-Aive改成Keep-Alive之后还是报错

    原来是回复图片消息要先关注自己申请的接口测试号公众号之后在测试号进行测试才可以,如果使用自己的个人订阅号是不可以提供服务的

    哈哈,这个就是微信开发文档中比较坑爹的一个地方。哈哈哈啊哈啊哈哈哈。。。

     下面贴一下主要的代码吧:

    WeixinUtil.java的媒体文件上传代码

    //下面写一个文件上传的代码
    public static String upload(String filePath,String accessToken,String type) throws IOException{
    //这里需要传递三个参数:文件所在的路径,票据,文件的类型
    //首先进来需要对文件路径进行判断,是否存在
    File file = new File(filePath);
    if(!file.exists()||!file.isFile()){
    throw new IOException("文件不存在");
    }
    String url = UPLOAD_URL.replace("ACCESS_TOKEN",accessToken).replace("TYPE",type);//然后需要对接口地址的两个参数access_tocken和type进行赋值
    URL urlObj = new URL(url);
    //连接
    HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
    //首先是以POST方式进行提交
    con.setRequestMethod("POST");
    con.setDoInput(true);//进行输入输出
    con.setDoOutput(true);
    con.setUseCaches(false);//如果是POST方式要设置忽略它的缓存

    //设置请求头信息
    con.setRequestProperty("Connection", "Keep-Alive");
    con.setRequestProperty("Charset", "UTF-8");

    //设置边界
    String BOUNDARY = "-------"+System.currentTimeMillis();
    con.setRequestProperty("Content-Type","multipart/form-data;boundary="+BOUNDARY);

    StringBuilder sb = new StringBuilder();
    sb.append("--");
    sb.append(BOUNDARY);
    sb.append(" ");
    sb.append("Content-Dispoistion:form-data;name="file";filename=""+file.getName()+"" ");
    sb.append("Content-Type:application/octet-stream ");

    byte[] head = sb.toString().getBytes("utf-8");
    //然后通过输出流的方式进行输出

    //获取输出流
    OutputStream out = new DataOutputStream(con.getOutputStream());

    //输出表头
    out.write(head);

    //文件正文部分
    //把文件以流文件的方式 推入到url中
    DataInputStream in = new DataInputStream(new FileInputStream(file));
    int bytes = 0;
    byte[] bufferOut = new byte[1024];
    while((bytes = in.read(bufferOut))!=-1){
    out.write(bufferOut, 0, bytes);
    }
    in.close();

    //结尾部分
    byte[] foot = (" --"+ BOUNDARY +"-- ").getBytes("utf-8");//定义最后数据分隔线

    out.write(foot);

    out.flush();
    out.close();

    StringBuffer buffer = new StringBuffer();
    BufferedReader reader = null;
    String result = null;

    //定义BufferedReader输入流来读取URL的响应
    //请求成功以后我们要在输入流里面去拿它的响应结果
    reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
    String line = null;
    try{
    while((line = reader.readLine())!=null){
    buffer.append(line);
    }
    if(result == null){
    result = buffer.toString();

    }
    }catch(IOException e){
    e.printStackTrace();
    }finally{
    if(reader!=null){
    reader.close();
    }
    }
    JSONObject jsonObj = JSONObject.fromObject(result);//把结果转成JSON格式
    System.out.println(jsonObj);
    String mediaId = jsonObj.getString("media_id");
    return mediaId;


    }

    WeixinTest.java  测试代码

    package com.imooc.test;

    import java.io.IOException;

    import com.imooc.po.AccessTocken;
    import com.imooc.util.WeixinUtil;

    public class WeixinTest {
    public static void main(String[] args) {
    AccessTocken token = WeixinUtil.getAccessTocken();
    System.out.println("票据:"+token.getToken());
    System.out.println("有效时间:"+token.getExpiresIn());

    String path = "D:/imooc.jpg";
    try {
    String mediaId = WeixinUtil.upload(path,token.getToken(),"image");
    System.out.println(mediaId);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }

    Image.java

    package com.imooc.po;

    public class Image {
    private String MediaId;//和发送消息-被动回复消息-回复图片消息的返回的一段XML代码里面的一个字段MediaId一样

    public String getMediaId() {
    return MediaId;
    }

    public void setMediaId(String mediaId) {
    MediaId = mediaId;
    }

    }

    ImageMessage.java

    package com.imooc.po;

    public class ImageMessage extends BaseMessage{
    //private Image image;//这里的大小写是很重要的 否则后面将javabean转为XML的时候无法识别
    private Image Image;
    public Image getImage() {
    return Image;
    }

    public void setImage(Image image) {
    //this.Image = image;
    Image = image;
    }
    }

    Messageutil.java的组装图片消息

    /**
    *
    * 图片消息的组装
    * @param toUserName
    * @param fromUserName
    * @return
    */
    public static String initImageMessage(String toUserName,String fromUserName){//接收方和发送方
    String message = null;
    Image image = new Image();
    //image.setMediaId("idKpa1NXpmkbUpntpH8nMwPj3cTTiH02-B_ZE57LOt9fWOPVKvrxp5BKokk8wUNi");
    image.setMediaId("aycSC7SSzXpVnz45Li_Qg1nUl4pHZpyNeHKVg70Ih7z9RmvUBA4yyT72FjFjOiu_");//再次上传图片,其实是重新获取票据,重新获取MediaId
    ImageMessage imageMessage = new ImageMessage();
    imageMessage.setFromUserName(toUserName);
    imageMessage.setToUserName(fromUserName);
    imageMessage.setMsgType(MESSAGE_IMAGE);//使用常量而不是字符串,这样可维护性比较强 消息的类型是图片
    imageMessage.setCreateTime(new Date().getTime());//还是我们的当前时间
    imageMessage.setImage(image);
    message = imageMessageToXml(imageMessage);//将JavaBean转为XML
    return message;

    }

    以及

    /**
    * 图片消息转为XML
    * @param imageMessage
    * @return
    */
    public static String imageMessageToXml(ImageMessage imageMessage){
    XStream xstream = new XStream();
    xstream.alias("xml", imageMessage.getClass());
    return xstream.toXML(imageMessage);
    }

    最后就在Servlet写业务逻辑

  • 相关阅读:
    Apache Pig的前世今生
    openssl之EVP系列之6---EVP_Encrypt系列函数编程架构及样例
    P3388 【模板】割点(割顶)
    让priority_queue支持小根堆的几种方法
    2017.11.7解题报告
    一个例子教你如何与出题人斗智斗勇
    debug
    树上倍增求LCA及例题
    素数的筛法
    Catalan卡特兰数入门
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6282815.html
Copyright © 2011-2022 走看看