Androidpn XMPP JID对象xmppUsername大写被转成小写


最近在用androidpn,发现一个很诡异的问题,跟了半天才发现原因,我设置的client的xmppUsername明明有大写的(排除username.toLowerCase问题),但是到了server端就成了全小写的了。下面贴个测试方法,原因就显而易见了。


贴代码前先简单解释下JID:

在XMPP 协议中表示一个地址,由三部分组成: node domain 和resource ,其中 node 和resource是可有可无的 ,domain 是必须的 。 例如 : [email protected]/sleeping , xiaoming 就是node ,xiaoming.home就是domain,sleeping 就是resource。 node domain 和resource任何一部分都不能超过1023 字节 ,加上@ 和 / 一个JID 总共不能超过3071字节。
如:apn中JID as this , 869274011349223@192.168.0.177/AndroidpnClient 。

测试代码如下:

import org.xmpp.packet.JID;

public class JIDTest
{

    /**  
     * @param args 
     * @see 
     */
    public static void main(String[] args)
    {
        JID jid = new JID("Node", "domain", "resource",true);
        System.out.println(jid);//Node@domain/resource
        
        JID jid_ = new JID("Node", "domain", "resource");
        System.out.println(jid_);//node@domain/resource
    }

}
从上面的例子就很容易找到 解决办法传入时加个true参数。在androidpn server端需要进行如下修改,org.androidpn.server.xmpp.session.ClientSession的setAuthToken方法改为:

/**
     * Initialize the session with an authentication token and resource name.
     * 
     * @param authToken the authentication token
     * @param resource the resource
     */
    public void setAuthToken(AuthToken authToken, String resource)
    {
        //update by @will_awoke  此处需要增加true参数,否则会被转成小写
        setAddress(new JID(authToken.getUsername(), getServerName(), resource, true));
        this.authToken = authToken;
        setStatus(Session.STATUS_AUTHENTICATED);
        // Add session to the session manager
        sessionManager.addSession(this);
    }


至于原因,参考下JID的源码,很容易知晓。源码在tinder-1.2.1.jar / org.xmpp.packet.JID,该类提供了多个构造器,其中有这样两个构造器:

public JID(String node, String domain, String resource)
  {
    this(node, domain, resource, false);
  }

  public JID(String node, String domain, String resource, boolean skipStringprep)
  { //something }
可见如果不设置skipStringprep,默认会置为false,具体实现如下:

if (skipStringprep) {
      this.node = node;
      this.domain = domain;
      this.resource = resource;
    }
    else
    {
      if ((node != null) && (node.equals(""))) {
        node = null;
      }
      if ((resource != null) && (resource.equals(""))) {
        resource = null;
      }
      try
      {
        this.node = nodeprep(node);
        this.domain = domainprep(domain);
        this.resource = resourceprep(resource);
      }
也即,skipStringprep == false时,会调用 

        this.node = nodeprep(node);
        this.domain = domainprep(domain);
        this.resource = resourceprep(resource);

进行转换为小写。这三个方法具体细节不再赘述。


综上,over~


你可能感兴趣的:(Androidpn XMPP JID对象xmppUsername大写被转成小写)