(8)java代码实现回复image类型的消息

本文介绍如何使用Java实现微信公众号被动回复图片消息的功能,包括获取access_token、上传图片获取MediaId及组装XML格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 按消息的来源,可以将消息分为两种,一种是用户过来的消息(即接受的普通消息),另一种是我的服务器返回给用户的消息(即被动回复消息)。
  • 用户发送的普通消息可以是:文本,图片,语音,视频,小视频,地址位置,连接,这7种类型。点击跳转官方文档说明
  • 被动回复消息只能是:文本,图片,语音,视频,音乐,图文,这6种类型。点击跳转官方文档说明

下面就重点讲解一下,如何依照官方文档编写被动回复消息的java代码,本文以image消息为例。

图片消息

    xml格式:
    <xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[fromUser]]></FromUserName>
    <CreateTime>12345678</CreateTime>#
    <MsgType><![CDATA[image]]></MsgType>
    <Image>
    <MediaId><![CDATA[media_id]]></MediaId>
    </Image>
    </xml>
    参数说明:

这里写图片描述

1 如何获取MediaId?
  1. 要想获得MediaId,就必须将多媒体文件上传到通过素材管理中的接口地址中。
  2. 在官方文档中,素材管理-新增临时素材查看详细说明,点我查看官方说明
    接口url:
    https://api.weixin.qq.com/cgibin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
  3. url地址参数说明
    这里写图片描述
  4. 所以,下面我们就需要获取参数access_token(type我们代码中手动写入,media文件上传的时候会指定)。
2 如何获取access_token?
  • 在官方文档中,开始开发-获取access_token,查看详细说明,点我查看官方说明
  • 公众号可以使用AppIDAppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。
  • 这里写图片描述
  • 这里写图片描述
3 如何用代码实现回复image消息?
  • 要构建image的xml格式(除了前4个基本元素外,还有个image元素,它内部又包含一个MediaId元素,所以就需要给MediaId传值),就要先获得MediaId,要想获得MediaId,又必须先获得access_token。
  • 所以基本思路:
    第一步 获取access_token
    第一步 获取MediaId
    第三步 拼装image的xml格式

    
3.1 获取access_token

  • 导入7个jar包
<!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib -->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>
<!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
    <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        <version>3.2.1</version>
    </dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.5</version>
    </dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
    </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.6</version>
</dependency>
  • 定义AccessToken对象
public class AccessToken{
        private String access_token;
        private int expires_in;
        public String getAccess_token() {
            return access_token;
        }
        public void setAccess_token(String access_token) {
            this.access_token = access_token;
        }
        public int getExpires_in() {
            return expires_in;
}
        public void setExpires_in(int expires_in) {
            this.expires_in = expires_in;
        }
}
  • 定义常量传入需要的值
public final static String APPID="wxb66105e88b4179b6";
    public final static String APPSECRET="e1e872b97cf1591adfa56813f2a87559";
    public final static String AccessTokenUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
  • 定义getAccessToken方法
public static AccessToken getAccessToken(){
        AccessToken token = new AccessToken();
        String url = AccessTokenUrl.replace("APPID", APPID).replaceAll("APPSECRET", APPSECRET);//替换到接口地址中的APPID和APPSECRET
        JSONObject jsonObject = doGet(url);//调用doGet方法发送get请求到url
        System.out.println("微信服务器返回的accessToken数据:"+jsonObject);
        if (jsonObject!=null) {
            token.setAccess_token(jsonObject.getString("access_token"));
            token.setExpires_in(jsonObject.getInt("expires_in"));
        }
        return token;
}   
  • 定义doGet方法
public static JSONObject doGet(String url){
        JSONObject jsonObject = null;
        CloseableHttpClient httpClient  = HttpClients.createDefault();//替代DefaultHttpClient
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            if (entity!=null) {
                String result = EntityUtils.toString(entity);
                jsonObject=JSONObject.fromObject(result);
            }
        } 
        catch (ClientProtocolException e) {
            e.printStackTrace();
        } 
        catch (IOException e) {
            e.printStackTrace();
        }
        return jsonObject;
}
  • 测试
@Test
    public void test1() throws Exception{
        AccessToken token = weiXinUtil.getAccessToken();
        System.out.println("票据:"+token.getAccess_token());
        System.out.println("accessToken有效时间:"+token.getExpires_in());
}
    • 正确输出
微信服务器返回的accessToken数据:{"access_token":"NrnXLx8Q5WWYHKgnswgf_EnM4FulqKj0O59jotaJWZ-6MTFXasE-qwqY_EeHmC1xfY5zzN9waAoNJe0Y6Lz6T31wKThQAk-onBk5NUq1xAVvwewcAisUGwKyQ9JqPM5GSVSfACALOL","expires_in":7200}

这里写图片描述

    • 如果console输出:
