openfire插件之PacketInterceptor

1.说明

    首先继承PacketInterceptor包拦截类,然后在initializelPlugin()方法中注册拦截器,就可以实现interceptPackage()方法中拦截包(即此方法中的packet参数)了。并且,可以通过入参incoming来判断是服务器发送的包还是接受的包(注:true为服务器接收的包;false为发出的包)。processed参数用处暂不明,猜想是对请求做了什么处理的标识,但不影响我们对包进行拦截和处理。

   本例中此方法实现了通过“jabber:iq:register”命名空间标识来拦截用户注册请求消息,记录消息id,用户名和用户省份信息,存入到upMap中。然后在拦截的返回包中判断,该消息的返回信息(注:请求消息的id和服务器返回的消息的id是一样的),通过id找到该注册消息的返回信息,如果为注册成功(即返回的iq中的type=“result”),就将用户省份信息更新到数据库中,之后删除缓存在upMap中的数据。这样就实现了对用户注册字段的扩展。(注:原来的协议中是没有省份字段的)

   这个扩展方式与前一种相比(参见另一博文基于IQHandler方式的扩展)的好处在于,这种方式不仅没有修改原注册流程的代码,而且最大程度的使用了原注册流程。这样可以避免一些不必要的风险。

2.PacketInterceptor示例:

public class AreaBroadcastPlugin implements Plugin, PacketInterceptor {
	private XMPPServer server;
	private UserInfoDao userInfoDao;
	private static Map<String, HashMap<String, String>> upMap; // 消息id和用户名省份

	@Override
	public void destroyPlugin() {
		System.out.println("destroy AreaBroadcastPlugin");
		InterceptorManager.getInstance().removeInterceptor(this); // 取消packet监听
		if (upMap != null) {
			upMap.clear();
			upMap = null;
		}
	}

	/**
	 * 首先注册拦截器
	 * 
	 */
	@Override
	public void initializePlugin(PluginManager manager, File pluginDirectory) {
		System.out.println("initialize AreaBroadcastPlugin");
		InterceptorManager.getInstance().addInterceptor(this); // 注册packet监听
		server = XMPPServer.getInstance();
		upMap = new ConcurrentHashMap<String, HashMap<String, String>>();
		userInfoDao = new UserInfoDao();
	}

	@Override
	public void interceptPacket(Packet packet, Session session,
			boolean incoming, boolean processed) throws PacketRejectedException {
		if (packet instanceof IQ) {
			IQ iq = (IQ) packet;
			/* 拦截未处理的注册请求信息并将消息id,用户名和省份信息存在upMap中 */
			if (incoming && !processed) {
				Element childElement = iq.getChildElement();
				String namespace = childElement.getNamespaceURI();
				if ("jabber:iq:register".equals(namespace)) {
					String id = iq.getID();
					String province = childElement.elementText("province");
					String username = childElement.elementText("username");
					if (username != null && !"".equals(username)
							&& province != null && !"".equals(province)) {
						HashMap<String, String> map = new HashMap<String, String>();
						map.put("username", username);
						map.put("province", province);
						if (id != null && !"".equals(id)) {
							upMap.put(id, map);
						}
					}
				}
			}
			/* 拦截已处理的注册成功返回信息并根据消息id取出用户名和省份信息存入数据库中 */
			if (!incoming && processed) {
				String type = iq.getType().toString();
				String id = iq.getID();
				/* 注册成功 */
				if ("result".equals(type)) {
					if (upMap.containsKey(id)) {
						String username = upMap.get(id).get("username");
						String province = upMap.get(id).get("province");
						if (username != null && !"".equals(username)
								&& province != null && !"".equals(province)) {
							try {
								userInfoDao.updateUser(username, province);
							} catch (UserNotFoundException e) {
								e.printStackTrace();
							}
						}
					}
				}
				if (upMap.containsKey(id)) {
					upMap.remove(id);
				}
			}
		}
	}

}

3.openfire注册相关协议

1./*用户注册,原本的协议中没有province字段,这里为扩展*/
<iq id="g0G4m-1" to="zhanglj" type="set">
<query xmlns="jabber:iq:register">
<username>re3</username>
<email></email>
<name></name>
<password>1</password>
<province>合肥</province>
</query>
</iq>

2.用户注册成功
<iq type="result" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3"/>

3.用户注册失败
i. 用户名为空:code='500"
 <iq type="error" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3">
<query xmlns="jabber:iq:register">
<username/>
<email/>
<name/>
<password>1</password>
<province>合肥</province>
</query>
<error code="500" type="wait">
<internal-server-error xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>

ii.密码为空:code='406"
 <iq type="error" id="g0G4m-1" from="zhanglj" to="re3@zhanglj/Spark 2.6.3">
<query xmlns="jabber:iq:register">
<username>r</username>
<email/>
<name/>
<password/>
</query>
<error code="406" type="modify"><not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>

iii.用户已存在:code='409"
<iq id="g0G4m-1" to="re3@zhanglj/Spark 2.6.3" from="zhanglj" type="error">
  <query xmlns="jabber:iq:register">
    <username>re5</username>
    <email/>
    <name/>
    <province>合肥</province>
    <password>1</password>
  </query>
  <error code="409" type="CANCEL">
    <conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值