天天看点

微信公众号(服务号)开发,配置URL响应微信发送的Token验证,接收公众号发送的消息,被动回复消息

话不多说,上菜

微信请求接口Controller控制层

/**
 * 微信客服公众号controller控制层
 */
@Controller
public class KeFuController {
    private final static Logger log = LoggerFactory.getLogger(KeFuController.class);

	//配置url请求回调接口
    @RequestMapping(value = "xxxxCheck" ,method = RequestMethod.GET)
    public void checkWeXin(HttpServletRequest request, HttpServletResponse response){
        log.info("-------------------------微信接口校验--------");
        PrintWriter out=null;
        try {
            //设置编码,不然接收到的消息乱码
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            String signature = request.getParameter("signature");//微信加密签名
            String timestamp = request.getParameter("timestamp");//时间戳
            String nonce = request.getParameter("nonce");//随机数
            String echostr = request.getParameter("echostr");//随机字符串
            out = response.getWriter();
            if(CheckUtil.checkSignature(signature,timestamp,nonce)){
                out.print(echostr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            out.close();
        }

    }
    //公众号消息接收接口(与服务器回调url保持一致)
 @RequestMapping(value = "xxxxCheck" ,method = RequestMethod.POST)
    public void getMessage(HttpServletRequest request ,HttpServletResponse response){
        log.info("`---------------------------微信公众号消息接收--------------------");
        try {
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Map<String,String> map = MessageUtil.xmlToMap(request);
        String toUserName = map.get("ToUserName");
        String fromUserName = map.get("FromUserName");
        String createTime = map.get("CreateTime");
        String msgType = map.get("MsgType");
        String content = map.get("Content");
        String msgId = map.get("MsgId");

        String message=null;
        if(MessageUtil.MESSAGE_TEXT.equals(msgType)){
            if("1".equals(content)){
                message = MessageUtil.initText(toUserName,fromUserName,MessageUtil.firstMenu());

            }else if("2".equals(content)){
                // message = MessageUtil.initText(toUserName,fromUserName,MessageUtil.secondMenu());
                message = MessageUtil.initNewsMessage(toUserName,fromUserName);

            }else if("3".equals(content)){
                message = MessageUtil.initText(toUserName,fromUserName,MessageUtil.thirdMenu());

            }else if("666".equals(content)){
                message = MessageUtil.initImageMessage(toUserName,fromUserName);

            }else if("8".equals(content)){
                message = MessageUtil.initMusicMessage(toUserName,fromUserName);

            }else if("?".equals(content) || "?".equals(content)){
                message = MessageUtil.initText(toUserName,fromUserName,MessageUtil.menuText());
            }else {
                TextMessage textMessage = new TextMessage();
                textMessage.setFromUserName(toUserName);
                textMessage.setToUserName(fromUserName);
                textMessage.setMsgType("text");
                textMessage.setCreateTime(new Date().getTime()+"");
                textMessage.setContent("您发送的是啥玩意儿?-------》:\n"+content+" \n给你个机会,重新表述一下^_^");
                message=MessageUtil.textMessageToXml(textMessage);
            }
            log.info("message:"+message);
        }else if(MessageUtil.MESSAGE_EVENT.equals(msgType)){//事件推送
            String eventType = map.get("Event");
            if(MessageUtil.MESSAGE_SUBSCRIBE.equals(eventType)){//关注后
                message = MessageUtil.initText(toUserName,fromUserName,MessageUtil.menuText());
            }
        }
        PrintWriter out=null;
        try {
            out = response.getWriter();
            out.print(message);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            out.close();
        }

    }

}
           

微信请求url校验

/**
 * 校验微信请求url
 */
public class CheckUtil {
    public static final String token = "xxxxxxxxxxxxxxxxxxx";//服务号中配置的token
    public static boolean checkSignature(String signature,String timestamp,String nonce){
        String[] arr= new String[]{token,timestamp,nonce};
        //排序
        Arrays.sort(arr);

        //生成字符串
        StringBuffer content = new StringBuffer();
        for (int i = 0; i <arr.length ; i++) {
            content.append(arr[i]);
        }
        //sha1加密
        String temp = getSha1(content.toString());
        return temp.equals(signature);
    }
    /**
     * sha1加密
     * @param str
     * @return
     */
    public static String getSha1(String str){
        if(str == null || str.length()==0){
            return null;
        }
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));

            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j*2];
            int k = 0;
            for(int i=0;i<j;i++){
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }
}
           

messageUtil消息工具类

import com.thoughtworks.xstream.XStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * xml转为map集合
 */
public class MessageUtil {

