打赏
Fork me on GitHub

微信公众平台,监听用户输入及事件

微信公众平台,监听用户输入及事件

微信消息类

/**
 * 
 */
package com.xianquan.wx.model;

import java.io.Serializable;
import java.util.Date;

import com.thoughtworks.xstream.annotations.XStreamOmitField;

/** 
* @ClassName: Message 
* @Description: 微信收到的消息
* @author coil
* @date 2020年1月10日 下午4:13:20
*  
*/
@Data
public class WechatMessage implements Serializable{

    private static final long serialVersionUID = 1L;
    
    public static final String TEXT = "text";
    public static final String IMAGE = "image";
    public static final String LOCATION = "location";
    public static final String LINK = "link";
    public static final String EVENT = "event";
    
    @XStreamOmitField
    private Integer id;//数据库存储的id
    
    // 开发者微信号  
    private String toUserName;  
    // 发送方帐号(一个OpenID)  
    private String fromUserName;  
    // 消息创建时间    
    private Date createTime;  
    // 消息类型(text/image/location/link)  
    private String msgType;  
    // 消息id,64位整型  
    private String msgId;
    
    // 消息内容 (文本消息专有)
    private String content;
    
    //图片链接 (图片消息专有)
    private String picUrl;
    
    // 消息标题 (链接消息专有) 
    private String title;  
    // 消息描述 (链接消息专有) 
    private String description;  
    // 消息链接  (链接消息专有)
    private String url;
    
    
    //地理位置纬度 Location_X(地理位置专有)
    private String locationX;
    //地理位置经度 Location_Y(地理位置专有)
    private String locationY;
    // 地图缩放大小  (地理位置专有)
    private String scale;  
    // 地理位置信息  (地理位置专有)
    private String label;
    
    
    //事件类型,subscribe(订阅)、unsubscribe(取消订阅)、CLICK(自定义菜单点击事件) (事件推送专有)
    private String event;
    //事件KEY值,与自定义菜单接口中KEY值对应(事件推送专有)
    private String eventKey;
    //头像
    private String headImgUrl;
    //标记图片的ID
    private String mediaId;
    //用户名称
    private String userName;
    //用户昵称
    private String remark;

}
WechatMessage

 

天气查询工具类

package com.xianquan.wx.weixin.sdk.weather;


import com.xianquan.wx.weixin.sdk.propertie.WeixinGlobal;
import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

/** 
* @ClassName: PM25 
* @Description: TODO
* @author coil
* @date 2020年1月14日 下午6:24:29 
*  
*/
public class PM25 {
    
    /**获取pm2.5的返回字符串*/
    public static String getPM25Data(String city){
        String result = "";
        city = HanyuPinyinUtil.toHanyuPinyin(city);
        StringBuffer buf = new StringBuffer();
        buf.append("city=");
        buf.append(city);
        buf.append("&token=");
        buf.append(WeixinGlobal.PM25_TOKEN);
        buf.append("&stations=no");
        String param = buf.toString();
        String urlName = WeixinGlobal.PM25_API + param;
        URL realUrl;
        try {
            realUrl = new URL(urlName);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            conn.setDoInput(true);
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    conn.getInputStream(),"UTF-8"));

            String line = br.readLine();
            while (line != null) {
                result += line;
                line = br.readLine();
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    
    /**解析返回数据类型*/
    public static Object analysisPMData(String strPM){
        Gson gson = new Gson();
        if(strPM.contains("error")){
            PM25Error error = gson.fromJson(strPM, PM25Error.class);
            return error;
        }else{
            strPM = strPM.replace("[", "").replace("]", "");
            PM25Result pm25Result = gson.fromJson(strPM,PM25Result.class);
            return pm25Result;
        }
    }
    
}
weather

监听用户对微信服务号的操作

