创建java项目

1)导入依赖 pom.xml:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.7.RELEASE</version><relativePath/>
</parent>
<properties><java.version>1.8</java.version>
</properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.1.7.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!-- json --><dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version><classifier>jdk15</classifier></dependency><!-- 公众号配置 --><!-- 配置xstream --><dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.3.1</version></dependency><!-- 配置dom4j --><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><dependency><groupId>org.apache.directory.studio</groupId><artifactId>org.dom4j.dom4j</artifactId><version>1.6.1</version></dependency><!-- 配置xmlpull --><dependency><groupId>xmlpull</groupId><artifactId>xmlpull</artifactId><version>1.1.3.1</version></dependency><!-- 配置javaSDK --><dependency><groupId>com.baidu.aip</groupId><artifactId>java-sdk</artifactId><version>4.8.0</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>RELEASE</version><scope>compile</scope></dependency>
</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

2)application.properties

#spring.datasource.url=jdbc:mysql://localhost:3306/shirodemo?useUnicode=true&amp&characterEncoding=utf-8&serverTimezone=GMT%2B8
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.username=root
#spring.datasource.password=rootserver.port=8080
spring.thymeleaf.cache=false#mybatis.mapper-locations=classpath:mapper/*.xml#mybatis.type-aliases-package=com.webchat.pojo## jsp ##
#访问页面的前置路径
#spring.mvc.view.prefix=/pages/
#访问页面的后缀
#spring.mvc.view.suffix=.jsp

3)mian方法

package com.bdqn;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class WxwebchatApplication {public static void main(String[] args) {SpringApplication.run(WxwebchatApplication.class, args);}}

4)创建消息实体类 com.bdqn.entity

4.1)BaseMessage: //父类

package com.bdqn.entity;import com.thoughtworks.xstream.annotations.XStreamAlias;import java.util.Map;/*** 接受到消息的基本属性  父类* @author 牙**/
public class BaseMessage {@XStreamAlias("ToUserName")private String toUserName;    //开发者微信号@XStreamAlias("FromUserName")private String fromUserName;   //发送方帐号@XStreamAlias("CreateTime")private String createTime;    //消息创建时间@XStreamAlias("MsgType")private String msgType;          //定义所有的类型public String getToUserName() {return toUserName;}public void setToUserName(String toUserName) {this.toUserName = toUserName;}public String getFromUserName() {return fromUserName;}public void setFromUserName(String fromUserName) {this.fromUserName = fromUserName;}public String getCreateTime() {return createTime;}public void setCreateTime(String createTime) {this.createTime = createTime;}public String getMsgType() {return msgType;}public void setMsgType(String msgType) {this.msgType = msgType;}public BaseMessage(Map<String,String> requestMap) {this.toUserName = requestMap.get("FromUserName");this.fromUserName = requestMap.get("ToUserName");this.createTime = System.currentTimeMillis()/1000+"";}}

4.2)TextMeassgae: //文本消息

package com.bdqn.entity;import com.thoughtworks.xstream.annotations.XStreamAlias;import java.util.Map;/*** 文本消息相关属性* @author 牙**/
@XStreamAlias("xml")
public class TextMessage extends BaseMessage {//内容@XStreamAlias("Content")private String content;public String getContent() {return content;}public void setContent(String content) {this.content = content;}public TextMessage(Map<String,String> requestMap,String content) {super(requestMap);//设置文本信息的msgtype为textthis.setMsgType("text");this.content = content;}}

4.3)VoiceMessage://语音消息

package com.bdqn.entity;import com.thoughtworks.xstream.annotations.XStreamAlias;import java.util.Map;/*** 语音消息相关属性* @author 牙**/
@XStreamAlias("xml")
public class VoiceMessage extends BaseMessage {@XStreamAlias("MediaId")private String mediaId;    //语音消息媒体idpublic String getMediaId() {return mediaId;}public void setMediaId(String mediaId) {this.mediaId = mediaId;}public VoiceMessage(Map<String, String> requestMap, String mediaId) {super(requestMap);this.setMsgType("voice");this.mediaId = mediaId;}}

4.4)vodio://视频消息

