最近在用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); }
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~