  1 package com.xianquan.wx.web.controller;
  2 
  3 import com.xianquan.wx.model.*;
  4 import com.xianquan.wx.weixin.sdk.message.Image;
  5 import com.xianquan.wx.weixin.sdk.message.ImageMessage;
  6 import com.xianquan.wx.weixin.sdk.model.reply.TextMessage;
  7 import com.xianquan.wx.weixin.sdk.propertie.WeixinGlobal;
  8 import com.xianquan.wx.weixin.sdk.util.AccessTokenUtil;
  9 import com.xianquan.wx.weixin.sdk.util.MessageUtil;
 10 import com.xianquan.wx.weixin.sdk.util.WeixinUtil;
 11 import com.xianquan.wx.weixin.sdk.weather.*;
 12 import org.springframework.beans.factory.annotation.Autowired;
 13 import org.springframework.stereotype.Controller;
 14 import org.springframework.web.bind.annotation.RequestMapping;
 15 import org.springframework.web.bind.annotation.RequestMethod;
 16 import org.springframework.web.bind.annotation.ResponseBody;
 17 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 18 
 19 import javax.annotation.Resource;
 20 import javax.servlet.http.HttpServletRequest;
 21 import java.util.Date;
 22 import java.util.List;
 23 import java.util.Map;
 24 
 25 
 26 @Controller()
 27 public class WeixinController {
 28     
 29     public static int pagesize = 10;
 30     
 31 
 32     //接收微信公众号接收的消息,处理后再做相应的回复
 33     @RequestMapping(value="/weixin",method=RequestMethod.POST,produces="text/html;charset=UTF-8")
 34     @ResponseBody
 35     public String replyMessage(HttpServletRequest request, RedirectAttributes attr){
 36         //仅处理微信服务端发的请求
 37         if (checkWeixinReques(request)) {
 38             Date date = new Date();
 39             Map<String, String> requestMap = WeixinUtil.parseXml(request);
 40             Message message = WeixinUtil.mapToMessage(requestMap);
 41             WechatMessage wechatMessage = WeixinUtil.mapToWechatMessage(requestMap);
 42             wechatMessage.setCreateTime(date);
 43             String type = message.getMsgType();
 44             String openId = message.getFromUserName();
 45             String msg = "";
 46             WechatUser user = null;
 47             String msgType = requestMap.get("MsgType");
 48             if(type != WechatMessage.EVENT){
 49                 /**
 50                  * 保存接受消息到数据库
 51                  */
 52             }
 53             if(type.equals(WechatMessage.EVENT)){
 54                 String eventType = requestMap.get("Event");
 55                 String accessToken = AccessTokenUtil.queryAccessToken();
 56                 if(wechatMessage.getEvent().equals("unsubscribe")){//取消关注公众号事件监听
 57                     /**
 58                      *
 59                      */
 60                 }
 61                 if(wechatMessage.getEvent().equals("subscribe")){//关注公众号事件监听
 62                     /**
 63                      * 
 64                      */
 65                 }
 66                 // 自定义菜单点击事件
 67                 else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
 68                     WechatUser wechatUser = wechatUserService.getByOpenId(openId);
 69                     String remark = wechatUser.getRemark();
 70                     String studentName = wechatUser.getStudentName();
 71                     Integer studentId = wechatUser.getStudentId();
 72                     // 事件KEY值,与创建自定义菜单时指定的KEY值对应
 73                     TextMessage textMessage = new TextMessage();
 74                     textMessage.setMsgType(Message.TEXT);
 75                     textMessage.setCreateTime(date.getTime());
 76                     textMessage.setFromUserName(message.getToUserName());
 77                     textMessage.setToUserName(message.getFromUserName());
 78                     String eventKey = requestMap.get("EventKey");
 79                     String respContent = "请求处理异常,请稍候尝试!";
 80                     if (eventKey.equals("11")) {
 81                         
 82                     }else if (eventKey.equals("14")) {
 83                         respContent = "14菜单项被点击,功能开发中!";
 84                     } else if (eventKey.equals("21")) {
 85                         respContent = "21菜单项被点击,功能开发中!";
 86                     } else if (eventKey.equals("32")) {
 87                         respContent = "32菜单项被点击!";
 88                     } else if (eventKey.equals("33")) {
 89                         respContent = "33菜单项被点击!";
 90                     }
 91                     textMessage.setContent("您好,"+user.getName()+"\n我的微信平台通知您:"+ respContent
 92                             );
 93                     msg = MessageUtil.textMessageToXml(textMessage);
 94                     return msg;
 95                 }
 96             }
 97             if (type.equals(Message.TEXT)) {//仅处理文本回复内容
 98                 String content = message.getContent();//消息内容
 99                 TextMessage textMessage = new TextMessage();
100                 textMessage.setFromUserName(message.getToUserName());
101                 textMessage.setToUserName(message.getFromUserName());
102                 textMessage.setMsgType(Message.TEXT);
103                 textMessage.setCreateTime(date.getTime());
104                 if(validateWechatContent(content)){
105                     String unbundling = null;
106                     String idCard = content.split("\\+")[0];
107                     String remark = content.split("\\+")[1];
108                     if( content.split("\\+").length == 3){
109                         unbundling = content.split("\\+")[2];
110                     }
111                 }else if(content.endsWith("天气")){
112                     String keyWord = content.replaceAll("天气", "").trim();
113                     String weather = BaiduWeather.getSend(keyWord);
114                     textMessage.setContent("您好,"+user.getName()+"\n我的微信平台通知您:\n【"+keyWord+"】"+weather);
115                 }else if(content.endsWith("空气质量")){
116                     String city = content.replaceAll("空气质量", "").trim();
117                     String strPM = PM25.getPM25Data(city);
118                     Object param = PM25.analysisPMData(strPM);
119                     if(param instanceof PM25Result){
120                         textMessage.setContent("您好,"+user.getName()+"\n我的微信平台通知您:\n"+((PM25Result) param).getArea()+
121                                 "今日空气质量指数(AQI):"+((PM25Result) param).getAqi()+
122                                 "\n空气质量指数类别:"+((PM25Result) param).getQuality()+
123                                 "\n首要污染物:"+((PM25Result) param).getPrimary_pollutant()+
124                                 "\npm2_5:"+((PM25Result) param).getPm2_5()+
125                                 "\npm2_5_24h:"+((PM25Result) param).getPm2_5_24h());
126                     }else if(param instanceof PM25Error){
127                         textMessage.setContent("您好,"+user.getName()+"\n我的微信平台通知您:\n"+((PM25Error) param).getError());
128                     }
129                     
130                 }else{
131                     textMessage.setContent("您好,"+user.getName()+"\n我的微信平台通知您:\n不能识别您发出的指令!");
132                     
133                 }
134                 msg = MessageUtil.textMessageToXml(textMessage);
135                 return msg;
136             }else if(type.equals(Message.IMAGE)){
137                 ImageMessage imageMessage = new ImageMessage();
138                 imageMessage.setToUserName(message.getFromUserName());
139                 imageMessage.setFromUserName(message.getToUserName());
140                 imageMessage.setCreateTime(date.getTime());
141                 imageMessage.setMsgType(Message.IMAGE);
142                 Image image = new Image();
143                 image.setMediaId(message.getMediaId());
144                 imageMessage.setImage(image);
145                 msg = MessageUtil.imageMessageToXml(imageMessage);
146                 return msg;
147             }else if(type.equals(Message.LOCATION)){
148                 TextMessage textMessage = new TextMessage();
149                 textMessage.setFromUserName(message.getToUserName());
150                 textMessage.setToUserName(message.getFromUserName());
151                 textMessage.setMsgType(Message.TEXT);
152                 textMessage.setCreateTime(date.getTime());
153                 textMessage.setContent("您好,"+user.getName()+"\n我的微信平台通知您:\n您发送的是位置,\n纬度为:"+message.getLocationX()+
154                         ";\n经度为:"+message.getLocationY()+";\n位置为:"+message.getLabel()+".");
155                 msg = MessageUtil.textMessageToXml(textMessage);
156                 return msg;
157             }
158             
159         }
160         return Reply.WELCOME_CONTENT;
161     }
162     
163     
164     //微信公众平台验证url是否有效使用的接口
165     @RequestMapping(value="/weixin",method=RequestMethod.GET,produces="text/html;charset=UTF-8")
166     @ResponseBody
167     public String initWeixinURL(HttpServletRequest request){
168         String echostr = request.getParameter("echostr");
169         if (checkWeixinReques(request) && echostr != null) {
170             System.out.println(echostr);
171             return echostr;
172         }else{
173             return "error";
174         }
175     }
176 
177 
178     /**
179      * 根据token计算signature验证是否为weixin服务端发送的消息
180      */
181     private static boolean checkWeixinReques(HttpServletRequest request){
182         String signature = request.getParameter("signature");
183         String timestamp = request.getParameter("timestamp");
184         String nonce = request.getParameter("nonce");
185         if (signature != null && timestamp != null && nonce != null ) {
186             String[] strSet = new String[] { WeixinGlobal.TOKEN, timestamp, nonce };
187             java.util.Arrays.sort(strSet);
188             String key = "";
189             for (String string : strSet) {
190                 key = key + string;
191             }
192             String pwd = WeixinUtil.sha1(key);
193             return pwd.equals(signature);
194         }else {
195             return false;
196         }
197     }
198     
199     /**
200     * @Title: validateWechatContent 
201     * @Description: 验证用户通过微信发送来的文本消息是否匹配格式
202     * @param content
203     * @return
204      */
205     private boolean validateWechatContent(String content){
206         if(content.contains("+") && content.split("\\+").length == 2 ||content.split("\\+").length == 3){
207             String str[] = content.split("\\+");
208             if(IdCardUtil.is18ByteIdCardComplex(str[0])){
209                 return true;
210             }
211             return false;
212         }
213         return false;
214     }
215 }
WeixinController

 

posted @ 2020-04-26 22:33  l-coil  阅读(710)  评论(0编辑  收藏  举报