package com.bdqn.entity;import com.thoughtworks.xstream.annotations.XStreamAlias;import java.util.Map;/*** 视频消息相关属性* @author 牙**/
@XStreamAlias("xml")
public class VideoMessage extends BaseMessage {@XStreamAlias("MediaId")private String mediaId;       //视频消息媒体id@XStreamAlias("Title")private String title;     //视频消息的标题@XStreamAlias("Description")private String description; //视频消息的描述public String getMediaId() {return mediaId;}public void setMediaId(String mediaId) {this.mediaId = mediaId;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public VideoMessage(Map<String, String> requestMap, String mediaId, String title, String description) {super(requestMap);this.setMsgType("video");this.mediaId = mediaId;this.title = title;this.description = description;}}

4.5)imageMessage://图片消息

package com.bdqn.entity;import com.thoughtworks.xstream.annotations.XStreamAlias;import java.util.Map;/*** 图片消息相关属性* @author 牙**/
@XStreamAlias("xml")
public class ImageMessage extends BaseMessage {@XStreamAlias("MediaId")private String mediaId; //图片消息媒体idpublic String getMediaId() {return mediaId;}public void setMediaId(String mediaId) {this.mediaId = mediaId;}public ImageMessage(Map<String, String> requestMap,String mediaId) {super(requestMap);this.setMsgType("image");this.mediaId = mediaId;}}

4.6)Article ://图文消息

package com.bdqn.entity;import com.thoughtworks.xstream.annotations.XStreamAlias;/*** 图文消息相关属性* @author 牙**/
@XStreamAlias("item")
public class Article {@XStreamAlias("Title")private String title;     //图文消息标题@XStreamAlias("Description")private String description;    //图文消息描述@XStreamAlias("PicUrl")private String picUrl;    //图片链接@XStreamAlias("Url")private String url;          //点击图文消息跳转链接public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getPicUrl() {return picUrl;}public void setPicUrl(String picUrl) {this.picUrl = picUrl;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public Article(String title, String description, String picUrl, String url) {super();this.title = title;this.description = description;this.picUrl = picUrl;this.url = url;}}

4.7)NewsMessage ://回复多条图文信息

package com.bdqn.entity;import com.thoughtworks.xstream.annotations.XStreamAlias;import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** 回复多条图文信息的相关属性* @author 牙**/
@XStreamAlias("xml")
public class NewsMessage extends BaseMessage{@XStreamAlias("ArticleCount")private String articleCount;   //多少图文@XStreamAlias("Articles")private List<Article> articles = new ArrayList<Article>();public String getArticleCount() {return articleCount;}public void setArticleCount(String articleCount) {this.articleCount = articleCount;}public List<Article> getArticles() {return articles;}public void setArticles(List<Article> articles) {this.articles = articles;}public NewsMessage(Map<String, String> requestMap, List<Article> articles) {super(requestMap);this.setMsgType("news");this.articleCount = articles.size()+"";this.articles = articles;}}

4.8)Music://音乐消息

package com.bdqn.entity;/*** 音乐消息属性* @author DELL**/
public class Music {private String tityle;       //音乐标题private String description;       //音乐描述private String musicURL;      //音乐链接private String hQmusicURL;    //高质量音乐链接private String thumbMediaId;   //缩略图的媒体idpublic String getTityle() {return tityle;}public void setTityle(String tityle) {this.tityle = tityle;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getMusicURL() {return musicURL;}public void setMusicURL(String musicURL) {this.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) {this.thumbMediaId = thumbMediaId;}public Music(String tityle, String description, String musicURL, String hQmusicURL, String thumbMediaId) {super();this.tityle = tityle;this.description = description;this.musicURL = musicURL;this.hQmusicURL = hQmusicURL;this.thumbMediaId = thumbMediaId;}
}

4.9 MusicMessage://音乐消息属性

