微信----简单自动回复功能emoji和文本处理demo
来源:互联网 发布:java毫秒转换成分钟 编辑:程序博客网 时间:2024/05/21 15:12
概述:emoji和文本混在一起该怎么解析?做过微信都知道,不能直接判断发过是文本还是其他事件?必须要解析出来,但是解析成字符串之后,你会发现emoji会产生异常,或者显示不出来,因为emoji都是\开头字符串代表emoji,但是在解析成字符串,无论你用utf-8都不可以满足要求。
你会想读取两遍,但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 {@Autowiredprivate WeiXinTokenAndTicket weiXinToken;@Autowiredprivate 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"));//获取openIdparameter.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;}@Overridepublic 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();}
@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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");
- 微信----简单自动回复功能emoji和文本处理demo
- 微信自动回复功能
- 微信关键字自动回复功能实现
- Android微信自动回复功能
- java 微信自动回复功能开发
- Android微信自动回复功能
- Android微信自动回复功能
- 微信自动回复功能实现
- 微信公众号开发--Emoji表情(可用于关注自动回复等)
- 微信自动回复
- Android通过AccessibilityService实现微信自动回复功能
- Android通过AccessibilityService实现微信自动回复功能
- java 微信自动回复功能开发(续)
- 微信公共平台开发:简单的自动回复
- PHP微信开发---简单的文本自动回复
- python脚本设置微信自动回复[简单应用]
- django wechatpy建立微信简单自动回复
- Python实现微信自动回复机器人(简单)
- 蓝桥杯训练:简单树——先序和中序遍历转出后序遍历
- 进入App时,白屏解决
- mycalender android 自定义日历控件
- 关于Python类属性与实例属性的讨论
- (hdu6075) 2017杭电多校联赛第四场-Questionnaire 思维题
- 微信----简单自动回复功能emoji和文本处理demo
- Lua用法小结
- 【Python小程序】收发邮件并控制计算机
- hadoop自定义对象序列化Writable和WritableComparable
- 拆分传过来的有逗号的参数
- Android三大动画详解
- 【总结】两种 NIO 实现:Selector 与 Epoll
- Android Studio 完美修改应用包名
- vs2015+opencv3.0读取视频