微信----简单自动回复功能emoji和文本处理demo
2017-08-03 17:42
661 查看
概述:emoji和文本混在一起该怎么解析?做过微信都知道,不能直接判断发过是文本还是其他事件?必须要解析出来,但是解析成字符串之后,你会发现emoji会产生异常,或者显示不出来,因为emoji都是\开头字符串代表emoji,但是在解析成字符串,无论你用utf-8都不可以满足要求。
你会想读取两遍,但InputStream不允许重复读,是否存在可以重复的流,把它缓存起来,ByteArrayOutputStream就可以重复读。
日志:
<?xml version="1.0" encoding="utf-8"?><xml> <ToUserName><![CDATA[33dfdfd]]></ToUserName> <FromUserName><![CDATA[3333-T_hZDR-YRjY]]></FromUserName> <CreateTime>1501751512</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[類峕]></Content>
<MsgId>6449973631174700350</MsgId> <Encrypt><![ddfd]]></Encrypt></xml>
这个emoji最后把右号解析没了
首先整个缓存类:
分发的控制类:
可以看出我先将流缓存起来,然后再用。
把必须类或方法贴出来
只涉及文本和emoji处理
实体类
需要增加一个属性文件
名称:jaxb.properties
内容:javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
文件结构:
注意事项:
1.引入jar
3.不需要设置字符编码。正如上面注释的
//marshaller.setProperty(Marshaller.JAXB_ENCODING, "gbk");
你会想读取两遍,但InputStream不允许重复读,是否存在可以重复的流,把它缓存起来,ByteArrayOutputStream就可以重复读。
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[你好]]></Content> </xml>
日志:
<?xml version="1.0" encoding="utf-8"?><xml> <ToUserName><![CDATA[33dfdfd]]></ToUserName> <FromUserName><![CDATA[3333-T_hZDR-YRjY]]></FromUserName> <CreateTime>1501751512</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[類峕]></Content>
<MsgId>6449973631174700350</MsgId> <Encrypt><![ddfd]]></Encrypt></xml>
这个emoji最后把右号解析没了
首先整个缓存类:
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 缓存InputStream,以便InputStream的重复利用 */ public class InputStreamCacher { private static final Logger logger = LoggerFactory.getLogger(InputStreamCacher.class); /** * 将InputStream中的字节保存到ByteArrayOutputStream中。 */ private ByteArrayOutputStream byteArrayOutputStream = null; public InputStreamCacher(InputStream inputStream) throws IOException { if(inputStream == null) { return ; } byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; try { while ((len = inputStream.read(buffer)) > -1 ) { byteArrayOutputStream.write(buffer, 0, len); } byteArrayOutputStream.flush(); } catch (IOException e) { logger.error(e.getMessage(), e); } } public InputStream getInputStream() { if (byteArrayOutputStream == null || byteArrayOutputStream.size()<0) return null; return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); } }
分发的控制类:
@Controller @RequestMapping("/weixin") public class WeiXinEventDispatchController { @Autowired private WeiXinTokenAndTicket weiXinToken; @Autowired private WeiXinMsgService weiXinMsgService; Logger logger = LoggerFactory.getLogger(WeiXinEventDispatchController.class); @ResponseBody @RequestMapping(value="/event", method = {RequestMethod.POST,RequestMethod.GET}) public void event(HttpServletRequest request, HttpServletResponse response) throws IOException, JAXBException { WeiXinRequestBaseParameter weiXinParameter = WeiXinUtil.installParamter(request); InputStream is = request.getInputStream(); InputStreamCacher cache = new InputStreamCacher(is); String data = XmlUtil.inputStream2Str(cache.getInputStream()); logger.info("============================data======================================="); logger.info("=" + data); if(data.contains("<MsgType><![CDATA[event]]></MsgType>") && data.contains("<Event><![CDATA[CLICK]]></Event>")){ String result = data.replace("<![CDATA[", "").replace("]]>", "").trim(); JAXBContext context = JAXBContext.newInstance(MenuClickEventDTO.class); Unmarshaller unmarshaller = context.createUnmarshaller(); MenuClickEventDTO obj = (MenuClickEventDTO)unmarshaller.unmarshal(new StringReader(result)); logger.info(obj.toString()); }else if(data.contains("<MsgType><![CDATA[event]]></MsgType>") && data.contains("<Event><![CDATA[VIEW]]></Event>")){ logger.info("发来了VIEW事件"); }else if(data.contains("<MsgType><![CDATA[event]]></MsgType>") && data.contains("<Event><![CDATA[subscribe]]></Event>")){ logger.info("订阅公众号"); weiXinMsgService.subscribe(weiXinParameter,data,response); }else if(data.contains("<MsgType><![CDATA[event]]></MsgType>") && data.contains("<Event><![CDATA[unsubscribe]]></Event>")){ logger.info("取消公众号"); weiXinMsgService.unsubscribe(weiXinParameter,data,response); }else if(data.contains("<MsgType><![CDATA[voice]]></MsgType>")){ logger.info("语言消息"); weiXinMsgService.voiceHandle(weiXinParameter,data,response); }else if(data.contains("<MsgType><![CDATA[text]]></MsgType>")){ logger.info("文本消息"); weiXinMsgService.textHandle(data,response,cache.getInputStream()); //response.getOutputStream().write(new String(out.toString()).trim().getBytes("UTF-8")); }else { logger.info("未知事件"); if(SignUtil.checkSignature(weiXinParameter)) { logger.info(weiXinParameter.toString()); response.getOutputStream().write(new String(weiXinParameter.getEchostr()).trim().getBytes("UTF-8")); } } } }InputStreamCacher cache = new InputStreamCacher(is);
可以看出我先将流缓存起来,然后再用。
把必须类或方法贴出来
/** * 组装微信请求的数据 * @param request * @return */ public static WeiXinRequestBaseParameter installParamter(HttpServletRequest request){ WeiXinRequestBaseParameter parameter = new WeiXinRequestBaseParameter(); //微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp,nonce参数 parameter.setSignature(request.getParameter("signature")); //时间戳 parameter.setTimestamp(request.getParameter("timestamp")); //获取openId parameter.setOpenid( request.getParameter("openid")); //随机数 parameter.setNonce(request.getParameter("nonce")); parameter.setEchostr(request.getParameter("echostr")); return parameter; }
import java.io.Serializable; /** * @author jack * @version 1.0 * */ public class WeiXinRequestBaseParameter implements Serializable { /** * */ private static final long serialVersionUID = 2297652335403982945L; private String signature; private String timestamp; private String openid; private String nonce; private String echostr; public WeiXinRequestBaseParameter(String signature, String timestamp, String openid, String nonce, String echostr) { super(); this.signature = signature; this.timestamp = timestamp; this.openid = openid; this.nonce = nonce; this.echostr = echostr; } public WeiXinRequestBaseParameter() { super(); } public String getEchostr() { return echostr; } public String getNonce() { return nonce; } public String getOpenid() { return openid; } public String getSignature() { return signature; } public String getTimestamp() { return timestamp; } public void setEchostr(String echostr) { this.echostr = echostr; } public void setNonce(String nonce) { this.nonce = nonce; } public void setOpenid(String openid) { this.openid = openid; } public void setSignature(String signature) { this.signature = signature; } public void setTimestamp(String timestamp) { this.timestamp = timestamp; } @Override public String toString() { return "WeiXinRequestBaseParameter [signature=" + signature + ", timestamp=" + timestamp + ", openid=" + openid + ", nonce=" + nonce + ", echostr=" + echostr + "]"; } }
/** * @param input * @return 返回一个xml * @throws IOException */ public static String inputStream2Str(InputStream input) throws IOException{ StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); InputStreamReader inputReader = new InputStreamReader(input); BufferedReader buffer = new BufferedReader(inputReader); String str = ""; while ((str = buffer.readLine()) != null) { sb.append(new String(str)); } input.close(); return sb.toString().trim(); }
只涉及文本和emoji处理
@Override public void textHandle(String data, HttpServletResponse response,InputStream inputStream) throws JAXBException, IOException { JAXBContext unmarshJc = JAXBContext.newInstance(MsgTextReqDTO.class); JAXBContext marshJc = JAXBContext.newInstance(MsgTextRespDTO.class); Unmarshaller unmarshaller = unmarshJc.createUnmarshaller(); MsgTextReqDTO msgTextReqDTO = (MsgTextReqDTO) unmarshaller.unmarshal(inputStream); //MsgTextReqDTO msgTextReqDTO = (MsgTextReqDTO) unmarshaller.unmarshal(new StringReader(data)); logger.info("Unmarshal: " +msgTextReqDTO.toString()); Marshaller marshaller = marshJc.createMarshaller(); //marshaller.setProperty(Marshaller.JAXB_ENCODING, "gbk"); MsgTextRespDTO msgRespDTO = new MsgTextRespDTO(); //======================硬编码================ msgRespDTO.setContent(msgTextReqDTO.getContent()); msgRespDTO.setCreateTime(WeiXinUtil.createTimestamp()); msgRespDTO.setFromUserName(msgTextReqDTO.getToUserName()); msgRespDTO.setMsgType(msgTextReqDTO.getMsgType()); msgRespDTO.setToUserName(msgTextReqDTO.getFromUserName()); marshaller.marshal(msgRespDTO, response.getOutputStream()); }
实体类
import java.io.Serializable; import javax.xml.bind.annotation.XmlRootElement; import org.eclipse.persistence.oxm.annotations.XmlCDATA; import org.eclipse.persistence.oxm.annotations.XmlPath; import com.rinlink.intelligent.weixin.entity.WeiXinBaseDTO; /** * 文本消息 * @author jack * */ @XmlRootElement(name="xml") public class MsgTextReqDTO extends WeiXinBaseDTO implements Serializable{ /** * */ private static final long serialVersionUID = -1964882722743733100L; @XmlCDATA @XmlPath("Content/text()") private String content; @XmlCDATA @XmlPath("Encrypt/text()") private String encrypt; @XmlPath("MsgId/text()") private String msgId; public MsgTextReqDTO() { super(); } public String getEncrypt() { return encrypt; } public void setEncrypt(String encrypt) { this.encrypt = encrypt; } public String getContent() { return content; } public String getMsgId() { return msgId; } public void setContent(String content) { this.content = content; } public void setMsgId(String msgId) { this.msgId = msgId; } }
import org.eclipse.persistence.oxm.annotations.XmlCDATA; import org.eclipse.persistence.oxm.annotations.XmlPath; public class WeiXinBaseDTO { @XmlCDATA @XmlPath("ToUserName/text()") private String toUserName; @XmlCDATA @XmlPath("FromUserName/text()") private String fromUserName; @XmlPath("CreateTime/text()") private String createTime; @XmlCDATA @XmlPath("MsgType/text()") private String msgType; public String getToUserName() { return toUserName; } public String getFromUserName() { return fromUserName; } public String getCreateTime() { return createTime; } public String getMsgType() { return msgType; } public void setToUserName(String toUserName) { this.toUserName = toUserName; } public void setFromUserName(String fromUserName) { this.fromUserName = fromUserName; } public void setCreateTime(String createTime) { this.createTime = createTime; } public void setMsgType(String msgType) { this.msgType = msgType; } @Override public String toString() { return "WeiXinBaseDTO [toUserName=" + toUserName + ", fromUserName=" + fromUserName + ", createTime=" + createTime + ", msgType=" + msgType + "]"; } }
import java.io.Serializable; import javax.xml.bind.annotation.XmlRootElement; import org.eclipse.persistence.oxm.annotations.XmlCDATA; import org.eclipse.persistence.oxm.annotations.XmlPath; import com.rinlink.intelligent.weixin.entity.WeiXinBaseDTO; /** * 回复文本消息 * @author jack * */ /** * @author Administrator * */ @XmlRootElement(name="xml") public class MsgTextRespDTO extends WeiXinBaseDTO implements Serializable{ /** * */ private static final long serialVersionUID = -1964882722743733100L; @XmlCDATA @XmlPath("Content/text()") private String content; public MsgTextRespDTO() { super(); } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "MsgTextRespDTO [content=" + content + "]" + " " + super.toString(); } }
需要增加一个属性文件
名称:jaxb.properties
内容:javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
文件结构:
注意事项:
1.引入jar
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>org.eclipse.persistence.moxy</artifactId> <version>2.7.0-RC1</version> </dependency>2.这里采用SpringMVC+Maven工程,可以根据你自己改装一下
3.不需要设置字符编码。正如上面注释的
//marshaller.setProperty(Marshaller.JAXB_ENCODING, "gbk");
相关文章推荐
- 超简单微信公众帐号自动回复和天气播报功能应用
- PHP微信开发, 简单的文本自动回复
- JAVA实现 SpringMVC方式的微信接入、实现简单的自动回复功能
- PHP微信开发---简单的文本自动回复
- Android微信自动回复功能
- 微信自动回复消息,批量发送消息,收到消息处理
- python实现微信自动回复功能
- PHP微信开发之文本自动回复
- 微信关键字自动回复功能实现
- Android微信自动回复功能
- 简单http接口对接微信功能DEMO,仅供参考
- python实现微信自动回复及接入聊天机器人等功能
- 微信自动回复功能开发总结
- 微信自动回复功能
- PHP微信开发之文本自动回复
- php微信的文本回复功能开发
- Android微信自动回复功能
- 微信自动回复功能实现
- 利用python微信库itchat实现微信自动回复功能
- Python包装网页微信API并实现简单自动回复