package com.bdqn.entity;import com.thoughtworks.xstream.annotations.XStreamAlias;import java.util.Map;/*** 音乐消息相关属性* @author 牙**/
@XStreamAlias("xml")
public class MusicMessage extends BaseMessage{//音乐类## 标题private Music music;   public Music getMusic() {return music;}public void setMusic(Music music) {this.music = music;}public MusicMessage(Map<String,String> requestMap, Music music) {super(requestMap);this.setMsgType("music");this.music = music;}
}

4.10) template/TemplateMessage:发送模板基本信息

package com.bdqn.entity.template;/*** 发送模板基本信息* @author 牙**/
public class TemplateMessage {private String userId;    //用户微信号private String templateId; //模板idprivate String chapterName;    //课程private String studentName;    //学生名称private int fraction;     //分数private String time;      //时间public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public String getTemplateId() {return templateId;}public void setTemplateId(String templateId) {this.templateId = templateId;}public String getChapterName() {return chapterName;}public void setChapterName(String chapterName) {this.chapterName = chapterName;}public String getStudentName() {return studentName;}public void setStudentName(String studentName) {this.studentName = studentName;}public int getFraction() {return fraction;}public void setFraction(int fraction) {this.fraction = fraction;}public String getTime() {return time;}public void setTime(String time) {this.time = time;}public TemplateMessage(String userId, String templateId, String chapterName, String studentName, int fraction,String time) {super();this.userId = userId;this.templateId = templateId;this.chapterName = chapterName;this.studentName = studentName;this.fraction = fraction;this.time = time;}
}

5) 导入工具类:com.bdqn.util

5.1)WebChatUtil :获取token和加密

package com.bdqn.util.weixin;import com.bdqn.entity.AccessToKen;
import net.sf.json.JSONObject;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;/*** 获取token和加密的一个类* @author 何**/
public class WebChatUtil {//定义tokenprivate static final String TOKEN = "zx";private static final String GET_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";//微信公众号appIDprivate static final String APPID="wx9666dd5922bf4b17";//微信公众号appsecretprivate static final String APPSECRET="21b0541fef1f265901b8c5db74e3f825";//用于存储tokenprivate static AccessToKen at;/*** 获取toKen*/private static void getToKen() {String url = GET_TOKEN_URL.replace("APPID", APPID).replaceAll("APPSECRET", APPSECRET);String toKenStr = ReplyUtil.get(url);//把获取的token分装成一个对象JSONObject jsonObject = JSONObject.fromObject(toKenStr);String token = jsonObject.getString("access_token");//过期时间String expiresIn =  jsonObject.getString("expires_in");//创建token对象,并存起来at = new AccessToKen(token, expiresIn);}/*** 向外暴露的获取token的方法* @return*/public static String getAccessToKen() {if(at==null || at.isExpired()){getToKen();}return at.getAccessToken();}/*** 验证签名的方法* token* @param* @param signature 微信加密签名* @param timestamp 时间戳* @param nonce 随机数* @return 将sha1加密后的字符串可与signature对比,返回boolean*/public static boolean checkSignature(String signature, String timestamp, String nonce) {//将token、timestamp、nonce三个参数进行字典序排序String[] strs = new String[] {TOKEN,timestamp,nonce};Arrays.sort(strs);//将三个参数字符串拼接成一个字符串进行sha1加密String str = strs[0]+strs[1]+strs[2];String mysig = sha1(str);return mysig.equals(signature);         //判断加密后的mysig和微信发送得的signature是否相等,返回boolean}/*** 进行sha1加密* @param str* @return*/private static String sha1(String str) {try {//获取一个加密对象MessageDigest md = MessageDigest.getInstance("sha1");//加密byte[] digest = md.digest(str.getBytes());//处理加密结果char[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};StringBuilder sb = new StringBuilder();//处理加密结果for (byte b : digest) {sb.append(chars[(b>>4)&15]);sb.append(chars[b&15]);}return sb.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}
}

5.2)ReplyUtil ://关于回复用户和发送请求

