
消息加密
需要到入库:commons-io-2.4.jar,commons-codec-1.9.jar(在官网的Java微信加密demo下)
第一步:访问,下载AES加密的示例代码
第二步:新建com.wtz.aes包,把实例代码中的8个AES加密类复制进去,将这些类的包名改为com.wtz.aes,导入库commons-codec-1.9.jar,选上面的Project下的Properties,点击Java Build Path,Libraries,Add Library,选Junit 4,Next,Finish,OK,AES加密导入完成
第三步:找到包com.wtz.util,新建类Parameter.java类,存放参数token,encodingAESKey(随机戳),corpId(AppID),这些在基本配置处可以得到
1 package com.wtz.util;
2
3 /**
4 * @author wangtianze QQ:864620012
5 * @date 2017年4月21日 下午9:27:50
6 * <p>version:1.0</p>
7 * <p>description:参数api</p>
8 */
9 public class Parameter {
10 //token
11 public static String token = "wangtianze";
12 //随机戳
13 public static String encodingAESKey = "X78dYU3MXpijKArRbiozTRq0jZZnjxxvuB4n8KJwRH1";
14 //应用AppID
15 public static String corpId = "wx9621c31e147dfdf9";
16 }
第四步:找到包com.wtz.util下的MessageUtil.java类,修改parseXml方法
1 package com.wtz.util;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.Writer;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 import javax.servlet.http.HttpServletRequest;
12
13 import org.dom4j.Document;
14 import org.dom4j.DocumentException;
15 import org.dom4j.Element;
16 import org.dom4j.io.SAXReader;
17
18 import com.thoughtworks.xstream.XStream;
19 import com.util.QuickWriter;
20 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
21 import com.thoughtworks.l.PrettyPrintWriter;
22 import com.thoughtworks.l.XppDriver;
23 import sponse.ImageMessage;
24 import sponse.MusicMessage;
25 import sponse.NewsMessage;
26 import sponse.TextMessage;
27 import sponse.VideoMessage;
28 import sponse.VoiceMessage;
29
30 /**
31 * @author wangtianze QQ:864620012
32 * @date 2017年4月19日 下午3:29:58
33 * <p>version:1.0</p>
34 * <p>description:消息处理工具类</p>
35 */
36 public class MessageUtil {
37 //请求消息类型:文本
38 public static final String REQ_MESSAGE_TYPE_TEXT = "text";
39 //请求消息类型:图片
40 public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
41 //请求消息类型:语音
42 public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
43 //请求消息类型:视频
44 public static final String REQ_MESSAGE_TYPE_VIDEO = "video";
45 //请求消息类型:地理位置
46 public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
47 //请求消息类型:链接
48 public static final String REQ_MESSAGE_TYPE_LINK = "link";
49 //请求消息类型:事件推送
50 public static final String REQ_MESSAGE_TYPE_EVENT = "event";
51
52 //---------------------------------------------------------------
53
54 //事件类型:subscribe(订阅)
55 public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
56 //事件类型:unsubscribe(取消订阅)
57 public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
58 //事件类型:scan(用户已关注时的扫描带参数的二维码)
59 public static final String EVENT_TYPE_SCAN = "scan";
60 //事件类型:LOCATION(上报地理位置)
61 public static final String EVENT_TYPE_LOCATION = "LOCATION";
62 //事件类型:CLICK(自定义菜单)
63 public static final String EVENT_TYPE_CLICK = "CLICK";
64
65 //---------------------------------------------------------------
66
67 //响应消息类型:文本
68 public static final String RESP_MESSAGE_TYPE_TEXT = "text";
69 //响应详细类型:图片
70 public static final String RESP_MESSAGE_TYPE_IMAGE = "image";
71 //响应消息类型:语音
72 public static final String RESP_MESSAGE_TYPE_VOICE = "voice";
73 //响应消息类型:视频
74 public static final String RESP_MESSAGE_TYPE_VIDEO = "video";
75 //响应详细类型:音乐
76 public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
77 //响应消息类型:图文
78 public static final String RESP_MESSAGE_TYPE_NEWS = "news";
79
80 //---------------------------------------------------------------
81
82 //-----------------------------------------老的,加密前---------------------------------------------
83 // //从流中解析出每个节点的内容
84 // public static Map<String,String> parseXml(HttpServletRequest request) throws IOException{
85 // Map<String,String> map = new HashMap<String,String>();
86 //
87 // //从输入流中获取流对象
88 // InputStream in = InputStream();
89 //
90 // //构建SAX阅读器对象
91 // SAXReader reader = new SAXReader();
92 // try {
93 // //从流中获得文档对象
94 // Document doc = ad(in);
95 //
96 // //获得根节点
97 // Element root = RootElement();
98 //
99 // //获取根节点下的所有子节点
100 // List<Element> children = root.elements();
101 //
102 // for(Element e:children){
103 // //遍历每一个节点,并按照节点名--节点值放入map中
104 // map.Name(), e.getText());
105 // System.out.println("用户发送的消息XML解析为:" + e.getName() + e.getText());
106 // }
107 //
108 // //关闭流
109 // in.close();
110 // in = null;
111 // } catch (DocumentException e) {
112 // // TODO Auto-generated catch block
113 // e.printStackTrace();
114 // }
115 //
116 // return map;
117 // }
118 //-----------------------------------------新的,加密后--------------------------------------------
119 //从流中解析出每个节点的内容
120 public static Map<String,String> parseXml(String request) throws IOException{
121 Map<String,String> map = new HashMap<String,String>();
122
123 //从request中获取流对象
124 InputStream in = new Bytes("UTF-8"));
125
126 //构建SAX阅读器对象
127 SAXReader reader = new SAXReader();
128 try {
129 //从流中获得文档对象
130 Document doc = ad(in);
131
132 //获得根节点
133 Element root = RootElement();
134
135 //获取根节点下的所有子节点
136 List<Element> children = root.elements();
137
138 for(Element e:children){
139 //遍历每一个节点,并按照节点名--节点值放入map中
140 map.Name(), e.getText());
141 System.out.println("用户发送的消息XML解析为:" + e.getName() + e.getText());
142 }
143
144 //关闭流
145 in.close();
146 in = null;
147 } catch (DocumentException e) {
148 // TODO Auto-generated catch block
149 e.printStackTrace();
150 }
151
152 return map;
153 }
154 //----------------------------------------------------------------------------------------------
155
156 /**
157 * 用于扩展节点数据按照<ToUserName><![CDATA[toUser]]></ToUserName>,中间加了CDATA段
158 */
159 private static XStream xstream = new XStream(new XppDriver(){
160 public HierarchicalStreamWriter createWriter(Writer out){
161 return new PrettyPrintWriter(out){
162 boolean cdata = true;
163 public void startNode(String name,Class clazz){
164 super.startNode(name,clazz);
165 }
166
167 protected void writeText(QuickWriter writer,String text){
168 if(cdata){
169 writer.write("<![CDATA[");
170 writer.write(text);
171 writer.write("]]>");
172 }else{
173 writer.write(text);
174 }
175 }
176 };
177 }
178 });
179
180 /**
181 * 将文本消息对象转换成XML格式
182 * params:textMessage 文本消息对象
183 * return:xml
184 */
185 public static String messageToXml(TextMessage textMessage){
186 xstream.alias("xml",Class());
187 XML(textMessage);
188 }
189
190 /**
191 * 将图片消息对象转换成XML格式
192 * params:imageMessage
193 * return:xml
194 */
195 public static String messageToXml(ImageMessage imageMessage){
196 xstream.alias("xml", Class());
197 XML(imageMessage);
198 }
199
200 /**
201 * 将语音消息对象转换成XML格式
202 * params:voiceMessage
203 * return:xml
204 */
205 public static String messageToXml(VoiceMessage voiceMessage){
206 xstream.alias("xml",Class());
207 XML(voiceMessage);
208 }
209
210 /**
211 * 将视频消息对象转换成XML格式
212 * params:videoMessage
213 * return:xml
214 */
215 public static String messageToXml(VideoMessage videoMessage){
216 xstream.alias("xml",Class());
217 XML(videoMessage);
218 }
219
220 /**
221 * 将音乐消息对象转换成XML格式
222 * params:musicMessage
223 * return:xml
224 */
225 public static String messageToXml(MusicMessage musicMessage){
226 xstream.alias("xml",Class());
227 XML(musicMessage);
228 }
229
230 /**
231 * 将图文消息对象转换成XML格式
232 * params:newsMessage
233 * return:xml
234 */
235 public static String messageToXml(NewsMessage newsMessage){
236 xstream.alias("xml",Class());
237 XML(newsMessage);
238 }
239 }
第五步:找到包com.wtz.util下的ProcessService.java类,修改dealRequest方法
1 package com.wtz.util;
2
3 import java.io.IOException;
4 import java.util.Date;
5 import java.util.Map;
6
7 import javax.servlet.http.HttpServletRequest;
8
9 import com.wtz.dao.PostCodeDao;
10 import sponse.TextMessage;
11
12 /**
13 * @author wangtianze QQ:864620012
14 * @date 2017年4月19日 下午8:04:14
15 * <p>version:1.0</p>
16 * <p>description:核心服务类</p>
17 */
18 public class ProcessService {
19 //定义数据访问的dao
20 private static PostCodeDao dao = new PostCodeDao();
21
22 //-----------------------------------老的,加密前--------------------------------------------------
23 // public static String dealRequest(HttpServletRequest request){
24 // //XML格式的消息数据
25 // String respXml = "";
26 // //默认返回的文本消息内容
27 // String respContent = "未知的消息类型";
28 // //调用parseXml方法解析请求消息
29 // Map<String, String> requestMap;
30 // try {
31 // requestMap = MessageUtil.parseXml(request);
32 // //发送方账号
33 // String fromUserName = ("FromUserName");
34 // //开发者微信号
35 // String toUserName = ("ToUserName");
36 // //消息类型
37 // String MsgType = ("MsgType");
38 // //消息内容
39 // String content = ("Content");
40 //
41 // //回复文本消息
42 // TextMessage textMessage = new TextMessage();
43 // textMessage.setToUserName(fromUserName);
44 // textMessage.setFromUserName(toUserName);
45 // textMessage.setCreateTime(new Date().getTime());
46 // textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
47 //
48 // if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)){
49 // respContent = "感谢您关注【王天泽的服务号】n" + "微信号:wangtianze1n" + "请回复序号:n" + "1.查邮政编码n" + "2.查电话区号n" + "?.返回帮助菜单n";
50 // if(content.equals("1")){
51 // respContent = "请按照格式输入地区名,例如输入 邮编:东城";
52 // }
53 // if(content.equals("2")){
54 // respContent = "请按照格式输入地区名,例如输入 区号:东城";
55 // }
56 // if(content.equals("?")){
57 // respContent = "感谢您关注【王天泽的服务号】n" + "微信号:wangtianze1n" + "请回复序号:n" + "1.查邮政编码n" + "2.查电话区号n" + "?.返回帮助菜单n";
58 // }
59 // if(content.startsWith("邮编:")){
60 // int pos = content.indexOf(":");
61 // String cityName = content.substring(pos + 1);
62 // respContent = dao.findPostCodeByCityName(cityName);
63 // System.out.println("邮编:respContent:" + respContent);
64 // }
65 // if(content.startsWith("区号:")){
66 // int pos = content.indexOf(":");
67 // String cityName = content.substring(pos + 1);
68 // respContent = dao.findTelCodeByCityName(cityName);
69 // System.out.println("区号:respContent:" + respContent);
70 // }
71 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)){
72 // respContent = "您发送的是图片消息";
73 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)){
74 // respContent = "您发送的是语音消息";
75 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)){
76 // respContent = "您发送的是视频消息";
77 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)){
78 // respContent = "您发送的是地理位置消息";
79 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)){
80 // respContent = "您发送的是链接消息";
81 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)){
82 // //事件类型
83 // String eventType = ("Event");
84 // if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){
85 // respContent = "感谢您关注【王天泽的服务号】n" + "微信号:wangtianze1n" + "请回复序号:n" + "1.查邮政编码n" + "2.查电话区号n" + "?.返回帮助菜单n";
86 // }else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){
87 // //TODO 取消订阅后用户不会再收到公众号发送的消息,因此不需要回复
88 // }else if(eventType.equals(MessageUtil.EVENT_TYPE_SCAN)){
89 // //TODO 处理扫描带参数二维码事件
90 // }else if(eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)){
91 // //TODO 处理上报地理位置事件
92 // }else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){
93 // //TODO 处理菜单点击事件
94 // }
95 // }
96 // //设置文本消息的内容
97 // textMessage.setContent(respContent);
98 // //将文本消息对象转换成xml
99 // respXml = ssageToXml(textMessage);
100 // } catch (IOException e) {
101 // // TODO Auto-generated catch block
102 // e.printStackTrace();
103 // }
104 //
105 // return respXml;
106 // }
107
108 //----------------------------------------------新的,加密后---------------------------------------------
109 public static String dealRequest(String request){
110 //XML格式的消息数据
111 String respXml = "";
112 //默认返回的文本消息内容
113 String respContent = "未知的消息类型";
114 //调用parseXml方法解析请求消息
115 Map<String, String> requestMap;
116 try {
117 requestMap = MessageUtil.parseXml(request);
118 //发送方账号
119 String fromUserName = ("FromUserName");
120 //开发者微信号
121 String toUserName = ("ToUserName");
122 //消息类型
123 String MsgType = ("MsgType");
124 //消息内容
125 String content = ("Content");
126
127 //回复文本消息
128 TextMessage textMessage = new TextMessage();
129 textMessage.setToUserName(fromUserName);
130 textMessage.setFromUserName(toUserName);
131 textMessage.setCreateTime(new Date().getTime());
132 textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
133
134 if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)){
135 respContent = "感谢您关注【王天泽的服务号】n" + "微信号:wangtianze1n" + "请回复序号:n" + "1.查邮政编码n" + "2.查电话区号n" + "?.返回帮助菜单n";
136 if(content.equals("1")){
137 respContent = "请按照格式输入地区名,例如输入 邮编:东城";
138 }
139 if(content.equals("2")){
140 respContent = "请按照格式输入地区名,例如输入 区号:东城";
141 }
142 if(content.equals("?")){
143 respContent = "感谢您关注【王天泽的服务号】n" + "微信号:wangtianze1n" + "请回复序号:n" + "1.查邮政编码n" + "2.查电话区号n" + "?.返回帮助菜单n";
144 }
145 if(content.startsWith("邮编:")){
146 int pos = content.indexOf(":");
147 String cityName = content.substring(pos + 1);
148 respContent = dao.findPostCodeByCityName(cityName);
149 System.out.println("邮编:respContent:" + respContent);
150 }
151 if(content.startsWith("区号:")){
152 int pos = content.indexOf(":");
153 String cityName = content.substring(pos + 1);
154 respContent = dao.findTelCodeByCityName(cityName);
155 System.out.println("区号:respContent:" + respContent);
156 }
157 }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)){
158 respContent = "您发送的是图片消息";
159 }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)){
160 respContent = "您发送的是语音消息";
161 }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)){
162 respContent = "您发送的是视频消息";
163 }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)){
164 respContent = "您发送的是地理位置消息";
165 }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)){
166 respContent = "您发送的是链接消息";
167 }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)){
168 //事件类型
169 String eventType = ("Event");
170 if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){
171 respContent = "感谢您关注【王天泽的服务号】n" + "微信号:wangtianze1n" + "请回复序号:n" + "1.查邮政编码n" + "2.查电话区号n" + "?.返回帮助菜单n";
172 }else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){
173 //TODO 取消订阅后用户不会再收到公众号发送的消息,因此不需要回复
174 }else if(eventType.equals(MessageUtil.EVENT_TYPE_SCAN)){
175 //TODO 处理扫描带参数二维码事件
176 }else if(eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)){
177 //TODO 处理上报地理位置事件
178 }else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){
179 //TODO 处理菜单点击事件
180 }
181 }
182 //设置文本消息的内容
183 textMessage.setContent(respContent);
184 //将文本消息对象转换成xml
185 respXml = ssageToXml(textMessage);
186 } catch (IOException e) {
187 // TODO Auto-generated catch block
188 e.printStackTrace();
189 }
190
191 return respXml;
192 }
193 }
第六步:找到包com.wtz.service,修改LoginServlet.java类,修改doPost方法
1 package com.wtz.service;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.PrintWriter;
6
7 import javax.servlet.ServletException;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 import org.apachemons.io.IOUtils;
13
14 import com.wtz.aes.AesException;
15 import com.wtz.aes.WXBizMsgCrypt;
16 import com.wtz.util.MessageUtil;
17 import com.wtz.util.Parameter;
18 import com.wtz.util.ProcessService;
19 import com.wtz.util.ValidationUtil;
20
21 /**
22 * @author wangtianze QQ:864620012
23 * @date 2017年4月17日 下午8:11:32
24 * <p>version:1.0</p>
25 * <p>description:微信请求验证类</p>
26 */
27 public class LoginServlet extends HttpServlet {
28
29 @Override
30 protected void doGet(HttpServletRequest request, HttpServletResponse response)
31 throws ServletException, IOException {
32 System.out.println("get请求。。。。。。");
33
34 //1.获得微信签名的加密字符串
35 String signature = Parameter("signature");
36
37 //2.获得时间戳信息
38 String timestamp = Parameter("timestamp");
39
40 //3.获得随机数
41 String nonce = Parameter("nonce");
42
43 //4.获得随机字符串
44 String echostr = Parameter("echostr");
45
46 System.out.println("获得微信签名的加密字符串:"+signature);
47 System.out.println("获得时间戳信息:"+timestamp);
48 System.out.println("获得随机数:"+nonce);
49 System.out.println("获得随机字符串:"+echostr);
50
51 PrintWriter out = Writer();
52
53 //验证请求确认成功原样返回echostr参数内容,则接入生效,成为开发者成功,否则失败
54 if(ValidationUtil.checkSignature(signature, timestamp, nonce)){
55 out.print(echostr);
56 }
57
58 out.close();
59 out = null;
60 }
61
62 /**
63 * 接受微信服务器发过来的XML数据包(通过post请求发送过来的)
64 */
65 @Override
66 protected void doPost(HttpServletRequest request, HttpServletResponse response)
67 throws ServletException, IOException {
68 //将请求响应的编码均设置为UTF-8,防止中文乱码
69 request.setCharacterEncoding("UTF-8");
70 response.setCharacterEncoding("UTF-8");
71
72 //------------------------老的,不加密----------------------------
73 // //获取微信加密的签名字符串
74 // String signature = Parameter("signature");
75 //
76 // //获取时间戳
77 // String timestamp = Parameter("timestamp");
78 //
79 // //获取随机数
80 // String nonce = Parameter("nonce");
81 //
82 // PrintWriter out = Writer();
83 //
84 // if(ValidationUtil.checkSignature(signature,timestamp,nonce)){
85 // String respXml = "";
86 // try {
87 // respXml = ProcessService.dealRequest(request);
88 // } catch (Exception e) {
89 // // TODO Auto-generated catch block
90 // e.printStackTrace();
91 // }
92 // out.print(respXml);
93 // }
94 // out.close();
95 // out = null;
96 //---------------------------新的,加密---------------------------
97 //获取微信加密的签名字符串
98 String signature = Parameter("msg_signature");
99
100 //获取时间戳
101 String timestamp = Parameter("timestamp");
102
103 //获取随机数
104 String nonce = Parameter("nonce");
105
106 //从请求中读取整个post数据
107 InputStream inputStream = InputStream();
108
109 //commons.io.jar方法,直接将流转成字符串
110 String Post = String(inputStream,"UTF-8");
111
112 System.out.println("Post:" + Post);
113
114 String Msg = "";
115 WXBizMsgCrypt wxcpt = null;
116 try {
117 wxcpt = new pId);
118 //解密消息
119 Msg = wxcpt.decryptMsg(signature,timestamp,nonce,Post);
120 } catch (AesException e) {
121 // TODO Auto-generated catch block
122 e.printStackTrace();
123 }
124 //Msg打印结果
125 System.out.println("Msg打印结果:" + Msg);
126
127 //调用核心业务类接收消息,处理消息
128 String respMessage = ProcessService.dealRequest(Msg);
129
130 //respMessage打印结果
131 System.out.println("respMessage打印结果:" + respMessage);
132
133 String encryptMsg = "";
134 try {
135 //加密回复消息
136 encryptMsg = ptMsg(respMessage, timestamp, nonce);
137 System.out.println("encryptMsg:" + encryptMsg);
138 } catch (AesException e) {
139 // TODO Auto-generated catch block
140 e.printStackTrace();
141 }
142
143 //响应消息
144 PrintWriter out = Writer();
145 out.print(encryptMsg);
146 out.close();
147 }
148 } 消息加密完成。
转载于:.html
本文发布于:2024-02-01 10:22:09,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170675413135948.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
| 留言与评论(共有 0 条评论) |