首先定义一个类InputMessage 接受微信发过来的消息,微信穿过来的消息主要有,文字(用户输入的),点击事件(按钮),图片,语音,链接,位置等等具体代码如下:
import java.io.Serializable;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("xml")
public class InputMessage implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@XStreamAlias("ToUserName")
private String ToUserName;
@XStreamAlias("FromUserName")
private String FromUserName;
@XStreamAlias("CreateTime")
private Long CreateTime;
@XStreamAlias("MsgType")
private String MsgType = "text";
@XStreamAlias("MsgId")
private Long MsgId;
// 文本消息
@XStreamAlias("Content")
private String Content;
// 图片消息
@XStreamAlias("PicUrl")
private String PicUrl;
// 位置消息
@XStreamAlias("LocationX")
private String LocationX;
@XStreamAlias("LocationY")
private String LocationY;
@XStreamAlias("Scale")
private Long Scale;
@XStreamAlias("Label")
private String Label;
// 链接消息
@XStreamAlias("Title")
private String Title;
@XStreamAlias("Description")
private String Description;
@XStreamAlias("Url")
private String URL;
// 语音信息
@XStreamAlias("MediaId")
private String MediaId;
@XStreamAlias("Format")
private String Format;
@XStreamAlias("Recognition")
private String Recognition;
// 事件
@XStreamAlias("Event")
private String Event;
@XStreamAlias("EventKey")
private String EventKey;
@XStreamAlias("Ticket")
private String Ticket;
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 Long getMsgId() {
return MsgId;
}
public void setMsgId(Long msgId) {
MsgId = msgId;
}
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
public String getPicUrl() {
return PicUrl;
}
public void setPicUrl(String picUrl) {
PicUrl = picUrl;
}
public String getLocationX() {
return LocationX;
}
public void setLocationX(String locationX) {
LocationX = locationX;
}
public String getLocationY() {
return LocationY;
}
public void setLocationY(String locationY) {
LocationY = locationY;
}
public Long getScale() {
return Scale;
}
public void setScale(Long scale) {
Scale = scale;
}
public String getLabel() {
return Label;
}
public void setLabel(String label) {
Label = label;
}
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 getURL() {
return URL;
}
public void setURL(String uRL) {
URL = uRL;
}
public String getEvent() {
return Event;
}
public void setEvent(String event) {
Event = event;
}
public String getEventKey() {
return EventKey;
}
public void setEventKey(String eventKey) {
EventKey = eventKey;
}
public String getMediaId() {
return MediaId;
}
public void setMediaId(String mediaId) {
MediaId = mediaId;
}
public String getFormat() {
return Format;
}
public void setFormat(String format) {
Format = format;
}
public String getRecognition() {
return Recognition;
}
public void setRecognition(String recognition) {
Recognition = recognition;
}
public String getTicket() {
return Ticket;
}
public void setTicket(String ticket) {
Ticket = ticket;
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface XStreamCDATA {
}
然后我们定义一个返回类根据对应的事件返回文本消息数据代码如下:
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("xml")
public class OutputMessage {
@XStreamAlias("ToUserName")
@XStreamCDATA
private String ToUserName;
@XStreamAlias("FromUserName")
@XStreamCDATA
private String FromUserName;
@XStreamAlias("CreateTime")
private Long CreateTime;
@XStreamAlias("MsgType")
@XStreamCDATA
private String MsgType = "text";
private ImageMessage Image;
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 ImageMessage getImage() {
return Image;
}
public void setImage(ImageMessage image) {
Image = image;
}
}
最后将消息转换给xml格式发送给用户所以还需要一个xml转换类代码如下:
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import java.io.Writer;
import java.lang.reflect.Field;
public class SerializeXmlUtil {
public static XStream createXstream() {
return new XStream(new XppDriver() {
@Override
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
boolean cdata = false;
Class targetClass = null;
@Override
public void startNode(String name, @SuppressWarnings("rawtypes") Class clazz) {
super.startNode(name, clazz);
// 业务处理,对于用XStreamCDATA标记的Field,需要加上CDATA标签
if (!name.equals("xml")) {
cdata = needCDATA(targetClass, name);
} else {
targetClass = clazz;
}
}
@Override
protected void writeText(QuickWriter writer, String text) {
if (cdata) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});
}
private static boolean needCDATA(Class<?> targetClass, String fieldAlias) {
boolean cdata = false;
// first, scan self
cdata = existsCDATA(targetClass, fieldAlias);
if (cdata)
return cdata;
// if cdata is false, scan supperClass until java.lang.Object
Class<?> superClass = targetClass.getSuperclass();
while (!superClass.equals(Object.class)) {
cdata = existsCDATA(superClass, fieldAlias);
if (cdata)
return cdata;
superClass = superClass.getClass().getSuperclass();
}
return false;
}
private static boolean existsCDATA(Class<?> clazz, String fieldAlias) {
if ("MediaId".equals(fieldAlias)) {
return true; // 特例添加 morning99
}
// scan fields
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
// 1. exists XStreamCDATA
if (field.getAnnotation(XStreamCDATA.class) != null) {
XStreamAlias xStreamAlias = field.getAnnotation(XStreamAlias.class);
// 2. exists XStreamAlias
if (null != xStreamAlias) {
if (fieldAlias.equals(xStreamAlias.value()))// matched
return true;
} else {// not exists XStreamAlias
if (fieldAlias.equals(field.getName()))
return true;
}
}
}
return false;
}
} ```
需要第三方的xml 转换的jar 支持这里我们引入
《dependency》
《groupId〉om.thoughtworks.xstream《/groupId>
《artifactId>xstream《/artifactId>
《version>1.4.9《/version>
《/dependency>
“`
工具类弄好了接下来就是投入使用了。微信那边采用的是post 请求所以我们在post中处理数据
if (isGet) {
// 微信加密签名
String signature = request.getParameter("signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
String echostr = request.getParameter("echostr");
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (signature != null && CheckoutUtil.checkSignature(StringConfig.Wen_Code,signature, timestamp, nonce)) {
try {
print = response.getWriter();
print.write(echostr);
print.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}else {
try {
// 接收消息并返回消息
new AcceptMessage().acceptMessage(request, response);
} catch (IOException e) {
e.printStackTrace();
}
}```
接下来就是acceptMessage登场的时间了,我们先通过ServletInputStream 获得流数据,接下来使用xml工具类转化成InputMessage 对象取得消息数据再根据消息数据处理返回 结果即可,据图代码如下所示:
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.thoughtworks.xstream.XStream;
import com.wen.blog.dto.TLResult;
import com.wen.blog.util.HandleTalk;
import com.wen.blog.util.ResultMsg;
public class AcceptMessage {
private Logger logger = LoggerFactory.getLogger(this.getClass());
public void acceptMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 处理接收消息
ServletInputStream in = request.getInputStream();
// 将POST流转换为XStream对象
XStream xs = SerializeXmlUtil.createXstream();
xs.processAnnotations(InputMessage.class);
xs.processAnnotations(OutputMessage.class);
// 将指定节点下的xml节点数据映射为对象
xs.alias(“xml”, InputMessage.class);
// 将流转换为字符串
StringBuilder xmlMsg = new StringBuilder();
byte[] b = new byte[4096];
for (int n; (n = in.read(b)) != -1;) {
xmlMsg.append(new String(b, 0, n, “UTF-8”));
}
// 将xml内容转换为InputMessage对象
InputMessage inputMsg = (InputMessage) xs.fromXML(xmlMsg.toString());
String servername = inputMsg.getToUserName();// 服务端
String custermname = inputMsg.getFromUserName();// 客户端
long createTime = inputMsg.getCreateTime();// 接收时间
Long returnTime = Calendar.getInstance().getTimeInMillis() / 1000;// 返回时间
// 取得消息类型
String msgType = inputMsg.getMsgType();
// 根据消息类型获取对应的消息内容
ResultMsg msg= new HandleTalk().handleTalk(inputMsg.getContent());
TLResult tl=(TLResult) msg.getData();
logger.info("回答的内容"+tl.text);
//String xmString = new String(tl.text.toString().getBytes("UTF-8"));
String xmString = tl.text;//new String(.toString().getBytes("UTF-8"));
//msgType.equals(MsgType.Text.toString())
if (tl.code==100000) {
// 文本消息
System.out.println("开发者微信号:" + inputMsg.getToUserName());
System.out.println("发送方帐号:" + inputMsg.getFromUserName());
System.out.println("消息创建时间:" + inputMsg.getCreateTime() + new Date(createTime * 1000l));
System.out.println("消息内容:" + inputMsg.getContent());
System.out.println("消息Id:" + inputMsg.getMsgId());
System.out.println("消息类型:" + msgType);
StringBuffer str = new StringBuffer();
str.append("<xml>");
str.append("<ToUserName><![CDATA[" + custermname + "]]></ToUserName>");
str.append("<FromUserName><![CDATA[" + servername + "]]></FromUserName>");
str.append("<CreateTime>" + returnTime + "</CreateTime>");
str.append("<MsgType><![CDATA[" + msgType + "]]></MsgType>");
str.append("<Content><![CDATA[" + xmString + "]]></Content>");
str.append("</xml>");
System.out.println(str.toString());
response.getWriter().write(str.toString());
} else if(tl.code==200000){
OutputMessage outputMsg = new OutputMessage();
outputMsg.setFromUserName(servername);
outputMsg.setToUserName(custermname);
outputMsg.setCreateTime(returnTime);
outputMsg.setMsgType(msgType);
ImageMessage images = new ImageMessage();
images.setMediaId(inputMsg.getMediaId());
outputMsg.setImage(images);
System.out.println("xml转换:/n" + xs.toXML(outputMsg));
response.getWriter().write(xs.toXML(outputMsg));
}
// 获取并返回多图片消息
/*if (msgType.equals(MsgType.Image.toString())) {
System.out.println("获取多媒体信息");
System.out.println("多媒体文件id:" + inputMsg.getMediaId());
System.out.println("图片链接:" + inputMsg.getPicUrl());
System.out.println("消息id,64位整型:" + inputMsg.getMsgId());
OutputMessage outputMsg = new OutputMessage();
outputMsg.setFromUserName(servername);
outputMsg.setToUserName(custermname);
outputMsg.setCreateTime(returnTime);
outputMsg.setMsgType(msgType);
ImageMessage images = new ImageMessage();
images.setMediaId(inputMsg.getMediaId());
outputMsg.setImage(images);
System.out.println("xml转换:/n" + xs.toXML(outputMsg));
response.getWriter().write(xs.toXML(outputMsg));
}
*/ } }
“`