openfire二次开发:使用Annotation注解VO转换xml文档
2013-06-20 16:09
495 查看
IQElementMapping是一个注解类,用于映射实体类与xml对象
VO接口,所有实体类的超类
消息实体,使用IQElementMapping注解
xml转换工具,使用反射机制
IQ处理器,用于处理客户端发送的查询IQ
/** * openfire_src */ package com.kingray.openfire.plugin.packet; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * IQ映射注解,用于注解实体类的字段,帮助转换器转换为xml对象 * @author KRXiongYingqi * @version 2013-6-17 上午10:44:44 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface IQElementMapping { public String value(); }
VO接口,所有实体类的超类
package com.kingray.openfire.plugin.vo; import java.io.Serializable; /** * VO类,所有实体类的超类 * @author KRXiongYingqi * @version 2013-6-20 下午4:02:49 */ public interface VO extends Serializable{ }
消息实体,使用IQElementMapping注解
package com.kingray.openfire.plugin.vo; import java.util.Date; import com.kingray.openfire.plugin.packet.IQElementMapping; import com.xiongyingqi.util.DateHelper; /** * 消息实体,用于存储传递时用到的查询条件或返回结果 * @author KRXiongYingqi * @version 2013-6-20 下午2:14:47 */ @IQElementMapping("message") public class MessageVO implements VO { @IQElementMapping("messageId") private long messageId; @IQElementMapping("sendMessageId") private String sendMessageId; @IQElementMapping("messageFrom") private String messageFrom; @IQElementMapping("messageTo") private String messageTo; @IQElementMapping("messageSubject") private String messageSubject; @IQElementMapping("messageBody") private String messageBody; @IQElementMapping("messageDateTime") private Date messageDateTime; @IQElementMapping("messageDateTimeStr") private String messageDateTimeStr; @IQElementMapping("messageType") private String messageType; public MessageVO(){ } public MessageVO(long messageId, String sendMessageId, String messageFrom, String messageTo, String messageBody){ this.messageId = messageId; this.sendMessageId = sendMessageId; this.messageFrom = messageFrom; this.messageTo = messageTo; this.messageBody = messageBody; } /** * @return the messageType */ public String getMessageType() { return messageType; } /** * @param messageType the messageType to set */ public void setMessageType(String messageType) { this.messageType = messageType; } /** * @return the messageSubject */ public String getMessageSubject() { return messageSubject; } /** * @param messageSubject the messageSubject to set */ public void setMessageSubject(String messageSubject) { this.messageSubject = messageSubject; } /** * @return the messageId */ public long getMessageId() { return messageId; } /** * @param messageId the messageId to set */ public void setMessageId(long messageId) { this.messageId = messageId; } /** * @return the sendMessageId */ public String getSendMessageId() { return sendMessageId; } /** * @param sendMessageId the sendMessageId to set */ public void setSendMessageId(String sendMessageId) { this.sendMessageId = sendMessageId; } /** * @return the messageFrom */ public String getMessageFrom() { return messageFrom; } /** * @param messageFrom the messageFrom to set */ public void setMessageFrom(String messageFrom) { if(messageFrom == null) messageFrom = ""; this.messageFrom = messageFrom; } /** * @return the messageTo */ public String getMessageTo() { return messageTo; } /** * @param messageTo the messageTo to set */ public void setMessageTo(String messageTo) { if(messageTo == null) messageTo = ""; this.messageTo = messageTo; } /** * @return the messageBody */ public String getMessageBody() { return messageBody; } /** * @param messageBody the messageBody to set */ public void setMessageBody(String messageBody) { this.messageBody = messageBody; } /** * @return the messageDateTime */ public Date getMessageDateTime() { return messageDateTime; } /** * @param messageDateTime the messageDateTime to set */ public void setMessageDateTime(Date messageDateTime) { this.messageDateTimeStr = DateHelper.FORMATTER_LONG.format(messageDateTime); this.messageDateTime = messageDateTime; } /** * @return the messageDateTimeStr */ public String getMessageDateTimeStr() { return messageDateTimeStr; } /** * @param messageDateTimeStr the messageDateTimeStr to set */ public void setMessageDateTimeStr(String messageDateTimeStr) { this.messageDateTime = DateHelper.strToDateLong(messageDateTimeStr); this.messageDateTimeStr = messageDateTimeStr; } @Override public String toString() { return this.getClass() + "@" + hashCode() + ": messageId: " + messageId + ", sendMessageId: " + sendMessageId + ", messageFrom: " + messageFrom + ", messageTo: " + messageTo + ", messageBody: " + messageBody + ", messageDateTime: " + messageDateTime; } }
xml转换工具,使用反射机制
/** * openfire_src */ package com.xiongyingqi.convert; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collection; import java.util.Iterator; import org.dom4j.DocumentHelper; import org.dom4j.Element; import com.kingray.openfire.plugin.packet.KingrayNameSpace; import com.kingray.openfire.plugin.vo.VO; import com.xiongyingqi.util.StringHelper; /** * Xml转换工具 * @author KRXiongYingqi * @version 2013-6-17 下午4:44:03 */ public class XmlConvert { private Class annotationClass; public XmlConvert(Class annotationClass){ this.annotationClass = annotationClass; } /** * 由Collection<? extends VO>转换为xml,被转换的类必须由有注解类注解 * <br>2013-6-17 下午4:44:45 * @param collection 消息集合 * @return org.dom4j.Element */ public Element convertVOs(Collection<? extends VO> collection){ Element element = DocumentHelper.createElement(KingrayNameSpace.QUERY_MESSAGE.getKey()); for (Iterator iterator = collection.iterator(); iterator.hasNext();) { // 遍历集合 Object instance = iterator.next(); Class instanceClass = instance.getClass(); String elementName = null; if(instanceClass.isAnnotationPresent(annotationClass)){ // 判断VO类是否包含了annotationClass的注解 Annotation annotation = instanceClass.getAnnotation(annotationClass); // 获取annotationClass的注解 Method[] methods = annotationClass.getMethods(); // 获取annotationClass的所有方法 if(methods.length > 1){ // 如果有多个注解 for (int i = 0; i < methods.length; i++) { Method method = methods[i]; String methodName = method.getName(); // 注解方法的方法名 if("value".equals(methodName)){ // 是否为value方法 try { elementName = (String) method.invoke(annotation); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } break; } } } else if(methods.length == 1){ Method method = methods[0]; String methodName = method.getName(); // 注解方法的方法名 if("value".equals(methodName)){ // 是否为value方法 try { elementName = (String) method.invoke(annotation); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } if(StringHelper.nullOrEmpty(elementName)){ elementName = instance.getClass().getSimpleName(); } Element messageElement = DocumentHelper.createElement(elementName); // 创建节点 // Class clazz = IQElementMapping.class; Field[] fields = instance.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { // 遍历每个字段 Field field = fields[i]; if(field.isAnnotationPresent(annotationClass)){ // 检测是否为IQElementMapping的注解类型 Annotation annotation = field.getAnnotation(annotationClass); Method[] methods = annotationClass.getDeclaredMethods(); // 获取注解类的所有方法 for (int j = 0; j < methods.length; j++) { Method annoutationMethod = methods[j]; String fieldName = null; try { fieldName = annoutationMethod.invoke(annotation) + ""; // 获取注解方法的返回值 } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (InvocationTargetException e1) { e1.printStackTrace(); } // annotation.value(); String fieldValue = null; // 被注解的字段的值 try { String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); // 使用bean的方法 Method method = instance.getClass().getDeclaredMethod(methodName); Object returnObject = method.invoke(instance); if(returnObject != null){ fieldValue = returnObject + ""; } // fieldValue = (String) field.get(messageVO); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } if(StringHelper.notNullAndNotEmpty(fieldValue)){ messageElement.addAttribute(fieldName, fieldValue); // 为每个字段设置属性 } } } } element.add(messageElement); } return element; } }
IQ处理器,用于处理客户端发送的查询IQ
package com.kingray.openfire.plugin.handler; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.jivesoftware.openfire.IQHandlerInfo; import org.jivesoftware.openfire.IQRouter; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.auth.UnauthorizedException; import org.jivesoftware.openfire.disco.ServerFeaturesProvider; import org.jivesoftware.openfire.handler.IQHandler; import org.jivesoftware.openfire.session.ClientSession; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; import org.xmpp.packet.PacketError; import com.kingray.openfire.plugin.dao.MessageDAO; import com.kingray.openfire.plugin.dao.impl.MessageDAOImpl; import com.kingray.openfire.plugin.packet.IQElementMapping; import com.kingray.openfire.plugin.packet.KingrayNameSpace; import com.kingray.openfire.plugin.packet.MessageHistoryIQ; import com.kingray.openfire.plugin.vo.MessageVO; import com.xiongyingqi.convert.XmlConvert; import com.xiongyingqi.util.CalendarHelper; import com.xiongyingqi.util.DateHelper; import com.xiongyingqi.util.StringHelper; /** * 服务类,用于处理客户端的数据查询等请求 * @author XiongYingqi * */ public class KingrayMessageHistoryIQHandler extends IQHandler implements ServerFeaturesProvider { private static final KingrayNameSpace QUERY_MESSAGE = KingrayNameSpace.QUERY_MESSAGE; // 命名空间 private MessageDAO messageDAO; private XmlConvert convert; private IQHandlerInfo info; private String serverString; public KingrayMessageHistoryIQHandler() { super(QUERY_MESSAGE.getKey()); // 取一个处理器名 messageDAO = new MessageDAOImpl(); convert = new XmlConvert(IQElementMapping.class); info = new IQHandlerInfo(QUERY_MESSAGE.getKey(), QUERY_MESSAGE.getValue()); XMPPServer server = XMPPServer.getInstance(); serverString = server.getServerInfo().getXMPPDomain(); // 注册IQ处理服务 IQRouter iqRouter = server.getIQRouter(); iqRouter.addHandler(this); // server.getServerFeaturesProviders().add(this); // server.getIQDiscoInfoHandler().addServerFeature(QUERY_MESSAGE.getValue()); } @Override public IQ handleIQ(IQ packet) throws UnauthorizedException { System.out.println("packet.toXML() =========== " + packet.toXML()); IQ response = handleMessageHistory(packet); response.setType(IQ.Type.result); response.setFrom(serverString); JID fromJid = packet.getFrom(); ClientSession session = XMPPServer.getInstance().getSessionManager().getSession(fromJid); if(session == null){ // response.setChildElement(packet.getChildElement().createCopy()); response.setError(PacketError.Condition.not_authorized); } // session.process(response); // deliverer.deliver(response); System.out.println(this.getClass() + " handleIQ ====== " + response.toXML()); // response = null; return response; } /** * 处理消息记录 * <br>2013-6-18 上午9:49:27 * @param packet * @return */ public IQ handleMessageHistory(IQ packet){ IQ response = IQ.createResultIQ(packet); String userName = packet.getFrom().getNode(); // 读取根节点数据 Element element = packet.getChildElement(); String relationUserName = element.attributeValue("relationUserName"); String actionType = element.attributeValue("actionType"); String messageDateTimeStr = element.attributeValue("messageDateTime"); Date messageDateTime = null; if(StringHelper.notNullAndNotEmpty(messageDateTimeStr)){ try { messageDateTime = DateHelper.strToDate(messageDateTimeStr); } catch (Exception e) { } } //读取<message节点数据> Collection<Long> messageIds = new HashSet<Long>(); Collection<String> sendMessageIds = new HashSet<String>(); List messageElements = element.elements(); for (Iterator iterator = messageElements.iterator(); iterator.hasNext();) { Element messageElement = (Element) iterator.next(); String messageIdStr = messageElement.attributeValue("messageId"); // 优先读取messageId if(StringHelper.notNullAndNotEmpty(messageIdStr)){ Long messageId = Long.parseLong(messageIdStr); messageIds.add(messageId); } else { // 如果不存在messageId属性,则读取sendMessageId String sendMessageId = messageElement.attributeValue("sendMessageId"); if(StringHelper.notNullAndNotEmpty(sendMessageId)){ sendMessageIds.add(sendMessageId); } } } if(!StringHelper.notNullAndNotEmpty(actionType)){ // 判断是否指定actionType,如果没有指定,则默认使用QUERY_COUNT actionType = MessageHistoryIQ.MessageHistoryActionType.QUERY_COUNT.toString(); } Element resultElement = null; if(actionType.equals(MessageHistoryIQ.MessageHistoryActionType.QUERY_COUNT.toString())){ // 查询条数 int messageHistoryCount = messageDAO.getMessageHistoryCountByUserName(userName, relationUserName, messageDateTime); resultElement = handleMessageHistoryCountResponseIQ(response, messageHistoryCount, relationUserName, messageDateTime); } else if(actionType.equals(MessageHistoryIQ.MessageHistoryActionType.QUERY_SUMMARY.toString())){ // 查询预览 Collection<MessageVO> messageVOs = messageDAO.getMessageHistorySummaryByUserName(userName, relationUserName, messageDateTime); resultElement = convert.convertVOs(messageVOs); // 将获取的数据转换为xml } else if(actionType.equals(MessageHistoryIQ.MessageHistoryActionType.QUERY_DETAIL.toString())){ // 查询详细消息 Collection<MessageVO> messageVOs = null; // 检查查询条件,如果查询条件不足,那么就返回错误 if(messageIds != null && messageIds.size() > 0){ messageVOs = messageDAO.getMessageHistoryDetailByMessageIds(messageIds); } else if(sendMessageIds != null && sendMessageIds.size() > 0){ messageVOs = messageDAO.getMessageHistoryDetailBySendMessageIds(sendMessageIds); } else if(StringHelper.notNullAndNotEmpty(userName)){ messageVOs = messageDAO.getMessageHistoryDetailByUserName(userName, relationUserName, messageDateTime); } else { // 查询条件不足,返回错误 response.setChildElement(packet.getChildElement().createCopy()); response.setError(PacketError.Condition.bad_request); return response; } if(messageVOs != null){ resultElement = convert.convertVOs(messageVOs); // 将获取的数据转换为xml } } System.out.println("resultElement ======== " + resultElement); resultElement.addAttribute("actionType", actionType); // 加入actionType resultElement.addNamespace("", QUERY_MESSAGE.getValue()); // 加入命名空间 response.setChildElement(resultElement); return response; } /** * 返回总消息数的IQ * <br>2013-6-17 下午3:26:22 * @param packet * @param messageCount * @param relationUserName * @param messageDateTime * @return */ public Element handleMessageHistoryCountResponseIQ(IQ packet, int messageHistoryCount, String relationUserName, Date messageDateTime){ Element element = DocumentHelper.createElement(QUERY_MESSAGE.getKey()); // Element messageHistoryCountElement = DocumentHelper.createElement("messageHistoryCount"); // messageHistoryCountElement.setData(messageHistoryCount); // element.add(messageHistoryCountElement); element.addAttribute("messageHistoryCount", messageHistoryCount + ""); if(StringHelper.notNullAndNotEmpty(relationUserName)){ element.addAttribute("relationUserName", relationUserName); } if(messageDateTime != null){ element.addAttribute("messageDateTime", DateHelper.dateToStr(messageDateTime)); } element.addNamespace("", QUERY_MESSAGE.getValue()); // 加入命名空间 // packet.setChildElement(element); return element; } /** * 必须实现该方法,否则openfire将无法实例化本处理器 */ @Override public IQHandlerInfo getInfo() { return info; } /** * <br>2013-6-19 下午5:56:05 * @see org.jivesoftware.openfire.disco.ServerFeaturesProvider#getFeatures() */ @Override public Iterator<String> getFeatures() { ArrayList<String> features = new ArrayList<String>(); features.add(QUERY_MESSAGE.getValue()); return features.iterator(); } }
相关文章推荐
- 关于使用JAXB读取xml文档转换为java对象出现非法注解异常
- 解析在.net中使用XSLT转换xml文档的示例详解
- 使用MSOffice .NET API 将文档(Word \ Excel \ PowerPoint \ Visio \ text \ XML \ RTF \ CSV等)转换为PDF
- servlet3.1(tomcat8、9)开发中,Filter使用注解(Annotation)时,如何定义执行顺序
- Spring2.5注解(标注)学习笔记(使用annotation代替XML)
- spring3 混合使用 XML 与注解(Annotation)进行 Bean 的配置
- XSLT语法 在.net中使用XSLT转换xml文档示例
- Spring之使用Annotation注解开发项目
- 结合使用接口和 ODI 约束开发 ODI XML 到数据库的转换
- Spring框架 注解annotation和配置文件混合使用(生成对象与属性注入) xml配置文件没有提示解决
- Mac下使用XMPP即时通讯【4】:openfire源码部署、二次开发
- c#使用XSLT将xml文档转换为html文档
- XSLT语法 在.net中使用XSLT转换xml文档示例
- spring注解开发AnnotationConfigApplicationContext的使用
- Objective-C ,ios,iphone开发基础:使用GDataXML解析XML文档,(libxml/tree.h not found 错误解决方案)
- 使用xStream框架从JavaBean对象转换成XML文档转换成Java对象
- spring3 混合使用 XML 与注解(Annotation)进行 Bean 的配置
- 使用OPENXML函数将XML文档转换为行结果集 [ZT]
- .net中使用XSLT转换xml文档
- 使用XStream注解实现Java对象与XML互相转换的代码示例---转自:http://www.blogjava.net/bolo