package com.bdqn.util.weixin;import com.bdqn.entity.*;
import com.thoughtworks.xstream.XStream;
import net.sf.json.JSONObject;import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;/*** 关于回复用户和发送请求的工具类*/
public class ReplyUtil {private static final String APPKEY="1fec136dbd19f44743803f89bd55ca62";//百度AI 设置APPID/AK/SKpublic static final String APP_ID = "15468351";public static final String API_KEY = "dacudUXgm64WLQ0Fjr2iRT66";public static final String SECRET_KEY = "l9kvj57aCYSa3t5HuHb2Bwkr5PevV3nt";/*** 调用机器人聊天* @param msg  发送的消息* @return*/public static String chat(String msg) {//1.问答String result =null;String url ="http://op.juhe.cn/robot/index";//请求接口地址Map<String,Object> params = new HashMap<String,Object>();//请求参数params.put("key",APPKEY);//您申请到的本接口专用的APPKEYparams.put("info",msg);//要发送给机器人的内容,不要超过30个字符params.put("dtype","");//返回的数据的格式,json或xml,默认为jsonparams.put("loc","");//地点,如北京中关村params.put("lon","");//经度,东经116.234632(小数点后保留6位),需要写为116234632params.put("lat","");//纬度,北纬40.234632(小数点后保留6位),需要写为40234632params.put("userid","");//1~32位,此userid针对您自己的每一个用户,用于上下文的关联try {result =RobotUtil.net(url, params, "GET");//解析JSONJSONObject jsonObject = JSONObject.fromObject(result);//取出code  判断是否执行成功int code = jsonObject.getInt("error_code");if(code != 0) {return null;}//取出返回的消息内容String resp = jsonObject.getJSONObject("result").getString("text");return resp;} catch (Exception e) {e.printStackTrace();}return null;}/*** 把消息对象处理为xml包* @param msg* @return*/public static String beanToXml(BaseMessage msg) {XStream stream = new XStream();//设置需要处理XStreamAlias("xml")注解的类stream.processAnnotations(TextMessage.class);stream.processAnnotations(ImageMessage.class);stream.processAnnotations(MusicMessage.class);stream.processAnnotations(NewsMessage.class);stream.processAnnotations(VideoMessage.class);stream.processAnnotations(VoiceMessage.class);String xml = stream.toXML(msg);return xml;}//ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ向制定地址发送 post 或 get 请求ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ///*** 向指定的地址发送一个post请求,带着data数据* @param url* @param data* @return*/public static String post(String url,String data) {try {URL urlObj = new URL(url);URLConnection connection = urlObj.openConnection();//要发送数据出去,必须要设置为可发送数据状态connection.setDoOutput(true);//获取输出流OutputStream os = connection.getOutputStream();//写出数据os.write(data.getBytes());os.close();//获取输入流InputStream is = connection.getInputStream();byte[] b = new byte[1024];int len;StringBuilder sb = new StringBuilder();while((len=is.read(b)) != -1) {sb.append(new String(b,0,len));}return sb.toString();} catch (Exception e) {e.printStackTrace();}return null;}/*** 向指定地址发送get请求* @param url* @return*/public static String get(String url) {try {URL urlObj = new URL(url);//开链接URLConnection connection = urlObj.openConnection();InputStream is = connection.getInputStream();byte[] b = new byte[1024];int len;StringBuilder sb = new StringBuilder();while((len=is.read(b)) != -1) {sb.append(new String(b,0,len));}return sb.toString();} catch (Exception e) {e.printStackTrace();}return null;}}

5.3)RobotUtil :回复消息的机器人类