    public static final String MESSAGE_TEXT = "text";
    public static final String MESSAGE_NEWS = "news";
    public static final String MESSAGE_IMAGE = "image";
    public static final String MESSAGE_VOICE = "voice";
    public static final String MESSAGE_VIDEO = "video";
    public static final String MESSAGE_MUSIC = "music";
    public static final String MESSAGE_LINK = "link";
    public static final String MESSAGE_LOCATION = "location";
    public static final String MESSAGE_EVENT = "event";
    public static final String MESSAGE_SUBSCRIBE = "subscribe";
    public static final String MESSAGE_UNSUBSCRIBE = "unsubscribe";
    public static final String MESSAGE_CLICK = "CLICK";
    public static final String MESSAGE_VIEW = "VIEW";

    public static Map<String,String> xmlToMap(HttpServletRequest request){
        Map<String,String> map = null;
        try {
            map = new HashMap<String,String>();
            SAXReader reader = new SAXReader();
            InputStream ins = request.getInputStream(); //从请求中获取输入流
            Document doc = reader.read(ins);

            Element root = doc.getRootElement();//获取根元素

            List<Element> list = root.elements();

            for (Element  e:list) {
                map.put(e.getName(),e.getText());
            }
            ins.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return map;


    }

    /**
     * 对象类型转为xml
     */
    public static String textMessageToXml(TextMessage textMessage){
        XStream xStream = new XStream();
        xStream.alias("xml",textMessage.getClass());
        return xStream.toXML(textMessage);
    }
    /**
     * 图文类型转为xml
     */
    public static String newsMessageToXml(NewsMessage newsMessage) {

        XStream xStream = new XStream();
        xStream.alias("xml",newsMessage.getClass());
        xStream.alias("item",new News().getClass());
        return xStream.toXML(newsMessage);
    }
    /**
     * 图片转为xml
     */
    public static String imageMessageToXml(ImageMessage imageMessage) {

        XStream xStream = new XStream();
        xStream.alias("xml",imageMessage.getClass());
        xStream.alias("item",new News().getClass());
        return xStream.toXML(imageMessage);
    }
    /**
     * 音乐转为xml
     */
    public static String musicMessageToXml(MusicMessage musicMessage) {

        XStream xStream = new XStream();
        xStream.alias("xml",musicMessage.getClass());
        xStream.alias("item",new News().getClass());
        return xStream.toXML(musicMessage);
    }

    public static String initNewsMessage(String toUserName,String fromUserName){
        String message = null;
        List<News> newsList = new ArrayList<>();
        NewsMessage newsMessage = new NewsMessage();
        News news = new News();
        news.setTitle("事xxxxxxx介绍");
        news.setDescription("事业动力-----当时这个热搜的名字叫“月薪一万和月薪十万最真实的差距”。\n" +
                "\n" +
                "网友们大呼太真实、太扎心了。\n" +
                "\n" +
                "其实这还只是月薪一万的,而我们大部分人都是月薪三、四千,听到这个消息后全都是背后脊柱一片发凉。\n" +
                "\n" +
                "之前公布的2018届毕业大学生的月薪只有4624元,那这些人和月薪十万的精英们相比,差距就远远不止是100倍了。\n" +
                "\n" +
                "这就是马太效应,有钱人会越来越有钱,而没钱的会越来越没钱,整个世界都是按照这个趋势在发展。");
        news.setPicUrl("http://jmkj.free.idcfengye.com/images/JM-1.jpg");
        news.setUrl("https://xin.baidu.com/detail/compinfo?pid=xlTM-TogKuTw1o4sDnZkRVyiaVWGOdcgcQmd&from=ps&fl=1&castk=LTE%3D&tab=basic");
        newsList.add(news);
        News news1 = new News();
        news1.setTitle("事xxxx介绍");
        news1.setDescription("事xxxxx-----当时这个热搜的名字叫“月薪一万和月薪十万最真实的差距”。\n" +
                "\n" +
                "网友们大呼太真实、太扎心了。\n" +
                "\n" +
                "其实这还只是月薪一万的,而我们大部分人都是月薪三、四千,听到这个消息后全都是背后脊柱一片发凉。\n" +
                "\n" +
                "之前公布的2018届毕业大学生的月薪只有4624元,那这些人和月薪十万的精英们相比,差距就远远不止是100倍了。\n" +
                "\n" +
                "这就是马太效应,有钱人会越来越有钱,而没钱的会越来越没钱,整个世界都是按照这个趋势在发展。");
        news1.setPicUrl("http://jmkj.free.idcfengye.com/images/JM-2.jpg");
        news1.setUrl("https://xin.baidu.com/detail/compinfo?pid=xlTM-TogKuTw1o4sDnZkRVyiaVWGOdcgcQmd&from=ps&fl=1&castk=LTE%3D&tab=basic");
        newsList.add(news1);
        News news2 = new News();
        news2.setTitle("事xxxx介绍");
        news2.setDescription("事xxxx-----当时这个热搜的名字叫“月薪一万和月薪十万最真实的差距”。\n" +
                "\n" +
                "网友们大呼太真实、太扎心了。\n" +
                "\n" +
                "其实这还只是月薪一万的,而我们大部分人都是月薪三、四千,听到这个消息后全都是背后脊柱一片发凉。\n" +
                "\n" +
                "之前公布的2018届毕业大学生的月薪只有4624元,那这些人和月薪十万的精英们相比,差距就远远不止是100倍了。\n" +
                "\n" +
                "这就是马太效应,有钱人会越来越有钱,而没钱的会越来越没钱,整个世界都是按照这个趋势在发展。");
        news2.setPicUrl("http://jmkj.free.idcfengye.com/images/JM-2.jpg");
        news2.setUrl("https://xin.baidu.com/detail/compinfo?pid=xlTM-TogKuTw1o4sDnZkRVyiaVWGOdcgcQmd&from=ps&fl=1&castk=LTE%3D&tab=basic");
        newsList.add(news2);
        newsMessage.setToUserName(fromUserName);
        newsMessage.setFromUserName(toUserName);
        newsMessage.setCreateTime(new Date().getTime()+"");
        newsMessage.setMsgType(MESSAGE_NEWS);
        newsMessage.setArticles(newsList);
        newsMessage.setArticleCount(newsList.size());

        message = newsMessageToXml(newsMessage);
        return message;

    }


    public  static String initText(String toUserName,String fromUserName,String content){
        TextMessage textMessage = new TextMessage();
        textMessage.setFromUserName(toUserName);
        textMessage.setToUserName(fromUserName);
        textMessage.setMsgType(MessageUtil.MESSAGE_TEXT);
        textMessage.setCreateTime(new Date().getTime()+"");
        textMessage.setContent(content);
        return  MessageUtil.textMessageToXml(textMessage);
    }

    /**
     * 组装图片消息
     * @param toUserName
     * @param fromUserName
     * @return
     */
    public static String initImageMessage(String toUserName,String fromUserName){
        String message = null;
        Image image = new Image();
        image.setMediaId("agzWlzSlAg1OPSUjP4jCDVQ6-gh78FTyxiTxFAEA0cjdJwqQYxr-IeCsgPouvc-m");
        // image.setMediaId("4tBep9n6etKfp7VTFuMfsMGTvXOWbu8K9m7I8aBJnn3uodlPEaLSUOYc_yiH_Ygx");
        ImageMessage imageMessage = new ImageMessage();
        imageMessage.setFromUserName(toUserName);
        imageMessage.setToUserName(fromUserName);
        imageMessage.setMsgType(MESSAGE_IMAGE);
        imageMessage.setCreateTime(new Date()+"");
        imageMessage.setImage(image);
        message = imageMessageToXml(imageMessage);
        return message;
    }
    /**
     * 组装音乐消息
     * @param toUserName
     * @param fromUserName
     * @return
     */
    public static String initMusicMessage(String toUserName,String fromUserName){
        String message = null;
        Music music = new Music();
        music.setThumbMediaId("ieKIN2UUDrAtq8-Uc0-g3cJGEEuoU-ucQ-IZpwTsFrHoRgo28N2tTqTFVcTZyr1c");
        // image.setMediaId("4tBep9n6etKfp7VTFuMfsMGTvXOWbu8K9m7I8aBJnn3uodlPEaLSUOYc_yiH_Ygx");
        music.setTitle("骆驼沙漠");
        music.setDescription("夏雨菲 - 沙漠骆驼");
        music.setMusicUrl("http://jmkj.free.idcfengye.com/music/ltsm.mp3");
        music.setHQMusicUrl("http://jmkj.free.idcfengye.com/music/ltsm.mp3");
        MusicMessage musicMessage = new MusicMessage();
        musicMessage.setFromUserName(toUserName);
        musicMessage.setToUserName(fromUserName);
        musicMessage.setMsgType(MESSAGE_MUSIC);
        musicMessage.setCreateTime(new Date()+"");
        musicMessage.setMusic(music);
        message = musicMessageToXml(musicMessage);
        return message;
    }

    /**
     * 主菜单
     * @return
     */
    public static  String menuText(){
        StringBuffer sb = new StringBuffer();
        sb.append("欢迎关注xxxx,请按照菜单提示进行操作:\n\n");
        sb.append("1、产品介绍\n");
        sb.append("2、公众号介绍\n");
        sb.append("3、公司介绍\n");
        sb.append("回复?调出此菜单。");
        return sb.toString();
    }

    public  static String firstMenu(){
        StringBuffer sb = new StringBuffer();
        sb.append("此产品用于测试");
        return sb.toString();
    }
    public  static String secondMenu(){
        StringBuffer sb = new StringBuffer();
        sb.append("此公众号用于测试");
        return sb.toString();
    }
    public  static String thirdMenu(){
        StringBuffer sb = new StringBuffer();
        sb.append("公司信息保密");
        return sb.toString();
    }
}
           

实体类对象。。。很多。。。

/**
* 	AccessToken 实体类
**/
public class AccessToken {
    private String token;
    private int expiresIn;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public int getExpiresIn() {
        return expiresIn;
    }