微信服务器返回的accessToken数据:{"errcode":40164,"errmsg":"invalid ip 60.12.8.170, not in whitelist hint: 

这里写图片描述

添加本机IP(60.12.8.170)到白名单,如下图

这里写图片描述

    • 如果console输出:
微信服务器返回的accessToken数据:{"errcode":40125,"errmsg":"invalid appsecret, view more at http://t.cn/RAEkdVq hint: [e89qca0917nfo1]"}
说明:工具类weixinUtil中的常量public final static String APPSECRET=””与基本配置中的AppSecret不一致

    
3.2 获取MediaId

微信服务器返回的json数据包:{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}

这里写图片描述

  • 素材上传接口地址
public final static String UploadUrl=
"https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
  • 文件上传工具类upload
public static String upload(String filePath,String accessToken,String type) throws IOException{
        File file = new File(filePath);
        if (!file.isFile() || !file.exists()) {
            throw new IOException("文件不存在");
        }
        String url = UploadUrl.replace("ACCESS_TOKEN", accessToken).replaceAll("TYPE", type);
        URL urlObj = new URL(url);

        HttpURLConnection connection = (HttpURLConnection)urlObj.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);

        //设置请求头
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Charset", "utf-8");

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

        StringBuilder sb = new StringBuilder();
        sb.append("--");
        sb.append(BOUNDARY);
        sb.append("\r\n");
        sb.append("Content-Disposition;form-data;name=\"flie\";filename=\""+file.getName()+"\"\r\n");
        sb.append("Content-Type:application/octet-stream\r\n\r\n"); 
        byte[] head = sb.toString().getBytes("utf-8");

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

        //文件正文部分,把文件以流的方式push到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 = ("\r\n--"+BOUNDARY+"--\r\n").getBytes("utf-8");
        out.write(foot);
        out.close();

        StringBuffer buffer = new StringBuffer();
        BufferedReader reader = null;
        String result = null;
        try {
            //读取url响应结果
            reader=new BufferedReader(new InputStreamReader(connection.getInputStream() ));
            String line = null;
            while((line = reader.readLine())!=null){
                buffer.append(line);
            }
            if (result==null) {
                result=buffer.toString();
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            if (reader!=null) {
                reader.close();
            }
        }
        JSONObject jsonObject = JSONObject.fromObject(result);
        System.out.println(jsonObject);
        String mediaId = jsonObject.getString("media_id");
        return mediaId;
}
  • 测试
@Test
public void test2() throws Exception{
    AccessToken token = weiXinUtil.getAccessToken();
    String path = "D:/3.jpg";
    String mediaId = weiXinUtil.upload(path, token.getAccess_token(), "image");
    System.out.println("微信服务器返回的mediaId:"+mediaId);
}
微信服务器返回的mediaId:
hcBIDu0UhtNpm3oixqLgpJ8HjbaAgLBbfFq6oJ8aoQW3mDWX90aVpoC4pEiONNw2 

这里写图片描述

    
3.3 拼装image的xml格式

  • 创建Image实体对象
  public class Image {
    private String MediaId;
    public String getMediaId() {
        return MediaId;
    }
    public void setMediaId(String mediaId) {
        MediaId = mediaId;
    }   
}
  • 创建imageMessage实体对象
public class baseMessage {
    private String ToUserName;
    private String FromUserName;
    private long CreateTime;
    private String MsgType;
    public String getToUserName() {
        return ToUserName;
    }
    public void setToUserName(String toUserName) {
        ToUserName = toUserName;
    }
    public String getFromUserName() {
        return FromUserName;
    }
    public void setFromUserName(String fromUserName) {
        FromUserName = fromUserName;
    }
    public long getCreateTime() {
        return CreateTime;
    }
    public void setCreateTime(long createTime) {
        CreateTime = createTime;
    }
    public String getMsgType() {
        return MsgType;
    }
    public void setMsgType(String msgType) {
        MsgType = msgType;
    }

}
public class imageMessage extends baseMessage{
    private Image Image;
    public Image getImage() {
        return Image;
    }
    public void setImage(Image image) {
        Image = image;
    }
}
  • 创建sendImageMessage方法
public final static String userResp_message_type_image = "image";//常量
public static String sendImageMessage(String toUserName,String fromUserName) throws Exception{
        Image img = new Image();
        String mediaId ="p483hrUP4Zf19H7XRWLKaT-Vt3FTArsj7dQPrWAy_lLbEgGc6DTrLvQT3_iqJ8j3";//复制成功上传文件后返回的media_id
        img.setMediaId(mediaId);//上传多媒体文件到素材管理的接口中,微信服务器会返回mediaId

        imageMessage image = new imageMessage();
        image.setFromUserName(toUserName);
        image.setToUserName(fromUserName);
        image.setCreateTime(new Date().getTime());
        image.setMsgType(messageUtil.userResp_message_type_image);
        image.setImage(img);

        String reponseMessage = messageUtil.imageMessageToXml(image);//利用写好的工具类将text类型消息拼装成微信服务器接受的xml格式
        System.out.println("imgReponseMessage=\n"+reponseMessage);
        return reponseMessage;
    }
  • handleRequestUtil的reponseInfo方法处理用户请求(用户发送B,服务器就回复一张图片)
if ("B".equals(map.get("Content").toUpperCase())) {
        reponseMessage = messageUtil.sendImageMessage(toUserName, fromUserName);
    }
  • Sevlet执行doPost请求
@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String responseMessage = handleRequestUtil.reponseInfo(request);
//工具类 handleRequestUtil的reponseInfo方法处理用户请求
        PrintWriter out = response.getWriter(); 
        out.print(responseMessage);
        out.close();
    }
  • 测试
    这里写图片描述
到此为止,被动回复image类型的消息就此结束了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值