package com.bdqn.util.weixin;import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;/*** 回复消息的机器人类* @author 牙* */
public class RobotUtil {public static final String DEF_CHATSET = "UTF-8";public static final int DEF_CONN_TIMEOUT = 30000;public static final int DEF_READ_TIMEOUT = 30000;public static String userAgent =  "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36";//配置您申请的KEYpublic static final String APPKEY ="*************************";/**** @param strUrl 请求地址* @param params 请求参数* @param method 请求方法* @return  网络请求字符串* @throws Exception*/public static String net(String strUrl, Map<String,Object> params,String method) throws Exception {HttpURLConnection conn = null;BufferedReader reader = null;String rs = null;try {StringBuffer sb = new StringBuffer();if(method==null || method.equals("GET")){strUrl = strUrl+"?"+urlencode(params);}URL url = new URL(strUrl);conn = (HttpURLConnection) url.openConnection();if(method==null || method.equals("GET")){conn.setRequestMethod("GET");}else{conn.setRequestMethod("POST");conn.setDoOutput(true);}conn.setRequestProperty("User-agent", userAgent);conn.setUseCaches(false);conn.setConnectTimeout(DEF_CONN_TIMEOUT);conn.setReadTimeout(DEF_READ_TIMEOUT);conn.setInstanceFollowRedirects(false);conn.connect();if (params!= null && method.equals("POST")) {try {DataOutputStream out = new DataOutputStream(conn.getOutputStream());out.writeBytes(urlencode(params));} catch (Exception e) {e.printStackTrace();}}InputStream is = conn.getInputStream();reader = new BufferedReader(new InputStreamReader(is, DEF_CHATSET));String strRead = null;while ((strRead = reader.readLine()) != null) {sb.append(strRead);}rs = sb.toString();} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}if (conn != null) {conn.disconnect();}}return rs;}//将map型转为请求参数型public static String urlencode(Map<String,Object> data) {StringBuilder sb = new StringBuilder();for (Map.Entry i : data.entrySet()) {try {sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue()+"","UTF-8")).append("&");} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return sb.toString();}}

6)创建service层