    public void setExpiresIn(int expiresIn) {
        this.expiresIn = expiresIn;
    }
}

           
/**
* 	基础信息 实体类
**/
public class BaseMessage {
    private  String ToUserName;
    private  String FromUserName;
    private  String 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 String getCreateTime() {
        return CreateTime;
    }

    public void setCreateTime(String createTime) {
        CreateTime = createTime;
    }

    public String getMsgType() {
        return MsgType;
    }

    public void setMsgType(String msgType) {
        MsgType = msgType;
    }
}

           
/**
* 图片 实体类
**/
public class Image {
    private String MediaId;

    public String getMediaId() {
        return MediaId;
    }

    public void setMediaId(String mediaId) {
        MediaId = mediaId;
    }
}
           
/**
* 	图片消息实体类(组装了基础消息的内容)
**/
public class ImageMessage extends  BaseMessage{
    private Image Image;

    public cn.xxs.weixin.gongzhonghao.kefugongzhonghao.po.Image getImage() {
        return Image;
    }

    public void setImage(cn.xxs.weixin.gongzhonghao.kefugongzhonghao.po.Image image) {
        Image = image;
    }
}

           
/**
* 	音乐 实体类
**/
public class Music {
    private String Title;
    private String Description;
    private String MusicUrl;
    private String HQMusicUrl;
    private String ThumbMediaId;

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return Description;
    }

    public void setDescription(String description) {
        Description = description;
    }

    public String getMusicUrl() {
        return MusicUrl;
    }

    public void setMusicUrl(String musicUrl) {
        MusicUrl = musicUrl;
    }

    public String getHQMusicUrl() {
        return HQMusicUrl;
    }

    public void setHQMusicUrl(String HQMusicUrl) {
        this.HQMusicUrl = HQMusicUrl;
    }

    public String getThumbMediaId() {
        return ThumbMediaId;
    }

    public void setThumbMediaId(String thumbMediaId) {
        ThumbMediaId = thumbMediaId;
    }
}

           
/**
* 	音乐消息实体类 (组装了基础消息的内容)
**/
public class MusicMessage extends BaseMessage{
    private Music Music;

    public cn.xxs.weixin.gongzhonghao.kefugongzhonghao.po.Music getMusic() {
        return Music;
    }

    public void setMusic(cn.xxs.weixin.gongzhonghao.kefugongzhonghao.po.Music music) {
        Music = music;
    }
}
           
/**
* 	图文消息实体类
**/
public class News {
    private String Title;
    private String Description;
    private String PicUrl;
    private String Url;

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return Description;
    }

    public void setDescription(String description) {
        Description = description;
    }

    public String getPicUrl() {
        return PicUrl;
    }

    public void setPicUrl(String picUrl) {
        PicUrl = picUrl;
    }

    public String getUrl() {
        return Url;
    }

    public void setUrl(String url) {
        Url = url;
    }
}
           
/**
* 	图文消息实体类(组装了基础消息的内容)
**/
public class NewsMessage extends BaseMessage {
    private int ArticleCount;
    private List<News> Articles;

    public int getArticleCount() {
        return ArticleCount;
    }

    public void setArticleCount(int articleCount) {
        ArticleCount = articleCount;
    }

    public List<News> getArticles() {
        return Articles;
    }

    public void setArticles(List<News> articles) {
        Articles = articles;
    }
}

           
/**
* 	文本消息实体类
**/
public class TextMessage extends BaseMessage{

    private  String Content;
    private  String MsgId;


    public String getContent() {
        return Content;
    }

    public void setContent(String content) {
        Content = content;
    }

    public String getMsgId() {
        return MsgId;
    }

    public void setMsgId(String msgId) {
        MsgId = msgId;
    }
}