package com.bdqn.service.weixin.impl;import com.bdqn.entity.Article;
import com.bdqn.entity.BaseMessage;
import com.bdqn.entity.NewsMessage;
import com.bdqn.entity.TextMessage;
import com.bdqn.service.weixin.ReplyService;
import com.bdqn.util.weixin.ReplyUtil;
import com.bdqn.util.weixin.WebChatUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Service;import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** 回复用户信息的Service实现类*/
@Service
public class ReplyServiceImpl implements ReplyService {/*** 解析xml数据包* @param //InputStream* @return*/@Overridepublic Map<String, String> parseRequest(InputStream is) {Map<String, String> map = new HashMap<String,String>();SAXReader reader = new SAXReader();try {//读取输入流,获取文档对象Document document = reader.read(is);//跟文档对象获取根节点Element rootElement = document.getRootElement();//获取根节点的所有的所有子节点List<Element> list = rootElement.elements();for (Element e : list) {map.put(e.getName(), e.getStringValue());}} catch (DocumentException e) {e.printStackTrace();}return map;}/*** 用于处理所有的事件和消息的回复* @param requestMap* @return 返回xml数据包**/@Overridepublic String getResponse(Map<String, String> requestMap) {BaseMessage msg = null;     //返回的数据//获取类型String msgType = requestMap.get("MsgType");switch (msgType) {// 处理文本消息case "text":String userMsg = requestMap.get("Content");if(userMsg.equals("最新资讯")) {List<Article> articleCount = new ArrayList<Article>();articleCount.add(new Article("最新校园事件", "开展社会实践活动", "http://img2.imgtn.bdimg.com/it/u=2720660882,4014236878&fm=26&gp=0.jpg", "www.baidu.com"));NewsMessage nm = new NewsMessage(requestMap, articleCount);msg = nm;break;}//调用方法返回聊天内容(聊天机器人)String resp = ReplyUtil.chat(userMsg);
//                System.err.println(resp);TextMessage tm = null;if(resp == null) tm = new TextMessage(requestMap, "嘤嘤嘤!臣妾不知道!qwq");else tm = new TextMessage(requestMap, resp);msg = tm;break;case "voice":   //语音消息String Recognition = requestMap.get("Recognition"); //解析的语音字符串System.err.println(Recognition);if(Recognition.equals("")){msg=new TextMessage(requestMap, "抱歉没听清你讲的什么,你嘴里有袜子?");break;}case "video":   //视频消息break;case "shortvideo":break;case "location":break;case "link":break;case "event"://定义菜单事件
//              msg = ReplyUtil.dealEvent(requestMap);String event = requestMap.get("Event");switch (event) {case "CLICK":        //自定义菜单点击事件msg = dealClick(requestMap);break;case "VIEW":        //自定义视图菜单事件msg = dealView(requestMap);break;/*case "subscribe":  //用户未关注时,进行关注后的事件推送//处理点击的第一个一级菜单List<Article> articleCount = new ArrayList<Article>();articleCount.add(new Article("最新校园事件", "青鸟学社开展社会实践活动", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1548093101558&di=a5256eebac10a34c73ca3a0cfcd38ed1&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F011a7258aff54ba801219c773b2db3.png", null));NewsMessage nm = new NewsMessage(requestMap, articleCount);return nm;case "SCAN":     //用户已关注时的事件推送//处理点击的第一个一级菜单List<Article> articleCount2 = new ArrayList<Article>();articleCount2.add(new Article("最新校园事件", "青鸟学社开展社会实践活动", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1548093101558&di=a5256eebac10a34c73ca3a0cfcd38ed1&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F011a7258aff54ba801219c773b2db3.png", null));NewsMessage nm2 = new NewsMessage(requestMap, articleCount2);return nm2;*/default:break;}break;default:break;}//把消息对象处理为xml包if(msg != null) {return ReplyUtil.beanToXml(msg);}else {return null;}}/*** 处理click菜单* @param requestMap* @return*/private static BaseMessage dealClick(Map<String, String> requestMap) {String key = requestMap.get("EventKey");switch (key) {case "campus_details":      //点击校园详情,自定义菜单时定义的key值对应//处理点击的第一个一级菜单List<Article> articleCount = new ArrayList<Article>();articleCount.add(new Article("校园详情", "学校背景,教学质量,校园环境...", "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.jpg", null));NewsMessage nm = new NewsMessage(requestMap, articleCount);return nm;case "journalism":          //校内新闻//处理点击的第一个一级菜单List<Article> articleCount1 = new ArrayList<Article>();articleCount1.add(new Article("校园新闻", "校内大新闻,新闻部出品", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1560534754197&di=c7df5c0583b344cec18c8dea4d2779f3&imgtype=0&src=http%3A%2F%2Fs9.sinaimg.cn%2Fmw690%2F004iLWzlgy6KYusHlUsa8", null));NewsMessage nm1 = new NewsMessage(requestMap, articleCount1);return nm1;case "propaganda_dept":          //校内新闻//处理点击的第一个一级菜单List<Article> articleCount2 = new ArrayList<Article>();articleCount2.add(new Article("宣传部活动", "宣传部大事件,王者争霸赛", "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.jpg", null));NewsMessage nm2 = new NewsMessage(requestMap, articleCount2);return nm2;default:break;}return null;}/*** 处理view类型按钮的菜单* @param requestMap* @return*/private static BaseMessage dealView(Map<String, String> requestMap) {// TODO Auto-generated method stubreturn null;}//根据OpenID列表群发     《内包含预览接口》@Overridepublic String groupSendingmessgaeByOpenId(String articleMediaId, List<String> list) {//根据OpenID群发地址
//      String url = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token="+WebChatUtil.getAccessToKen();//预览地址,预览群发消息的样式String url = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token="+ WebChatUtil.getAccessToKen();//根据OpenID群发地址/*String data = "{\r\n" +"   \"touser\":[\r\n" +"    \"oO9Jv5sAcmD4tDKUl8Ma1ovxehS0\",\r\n" +"    \"oO9Jv5iSPNKLNDWNV4FPdbUqQmZc\"\r\n" +"   ],\r\n" +"   \"mpnews\":{\r\n" +"      \"media_id\":\""+articleMediaId+"\"\r\n" +"   },\r\n" +"    \"msgtype\":\"mpnews\",\r\n" +"    \"send_ignore_reprint\":0\r\n" +"}";*///预览地址,预览群发消息的样式  (测试能否发群发送二个用户)String opid = "";for(String li : list){opid += "\""+li+"\",";}String datas="{\r\n" +"   \"touser\":"+opid+"\r\n" +"   \"mpnews\":{              \r\n" +"            \"media_id\":\""+articleMediaId+"\"               \r\n" +"             },\r\n" +"   \"msgtype\":\"mpnews\" \r\n" +"}";/*String datas="{\r\n" +            备份"   \"touser\":\"oO9Jv5iSPNKLNDWNV4FPdbUqQmZc\", \"oO9Jv5sAcmD4tDKUl8Ma1ovxehS0\",\r\n" +"   \"mpnews\":{              \r\n" +"            \"media_id\":\""+articleMediaId+"\"               \r\n" +"             },\r\n" +"   \"msgtype\":\"mpnews\" \r\n" +"}";*/System.err.println("群发格式:"+datas);String result = ReplyUtil.post(url, datas);System.err.println("群发方法:"+result);return result;}//公众号认证后群发消息的方法@Overridepublic String groupSendingmessgae(String articleMediaId) {String url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token="+WebChatUtil.getAccessToKen();String data = "{\r\n" +"   \"filter\":{\r\n" +"   \"is_to_all\":true\r\n" +                     //用于设定是否向全部用户发送true false"   },\r\n" +"   \"mpnews\":{\r\n" +"      \"media_id\":\""+articleMediaId+"\"\r\n" +   //用于群发的消息的media_id"   },\r\n" +"    \"msgtype\":\"mpnews\",\r\n" +                //群发的消息类型"    \"send_ignore_reprint\":0\r\n" +                 //图文消息被判定为转载时,是否继续群发 1为继续群发(转载),0为停止群发。 该参数默认为0"}";System.err.println("根据标签进行群发post格式:"+data);String result = ReplyUtil.post(url, data);System.err.println("调用的方法:"+result);return result;}}

6)创建微信公众号的主入口: com.bdqn.controller

package com.bdqn.controller.weixin;import com.bdqn.service.weixin.ReplyService;
import com.bdqn.util.weixin.WebChatUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;/*** 微信公众号的主入口*/
@RestController
@RequestMapping(value="/weixin/mywebchat")public class WebChatController {@Autowiredpublic ReplyService replyService;// 开发者接入验证 确认请求来自微信服务器@RequestMapping(method = RequestMethod.GET)public String get(HttpServletRequest request, HttpServletResponse response) throws IOException {//消息来源可靠性验证String signature = request.getParameter("signature");// 微信加密签名String timestamp = request.getParameter("timestamp");// 时间戳String nonce = request.getParameter("nonce");       // 随机数String echostr = request.getParameter("echostr");   //随机字符串//确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败if(WebChatUtil.checkSignature(signature, timestamp, nonce)){System.out.println("=======请求校验成功=======" + echostr);return echostr;}else {System.out.println("=======请求校验失败=======");return null;}}//服务器返回给用户信息@RequestMapping(method = RequestMethod.POST)public String post(HttpServletRequest request, HttpServletResponse response) throws IOException {//设置文字类型request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");response.setHeader("Content-Type","text/html;charset=UTF-8");response.setHeader("Content-Type","text/html;charset=UTF-8");//处理消息和事件推送Map<String,String> requestMap = replyService.parseRequest(request.getInputStream());System.err.println(requestMap);//准备回复的数据包String respXml = replyService.getResponse(requestMap);System.err.println(respXml);return respXml;}}

java开发微信公众号-订阅号-消息接收,及返回给用户信息相关推荐

  1. Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理

    在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...

  2. Java开发微信公众号之被动回复用户消息-回复图片消息

    一.前言 hello小伙伴们,大家好,做微信开发两年了,最近看到微信方面的文章阅读量和关注量上升的比较快速,激发了我满满的动力啊,所以就滋生了一个想法,从头开始整理一下微信公众号开发,写一个简易的教程 ...

  3. Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发

    接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 3.依据接口文档实现业务逻辑 资料准备: 1.一个可以访问的外网,即80的访问端口,因为微信公众号接 ...

  4. java开发微信公众号支付

    这篇文章主要给大家结合微信支付接口开发的实践,从获取用户授权到各主要接口的使用方法等方面介绍微信支付的关键点技术,有需要的小伙伴可以参考下 最近做了微信公众号支付的开发,由于是第一次做也摸索了几天的时 ...

  5. 微信公众平台订阅号运营11个秘决

    据媒体报道微信用户数已经突破6亿!相信在不久的将来微信必将成为重要营销渠道,很多企业都开通了微信号,但是99%微信号都没有专人负责运营,爱煮饭负责运营企业微信订阅号大概有半年多的时间,从0增加到180 ...

  6. 微信公众平台订阅号如何升级转换为服务号?

    很多用户开通微信公众平台时选择了订阅号,但是后来又想用微信支付.小店等功能,就需要把订阅号变成服务号.因微信官方政策限制,目前订阅号改为服务号的方法是进行账号迁移,这也是唯一的方法了. 微信公众平台订 ...

  7. 微信公众平台订阅号和服务号和企业号的区别

    为了帮助网友解决"微信公众平台订阅号和服务号和企业号的区别"相关的问题,中国学网通过互联网对"微信公众平台订阅号和服务号和企业号的区别"相关的解决方案进行了整理 ...

  8. Java开发微信公众号之整合weixin-java-tools框架开发微信公众号

    微信开发者接入文档 : https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319 微信公众平台测试账号申请: http ...

  9. 用java开发微信公众号:测试公众号与本地测试环境搭建(一)

    本文为原创,原始地址为:http://www.cnblogs.com/fengzheng/p/5023678.html 俗话说,工欲善其事,必先利其器.要做微信公众号开发,两样东西不可少,那就是要有一 ...

最新文章

  1. 砂石到芯片转变旅程:一千多道工序,数百英里
  2. codeforces 712 Memory and De-Evolution
  3. 在阿里云做前端,是种怎样的体验?
  4. 裂墙推荐!再也不用求后端给接口了...
  5. Blazor 事件处理开发指南
  6. shell编程追加1
  7. 清除浮动-双伪元素清除浮动(HTML、CSS)
  8. 埃及分数问题+迭代加深搜索
  9. EntityFramework 连接数据库出错
  10. 第四次黄鹤楼之老照片
  11. C语言程序设计谭浩强版 五
  12. uni-app配置代理
  13. java实现身份证归属地查询
  14. 【无人机】【2008.09】用于小型无人机目标定位的轨迹优化
  15. 鸿蒙系统背后的故事,华为“鸿蒙”刷屏背后,这7本书是中国人的终极浪漫
  16. 微信头像 尺寸 php,怎么把照片缩小做微信头像
  17. 跟锦数学200217 厦门大学2019年数学分析考研试题4 (解答见跟锦数学微信公众账号)...
  18. Attack State Slight Movement(攻击状态)
  19. Android转接电话到iPhone,Android迁移数据到iPhone
  20. 通过指针访问二维数组的三种方法

热门文章

  1. 动态规划Ⅰ:斐波那契数列
  2. Crispin ShoeDesign 3D 鞋样设计软件
  3. Javascript事件汇总
  4. 什么是组织变革(组织变革的目的)
  5. 我90后刚毕业后 做前端美工设计的一些经验
  6. 在macOS的终端上使用conda安装软件时的镜像无效问题处理
  7. win10电脑远程连接时可能出现的问题
  8. RFA-Net: Residual feature attention network for fine-grained image inpainting 论文阅读笔记
  9. html做生日快乐页面,生日快乐网站模板(个人制作)(HTML5+CSS3+JS) 修改版
  10. 单片机的字节寻址c语言,单片机C语言通用万能编程模板