基于xmpp openfire smack开发之smack类库介绍和使用[2]

阅读更多

本文转载http://blog.csdn.net/shimiso

 

关于Smack编程库,前面我们提到,它是面向Java端的api,主要在PC上使用,利用它我们可以向openfire服务器注册用户,发送消息,并且可以通过监听器获得此用户的应答消息,以及构建聊天室,分组,个人通讯录等等。

基于xmpp openfire smack开发之smack类库介绍和使用[2]_第1张图片

下面我们写几个程序小例子测试一下。

(1)登录操作

[java] view plain copy print ?
  1. PPConnection.DEBUG_ENABLED=true;
  2. AccountManageraccountManager;
  3. finalConnectionConfigurationconnectionConfig=newConnectionConfiguration(
  4. "192.168.1.78",Integer.parseInt("5222"),"csdn.shimiso.com");
  5. //允许自动连接
  6. connectionConfig.setReconnectionAllowed(true);
  7. connectionConfig.setSendPresence(true);
  8. Connectionconnection=newXMPPConnection(connectionConfig);
  9. try{
  10. connection.connect();//开启连接
  11. accountManager=connection.getAccountManager();//获取账户管理类
  12. }catch(XMPPExceptione){
  13. thrownewIllegalStateException(e);
  14. }
  15. //登录
  16. connection.login("admin","admin","SmackTest");
  17. System.out.println(connection.getUser());
  18. connection.getChatManager().createChat("[email protected]",null).sendMessage("Helloword!");
		PPConnection.DEBUG_ENABLED = true;
		AccountManager accountManager;
		final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
				"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(true);

		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			accountManager = connection.getAccountManager();// 获取账户管理类
		} catch (XMPPException e) {
			throw new IllegalStateException(e);
		}

		// 登录
		connection.login("admin", "admin","SmackTest");
		System.out.println(connection.getUser()); 
		connection.getChatManager().createChat("[email protected]",null).sendMessage("Hello word!");

运行结果:

基于xmpp openfire smack开发之smack类库介绍和使用[2]_第2张图片

在login中一共有三个参数,登录名,密码,资源名,可能有人不明白资源名到底是什么意思,其实就是客户端的来源,客户端的名称,如果不写它默认就叫smack,如果你用相同的账户不同的资源名和同一个人发三条消息,那将会弹出三个窗口,而不是一个窗口。
同时smack还为我们提供了非常好的调试工具Smack Debug,利用该工具我们可以准确的捕获详细的往返报文信息。

(2)下面我们继续写个聊天的例子:

[java] view plain copy print ?
  1. PPConnection.DEBUG_ENABLED=true;
  2. AccountManageraccountManager;
  3. finalConnectionConfigurationconnectionConfig=newConnectionConfiguration(
  4. "192.168.1.78",Integer.parseInt("5222"),"csdn.shimiso.com");
  5. //允许自动连接
  6. connectionConfig.setReconnectionAllowed(true);
  7. connectionConfig.setSendPresence(true);
  8. Connectionconnection=newXMPPConnection(connectionConfig);
  9. try{
  10. connection.connect();//开启连接
  11. accountManager=connection.getAccountManager();//获取账户管理类
  12. }catch(XMPPExceptione){
  13. thrownewIllegalStateException(e);
  14. }
  15. //登录
  16. connection.login("admin","admin","SmackTest3");
  17. ChatManagerchatmanager=connection.getChatManager();
  18. ChatnewChat=chatmanager.createChat("[email protected]",newMessageListener(){
  19. publicvoidprocessMessage(Chatchat,Messagemessage){
  20. if(message.getBody()!=null){
  21. System.out.println("Receivedfrom【"
  22. +message.getFrom()+"】message:"
  23. +message.getBody());
  24. }
  25. }
  26. });
  27. Scannerinput=newScanner(System.in);
  28. while(true){
  29. Stringmessage=input.nextLine();
  30. newChat.sendMessage(message);
  31. }
		PPConnection.DEBUG_ENABLED = true;
		AccountManager accountManager;
		final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
				"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(true);

		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			accountManager = connection.getAccountManager();// 获取账户管理类
		} catch (XMPPException e) {
			throw new IllegalStateException(e);
		}

		// 登录
		connection.login("admin", "admin","SmackTest3");  
		ChatManager chatmanager = connection.getChatManager();
		Chat newChat = chatmanager.createChat("[email protected]", new MessageListener() {
			public void processMessage(Chat chat, Message message) {
				if (message.getBody() != null) {
					System.out.println("Received from 【"
							+ message.getFrom() + "】 message: "
							+ message.getBody());
				}

			}
		});
		Scanner input = new Scanner(System.in);
		while (true) {
			String message = input.nextLine(); 
			newChat.sendMessage(message);
		}

运行结果:

基于xmpp openfire smack开发之smack类库介绍和使用[2]_第3张图片

这里我们用Scanner来捕捉用户在控制台的键盘操作,将信息发出,同时创建了一个MessageListener监听,在其中强制实现processMessage方法即可捕获发回的信息,在初次使用上还是较为容易上手的,我们只要细心查看API即可逐步深入下去。

(3)除了聊天以外我们经常还能想到就是广播

需要给所有在线的用户发送一个通知,或者给所有在线和离线的用户全发送,我们先演示如何给在线用户发送一个广播:

[java] view plain copy print ?
  1. PPConnection.DEBUG_ENABLED=false;
  2. AccountManageraccountManager;
  3. finalConnectionConfigurationconnectionConfig=newConnectionConfiguration(
  4. "192.168.1.78",Integer.parseInt("5222"),"csdn.shimiso.com");
  5. //允许自动连接
  6. connectionConfig.setReconnectionAllowed(true);
  7. connectionConfig.setSendPresence(true);
  8. Connectionconnection=newXMPPConnection(connectionConfig);
  9. try{
  10. connection.connect();//开启连接
  11. accountManager=connection.getAccountManager();//获取账户管理类
  12. }catch(XMPPExceptione){
  13. thrownewIllegalStateException(e);
  14. }
  15. connection.login("admin","admin","SmackTest3");
  16. Messagenewmsg=newMessage();
  17. newmsg.setTo("[email protected]");
  18. newmsg.setSubject("重要通知");
  19. newmsg.setBody("今天下午2点60分有会!");
  20. newmsg.setType(Message.Type.headline);//normal支持离线
  21. connection.sendPacket(newmsg);
  22. connection.disconnect();
		PPConnection.DEBUG_ENABLED = false;
		AccountManager accountManager;
		final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
				"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(true);

		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			accountManager = connection.getAccountManager();// 获取账户管理类
		} catch (XMPPException e) {
			throw new IllegalStateException(e);
		}
		connection.login("admin", "admin","SmackTest3"); 
		Message newmsg = new Message(); 
		newmsg.setTo("[email protected]");
		newmsg.setSubject("重要通知");
		newmsg.setBody("今天下午2点60分有会!");
		newmsg.setType(Message.Type.headline);// normal支持离线 
		connection.sendPacket(newmsg);
		connection.disconnect();

运行结果:

基于xmpp openfire smack开发之smack类库介绍和使用[2]_第4张图片

将参数设置为Message.Type.normal即可支持离线广播,openfire系统会自动判断该用户是否在线,如果在线就直接发送出去,如果不在线则将信息存入ofoffline表,现在我将shimiso用户退出登录,再给它发消息,我们可以进入openfire库的ofoffline表中,非常清楚看到里面躺着一条离线消息记录是发给shimiso这个用户的

基于xmpp openfire smack开发之smack类库介绍和使用[2]_第5张图片

(4)那么我们如何让shimiso这个用户一登陆就取到离线消息呢?

请看如下代码

[java] view plain copy print ?
  1. PPConnection.DEBUG_ENABLED=false;
  2. AccountManageraccountManager;
  3. finalConnectionConfigurationconnectionConfig=newConnectionConfiguration(
  4. "192.168.1.78",Integer.parseInt("5222"),"csdn.shimiso.com");
  5. //允许自动连接
  6. connectionConfig.setReconnectionAllowed(true);
  7. connectionConfig.setSendPresence(false);//不要告诉服务器自己的状态
  8. Connectionconnection=newXMPPConnection(connectionConfig);
  9. try{
  10. connection.connect();//开启连接
  11. accountManager=connection.getAccountManager();//获取账户管理类
  12. }catch(XMPPExceptione){
  13. thrownewIllegalStateException(e);
  14. }
  15. connection.login("shimiso","123","SmackTest");
  16. OfflineMessageManagerofflineManager=newOfflineMessageManager(
  17. connection);
  18. try{
  19. Iteratorit=offlineManager
  20. .getMessages();
  21. System.out.println(offlineManager.supportsFlexibleRetrieval());
  22. System.out.println("离线消息数量:"+offlineManager.getMessageCount());
  23. Map>offlineMsgs=newHashMap>();
  24. while(it.hasNext()){
  25. org.jivesoftware.smack.packet.Messagemessage=it.next();
  26. System.out
  27. .println("收到离线消息,Receivedfrom【"+message.getFrom()
  28. +"】message:"+message.getBody());
  29. StringfromUser=message.getFrom().split("/")[0];
  30. if(offlineMsgs.containsKey(fromUser)){
  31. offlineMsgs.get(fromUser).add(message);
  32. }else{
  33. ArrayListtemp=newArrayList();
  34. temp.add(message);
  35. offlineMsgs.put(fromUser,temp);
  36. }
  37. }
  38. //在这里进行处理离线消息集合......
  39. Setkeys=offlineMsgs.keySet();
  40. IteratoroffIt=keys.iterator();
  41. while(offIt.hasNext()){
  42. Stringkey=offIt.next();
  43. ArrayListms=offlineMsgs.get(key);
  44. for(inti=0;i
  45. System.out.println("-->"+ms.get(i));
  46. }
  47. }
  48. offlineManager.deleteMessages();
  49. }catch(Exceptione){
  50. e.printStackTrace();
  51. }
  52. offlineManager.deleteMessages();//删除所有离线消息
  53. Presencepresence=newPresence(Presence.Type.available);
  54. nnection.sendPacket(presence);//上线了
  55. nnection.disconnect();//关闭连接
		PPConnection.DEBUG_ENABLED = false;
		AccountManager accountManager;
		final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
				"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(false);//不要告诉服务器自己的状态
		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			accountManager = connection.getAccountManager();// 获取账户管理类
		} catch (XMPPException e) {
			throw new IllegalStateException(e);
		} 
		connection.login("shimiso", "123","SmackTest"); 
		OfflineMessageManager offlineManager = new OfflineMessageManager(
				connection);
		try {
			Iterator it = offlineManager
					.getMessages();

			System.out.println(offlineManager.supportsFlexibleRetrieval());
			System.out.println("离线消息数量: " + offlineManager.getMessageCount());

			Map> offlineMsgs = new HashMap>();

			while (it.hasNext()) {
				org.jivesoftware.smack.packet.Message message = it.next();
				System.out
						.println("收到离线消息, Received from 【" + message.getFrom()
								+ "】 message: " + message.getBody());
				String fromUser = message.getFrom().split("/")[0];

				if (offlineMsgs.containsKey(fromUser)) {
					offlineMsgs.get(fromUser).add(message);
				} else {
					ArrayList temp = new ArrayList();
					temp.add(message);
					offlineMsgs.put(fromUser, temp);
				}
			}

			// 在这里进行处理离线消息集合......
			Set keys = offlineMsgs.keySet();
			Iterator offIt = keys.iterator();
			while (offIt.hasNext()) {
				String key = offIt.next();
				ArrayList ms = offlineMsgs.get(key);

				for (int i = 0; i < ms.size(); i++) {
					System.out.println("-->" + ms.get(i));
				}
			}

			offlineManager.deleteMessages();
		} catch (Exception e) {
			e.printStackTrace();
		}
		offlineManager.deleteMessages();//删除所有离线消息
		Presence presence = new Presence(Presence.Type.available);
        		nnection.sendPacket(presence);//上线了
        		nnection.disconnect();//关闭连接

运行结果:

基于xmpp openfire smack开发之smack类库介绍和使用[2]_第6张图片

这里我们需要特别当心的是先不要告诉openfire服务器你上线了,否则永远也拿不到离线消息,用下面英文大概意思就是在你上线之前去获取离线消息,这么设计是很有道理的。

The OfflineMessageManager helps manage offline messages even before the user has sent an available presence. When a user asks for his offline messages before sending an available presence then the server will not send a flood with all the offline messages when the user becomes online. The server will not send a flood with all the offline messages to the session that made the offline messages request or to any other session used by the user that becomes online.

拿到离线消息处理完毕之后删除离线消息offlineManager.deleteMessages() 接着通知服务器上线了。

(5)下面我们来看看如何来发送文件

 

[java] view plain copy print ?
  1. PPConnection.DEBUG_ENABLED=false;
  2. AccountManageraccountManager;
  3. finalConnectionConfigurationconnectionConfig=newConnectionConfiguration(
  4. "192.168.1.78",Integer.parseInt("5222"),"csdn.shimiso.com");
  5. //允许自动连接
  6. connectionConfig.setReconnectionAllowed(true);
  7. connectionConfig.setSendPresence(true);
  8. Connectionconnection=newXMPPConnection(connectionConfig);
  9. try{
  10. connection.connect();//开启连接
  11. accountManager=connection.getAccountManager();//获取账户管理类
  12. }catch(XMPPExceptione){
  13. thrownewIllegalStateException(e);
  14. }
  15. connection.login("admin","admin","Rooyee");
  16. Presencepre=connection.getRoster().getPresence("[email protected]");
  17. System.out.println(pre);
  18. if(pre.getType()!=Presence.Type.unavailable){
  19. //创建文件传输管理器
  20. FileTransferManagermanager=newFileTransferManager(connection);
  21. //创建输出的文件传输
  22. OutgoingFileTransfertransfer=manager
  23. .createOutgoingFileTransfer(pre.getFrom());
  24. //发送文件
  25. transfer.sendFile(newFile("E:\\Chrysanthemum.jpg"),"图片");
  26. while(!transfer.isDone()){
  27. if(transfer.getStatus()==FileTransfer.Status.in_progress){
  28. //可以调用transfer.getProgress();获得传输的进度 
  29. System.out.println(transfer.getStatus());
  30. System.out.println(transfer.getProgress());
  31. System.out.println(transfer.isDone());
  32. }
  33. }
  34. }
		PPConnection.DEBUG_ENABLED = false;
		AccountManager accountManager;
		final ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
				"192.168.1.78", Integer.parseInt("5222"), "csdn.shimiso.com");

		// 允许自动连接
		connectionConfig.setReconnectionAllowed(true);
		connectionConfig.setSendPresence(true);

		Connection connection = new XMPPConnection(connectionConfig);
		try {
			connection.connect();// 开启连接
			accountManager = connection.getAccountManager();// 获取账户管理类
		} catch (XMPPException e) {
			throw new IllegalStateException(e);
		}
		  connection.login("admin", "admin","Rooyee"); 
		  Presence pre = connection.getRoster().getPresence("[email protected]");
			System.out.println(pre);
			if (pre.getType() != Presence.Type.unavailable) {
				// 创建文件传输管理器
				FileTransferManager manager = new FileTransferManager(connection);
				// 创建输出的文件传输
				OutgoingFileTransfer transfer = manager
						.createOutgoingFileTransfer(pre.getFrom());
				// 发送文件
				transfer.sendFile(new File("E:\\Chrysanthemum.jpg"), "图片");
				while (!transfer.isDone()) {
					if (transfer.getStatus() == FileTransfer.Status.in_progress) {
						// 可以调用transfer.getProgress();获得传输的进度 
						System.out.println(transfer.getStatus());
						System.out.println(transfer.getProgress());
						System.out.println(transfer.isDone());
					}
				}
			}

运行结果:

基于xmpp openfire smack开发之smack类库介绍和使用[2]_第7张图片

在这里我们需要特别注意的是,跨资源是无法发送文件的,看connection.login("admin", "admin","Rooyee");这个代码就明白了,必须是“域名和资源名”完全相同的两个用户才可以互发文件,否则永远都没反应,如果不清楚自己所用的客户端的资源名,可以借助前面提到的SmackDebug工具查看往返信息完整报文,在to和from中一定可以看到。

如果我们自己要写文件接收例子的话,参考代码如下:

[java] view plain copy print ?
  1. FileTransferManagertransfer=newFileTransferManager(connection);
  2. transfer.addFileTransferListener(newRecFileTransferListener());
  3. publicclassRecFileTransferListenerimplementsFileTransferListener{
  4. publicStringgetFileType(StringfileFullName){
  5. if(fileFullName.contains(".")){
  6. return"."+fileFullName.split("//.")[1];
  7. }else{
  8. returnfileFullName;
  9. }
  10. }
  11. @Override
  12. publicvoidfileTransferRequest(FileTransferRequestrequest){
  13. System.out.println("接收文件开始.....");
  14. finalIncomingFileTransferinTransfer=request.accept();
  15. finalStringfileName=request.getFileName();
  16. longlength=request.getFileSize();
  17. finalStringfromUser=request.getRequestor().split("/")[0];
  18. System.out.println("文件大小:"+length+""+request.getRequestor());
  19. System.out.println(""+request.getMimeType());
  20. try{
  21. JFileChooserchooser=newJFileChooser();
  22. chooser.setCurrentDirectory(newFile("."));
  23. intresult=chooser.showOpenDialog(null);
  24. if(result==JFileChooser.APPROVE_OPTION){
  25. finalFilefile=chooser.getSelectedFile();
  26. System.out.println(file.getAbsolutePath());
  27. newThread(){
  28. publicvoidrun(){
  29. try{
  30. System.out.println("接受文件:"+fileName);
  31. inTransfer
  32. .recieveFile(newFile(file
  33. .getAbsolutePath()
  34. +getFileType(fileName)));
  35. Messagemessage=newMessage();
  36. message.setFrom(fromUser);
  37. message.setProperty("REC_SIGN","SUCCESS");
  38. message.setBody("["+fromUser+"]发送文件:"
  39. +fileName+"/r/n"+"存储位置:"
  40. +file.getAbsolutePath()
  41. +getFileType(fileName));
  42. if(Client.isChatExist(fromUser)){
  43. Client.getChatRoom(fromUser)
  44. .messageReceiveHandler(message);
  45. }else{
  46. ChatFrameThreadcft=newChatFrameThread(
  47. fromUser,message);
  48. cft.start();
  49. }
  50. }catch(Exceptione2){
  51. e2.printStackTrace();
  52. }
  53. }
  54. }.start();
  55. }else{
  56. System.out.println("拒绝接受文件:"+fileName);
  57. request.reject();
  58. Messagemessage=newMessage();
  59. message.setFrom(fromUser);
  60. message.setBody("拒绝"+fromUser+"发送文件:"+fileName);
  61. message.setProperty("REC_SIGN","REJECT");
  62. if(Client.isChatExist(fromUser)){
  63. Client.getChatRoom(fromUser).messageReceiveHandler(message);
  64. }else{
  65. ChatFrameThreadcft=newChatFrameThread(fromUser,message);
  66. cft.start();
  67. }
  68. }
  69. /*
  70. *InputStreamin=inTransfer.recieveFile();
  71. *
  72. *StringfileName="r"+inTransfer.getFileName();
  73. *
  74. *OutputStreamout=newFileOutputStream(new
  75. *File("d:/receive/"+fileName));byte[]b=newbyte[512];
  76. *while(in.read(b)!=-1){out.write(b);out.flush();}
  77. *
  78. *in.close();out.close();
  79. */
  80. }catch(Exceptione){
  81. e.printStackTrace();
  82. }
  83. System.out.println("接收文件结束.....");
  84. }
  85. }
FileTransferManager transfer = new FileTransferManager(connection);
transfer.addFileTransferListener(new RecFileTransferListener());
public class RecFileTransferListener implements FileTransferListener {

	public String getFileType(String fileFullName) {
		if (fileFullName.contains(".")) {
			return "." + fileFullName.split("//.")[1];
		} else {
			return fileFullName;
		}

	}

	@Override
	public void fileTransferRequest(FileTransferRequest request) {
		System.out.println("接收文件开始.....");
		final IncomingFileTransfer inTransfer = request.accept();
		final String fileName = request.getFileName();
		long length = request.getFileSize();
		final String fromUser = request.getRequestor().split("/")[0];
		System.out.println("文件大小:" + length + "  " + request.getRequestor());
		System.out.println("" + request.getMimeType());
		try {

			JFileChooser chooser = new JFileChooser();
			chooser.setCurrentDirectory(new File("."));

			int result = chooser.showOpenDialog(null);

			if (result == JFileChooser.APPROVE_OPTION) {
				final File file = chooser.getSelectedFile();
				System.out.println(file.getAbsolutePath());
				new Thread() {
					public void run() {
						try {

							System.out.println("接受文件: " + fileName);
							inTransfer
									.recieveFile(new File(file
											.getAbsolutePath()
											+ getFileType(fileName)));

							Message message = new Message();
							message.setFrom(fromUser);
							message.setProperty("REC_SIGN", "SUCCESS");
							message.setBody("[" + fromUser + "]发送文件: "
									+ fileName + "/r/n" + "存储位置: "
									+ file.getAbsolutePath()
									+ getFileType(fileName));
							if (Client.isChatExist(fromUser)) {
								Client.getChatRoom(fromUser)
										.messageReceiveHandler(message);
							} else {
								ChatFrameThread cft = new ChatFrameThread(
										fromUser, message);
								cft.start();

							}
						} catch (Exception e2) {
							e2.printStackTrace();
						}
					}
				}.start();
			} else {

				System.out.println("拒绝接受文件: " + fileName);

				request.reject();
				Message message = new Message();
				message.setFrom(fromUser);
				message.setBody("拒绝" + fromUser + "发送文件: " + fileName);
				message.setProperty("REC_SIGN", "REJECT");
				if (Client.isChatExist(fromUser)) {
					Client.getChatRoom(fromUser).messageReceiveHandler(message);
				} else {
					ChatFrameThread cft = new ChatFrameThread(fromUser, message);
					cft.start();
				}
			}

			/*
			 * InputStream in = inTransfer.recieveFile();
			 * 
			 * String fileName = "r"+inTransfer.getFileName();
			 * 
			 * OutputStream out = new FileOutputStream(new
			 * File("d:/receive/"+fileName)); byte[] b = new byte[512];
			 * while(in.read(b) != -1) { out.write(b); out.flush(); }
			 * 
			 * in.close(); out.close();
			 */
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println("接收文件结束.....");

	}

}

(6)用户列表

[java] view plain copy print ?
  1. **
  2. *返回所有组信息
  3. *
  4. *@returnList(RosterGroup)
  5. */
  6. publicstaticListgetGroups(Rosterroster){
  7. ListgroupsList=newArrayList();
  8. CollectionrosterGroup=roster.getGroups();
  9. Iteratori=rosterGroup.iterator();
  10. while(i.hasNext())
  11. groupsList.add(i.next());
  12. returngroupsList;
  13. }
  14. /**
  15. *返回相应(groupName)组里的所有用户
  16. *
  17. *@returnList(RosterEntry)
  18. */
  19. publicstaticListgetEntriesByGroup(Rosterroster,
  20. StringgroupName){
  21. ListEntriesList=newArrayList();
  22. RosterGrouprosterGroup=roster.getGroup(groupName);
  23. CollectionrosterEntry=rosterGroup.getEntries();
  24. Iteratori=rosterEntry.iterator();
  25. while(i.hasNext())
  26. EntriesList.add(i.next());
  27. returnEntriesList;
  28. }
  29. /**
  30. *返回所有用户信息
  31. *
  32. *@returnList(RosterEntry)
  33. */
  34. publicstaticListgetAllEntries(Rosterroster){
  35. ListEntriesList=newArrayList();
  36. CollectionrosterEntry=roster.getEntries();
  37. Iteratori=rosterEntry.iterator();
  38. while(i.hasNext())
  39. EntriesList.add(i.next());
  40. returnEntriesList;
  41. }
	**
	 * 返回所有组信息 
	 * 
	 * @return List(RosterGroup)
	 */
	public static List getGroups(Roster roster) {
		List groupsList = new ArrayList();
		Collection rosterGroup = roster.getGroups();
		Iterator i = rosterGroup.iterator();
		while (i.hasNext())
			groupsList.add(i.next());
		return groupsList;
	}

	/**
	 * 返回相应(groupName)组里的所有用户
	 * 
	 * @return List(RosterEntry)
	 */
	public static List getEntriesByGroup(Roster roster,
			String groupName) {
		List EntriesList = new ArrayList();
		RosterGroup rosterGroup = roster.getGroup(groupName);
		Collection rosterEntry = rosterGroup.getEntries();
		Iterator i = rosterEntry.iterator();
		while (i.hasNext())
			EntriesList.add(i.next());
		return EntriesList;
	}

	/**
	 * 返回所有用户信息 
	 * 
	 * @return List(RosterEntry)
	 */
	public static List getAllEntries(Roster roster) {
		List EntriesList = new ArrayList();
		Collection rosterEntry = roster.getEntries();
		Iterator i = rosterEntry.iterator();
		while (i.hasNext())
			EntriesList.add(i.next());
		return EntriesList;
	}

(7)用户头像的获取

使用VCard,很强大,具体自己看API吧,可以看看VCard传回来XML的组成,含有很多信息的

[java] view plain copy print ?
  1. **
  2. *获取用户的vcard信息
  3. *@paramconnection
  4. *@paramuser
  5. *@return
  6. *@throwsXMPPException
  7. */
  8. publicstaticVCardgetUserVCard(XMPPConnectionconnection,Stringuser)throwsXMPPException
  9. {
  10. VCardvcard=newVCard();
  11. vcard.load(connection,user);
  12. returnvcard;
  13. }
  14. /**
  15. *获取用户头像信息
  16. */
  17. publicstaticImageIcongetUserImage(XMPPConnectionconnection,Stringuser){
  18. ImageIconic=null;
  19. try{
  20. System.out.println("获取用户头像信息:"+user);
  21. VCardvcard=newVCard();
  22. vcard.load(connection,user);
  23. if(vcard==null||vcard.getAvatar()==null)
  24. {
  25. returnnull;
  26. }
  27. ByteArrayInputStreambais=newByteArrayInputStream(
  28. vcard.getAvatar());
  29. Imageimage=ImageIO.read(bais);
  30. ic=newImageIcon(image);
  31. System.out.println("图片大小:"+ic.getIconHeight()+""+ic.getIconWidth());
  32. }catch(Exceptione){
  33. e.printStackTrace();
  34. }
  35. returnic;
  36. }
	**
	 * 获取用户的vcard信息
	 * @param connection
	 * @param user
	 * @return
	 * @throws XMPPException
	 */
	public static VCard getUserVCard(XMPPConnection connection, String user) throws XMPPException
	{
		VCard vcard = new VCard();
		vcard.load(connection, user);
		
		return vcard;
	}

	/**
	 * 获取用户头像信息
	 */
	public static ImageIcon getUserImage(XMPPConnection connection, String user) {
		ImageIcon ic = null;
		try {
			System.out.println("获取用户头像信息: "+user);
			VCard vcard = new VCard();
			vcard.load(connection, user);
			
			if(vcard == null || vcard.getAvatar() == null)
			{
				return null;
			}
			ByteArrayInputStream bais = new ByteArrayInputStream(
					vcard.getAvatar());
			Image image = ImageIO.read(bais);
	
			
		    ic = new ImageIcon(image);
			System.out.println("图片大小:"+ic.getIconHeight()+" "+ic.getIconWidth());
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ic;
	}

(8)组操作和用户分组操作

[java] view plain copy print ?
  1. **
  2. *添加一个组
  3. */
  4. publicstaticbooleanaddGroup(Rosterroster,StringgroupName)
  5. {
  6. try{
  7. roster.createGroup(groupName);
  8. returntrue;
  9. }catch(Exceptione){
  10. e.printStackTrace();
  11. returnfalse;
  12. }
  13. }
  14. /**
  15. *删除一个组
  16. */
  17. publicstaticbooleanremoveGroup(Rosterroster,StringgroupName)
  18. {
  19. returnfalse;
  20. }
  21. /**
  22. *添加一个好友无分组
  23. */
  24. publicstaticbooleanaddUser(Rosterroster,StringuserName,Stringname)
  25. {
  26. try{
  27. roster.createEntry(userName,name,null);
  28. returntrue;
  29. }catch(Exceptione){
  30. e.printStackTrace();
  31. returnfalse;
  32. }
  33. }
  34. /**
  35. *添加一个好友到分组
  36. *@paramroster
  37. *@paramuserName
  38. *@paramname
  39. *@return
  40. */
  41. publicstaticbooleanaddUser(Rosterroster,StringuserName,Stringname,StringgroupName)
  42. {
  43. try{
  44. roster.createEntry(userName,name,newString[]{groupName});
  45. returntrue;
  46. }catch(Exceptione){
  47. e.printStackTrace();
  48. returnfalse;
  49. }
  50. }
  51. /**
  52. *删除一个好友
  53. *@paramroster
  54. *@paramuserName
  55. *@return
  56. */
  57. publicstaticbooleanremoveUser(Rosterroster,StringuserName)
  58. {
  59. try{
  60. if(userName.contains("@"))
  61. {
  62. userName=userName.split("@")[0];
  63. }
  64. RosterEntryentry=roster.getEntry(userName);
  65. System.out.println("删除好友:"+userName);
  66. System.out.println("User:"+(roster.getEntry(userName)==null));
  67. roster.removeEntry(entry);
  68. returntrue;
  69. }catch(Exceptione){
  70. e.printStackTrace();
  71. returnfalse;
  72. }
  73. }
	**
	 * 添加一个组
	 */
	public static boolean addGroup(Roster roster,String groupName)
	{
		try {
			roster.createGroup(groupName);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 删除一个组
	 */
	public static boolean removeGroup(Roster roster,String groupName)
	{
		return false;
	}
	
	/**
	 * 添加一个好友  无分组
	 */
	public static boolean addUser(Roster roster,String userName,String name)
	{
		try {
			roster.createEntry(userName, name, null);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 添加一个好友到分组
	 * @param roster
	 * @param userName
	 * @param name
	 * @return
	 */
	public static boolean addUser(Roster roster,String userName,String name,String groupName)
	{
		try {
			roster.createEntry(userName, name,new String[]{ groupName});
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 删除一个好友
	 * @param roster
	 * @param userName
	 * @return
	 */
	public static boolean removeUser(Roster roster,String userName)
	{
		try {
			
			if(userName.contains("@"))
			{
				userName = userName.split("@")[0];
			}
			RosterEntry entry = roster.getEntry(userName);
			System.out.println("删除好友:"+userName);
			System.out.println("User: "+(roster.getEntry(userName) == null));
			roster.removeEntry(entry);
			
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		
	}

(9)用户查询

[java] view plain copy print ?
  1. publicstaticListsearchUsers(XMPPConnectionconnection,StringserverDomain,StringuserName)throwsXMPPException
  2. {
  3. Listresults=newArrayList();
  4. System.out.println("查询开始..............."+connection.getHost()+connection.getServiceName());
  5. UserSearchManagerusm=newUserSearchManager(connection);
  6. FormsearchForm=usm.getSearchForm(serverDomain);
  7. FormanswerForm=searchForm.createAnswerForm();
  8. answerForm.setAnswer("Username",true);
  9. answerForm.setAnswer("search",userName);
  10. ReportedDatadata=usm.getSearchResults(answerForm,serverDomain);
  11. Iteratorit=data.getRows();
  12. Rowrow=null;
  13. UserBeanuser=null;
  14. while(it.hasNext())
  15. {
  16. user=newUserBean();
  17. row=it.next();
  18. user.setUserName(row.getValues("Username").next().toString());
  19. user.setName(row.getValues("Name").next().toString());
  20. user.setEmail(row.getValues("Email").next().toString());
  21. System.out.println(row.getValues("Username").next());
  22. System.out.println(row.getValues("Name").next());
  23. System.out.println(row.getValues("Email").next());
  24. results.add(user);
  25. //若存在,则有返回,UserName一定非空,其他两个若是有设,一定非空
  26. }
  27. returnresults;
  28. }
public static List searchUsers(XMPPConnection connection,String serverDomain,String userName) throws XMPPException
	{
		List results = new ArrayList();
		System.out.println("查询开始..............."+connection.getHost()+connection.getServiceName());
		
		UserSearchManager usm = new UserSearchManager(connection);
		
		
        Form searchForm = usm.getSearchForm(serverDomain);
        Form answerForm = searchForm.createAnswerForm();
        answerForm.setAnswer("Username", true);
        answerForm.setAnswer("search", userName);
        ReportedData data = usm.getSearchResults(answerForm, serverDomain);
		 
		 Iterator it = data.getRows();
		 Row row = null;
		 UserBean user = null;
		 while(it.hasNext())
		 {
			 user = new UserBean();
			 row = it.next();
			 user.setUserName(row.getValues("Username").next().toString());
			 user.setName(row.getValues("Name").next().toString());
			 user.setEmail(row.getValues("Email").next().toString());
			 System.out.println(row.getValues("Username").next());
			 System.out.println(row.getValues("Name").next());
			 System.out.println(row.getValues("Email").next());
			 results.add(user);
			 //若存在,则有返回,UserName一定非空,其他两个若是有设,一定非空
		 }
		 
		 return results;
	}

(10)修改自身状态

包括上线,隐身,对某人隐身,对某人上线

[java] view plain copy print ?
  1. ublicstaticvoidupdateStateToAvailable(XMPPConnectionconnection)
  2. {
  3. Presencepresence=newPresence(Presence.Type.available);
  4. nnection.sendPacket(presence);
  5. publicstaticvoidupdateStateToUnAvailable(XMPPConnectionconnection)
  6. {
  7. Presencepresence=newPresence(Presence.Type.unavailable);
  8. nnection.sendPacket(presence);
  9. }
  10. publicstaticvoidupdateStateToUnAvailableToSomeone(XMPPConnectionconnection,StringuserName)
  11. {
  12. Presencepresence=newPresence(Presence.Type.unavailable);
  13. presence.setTo(userName);
  14. nnection.sendPacket(presence);
  15. }
  16. publicstaticvoidupdateStateToAvailableToSomeone(XMPPConnectionconnection,StringuserName)
  17. {
  18. Presencepresence=newPresence(Presence.Type.available);
  19. presence.setTo(userName);
  20. nnection.sendPacket(presence);
  21. }
	ublic static void updateStateToAvailable(XMPPConnection connection)
	{
		Presence presence = new Presence(Presence.Type.available);
        		nnection.sendPacket(presence);
     	
	
	public static void updateStateToUnAvailable(XMPPConnection connection)
	{
		Presence presence = new Presence(Presence.Type.unavailable);
        		nnection.sendPacket(presence);
    	}
	
	public static void updateStateToUnAvailableToSomeone(XMPPConnection connection,String userName)
	{
		Presence presence = new Presence(Presence.Type.unavailable);
		presence.setTo(userName);
        		nnection.sendPacket(presence);
	}
	public static void updateStateToAvailableToSomeone(XMPPConnection connection,String userName)
	{
		Presence presence = new Presence(Presence.Type.available);
		presence.setTo(userName);
        		nnection.sendPacket(presence);

	}

(11)心情修改

[java] view plain copy print ?
  1. **
  2. *修改心情
  3. *@paramconnection
  4. *@paramstatus
  5. */
  6. publicstaticvoidchangeStateMessage(XMPPConnectionconnection,Stringstatus)
  7. {
  8. Presencepresence=newPresence(Presence.Type.available);
  9. presence.setStatus(status);
  10. connection.sendPacket(presence);
  11. }
	**
	 * 修改心情
	 * @param connection
	 * @param status
	 */
	public static void changeStateMessage(XMPPConnection connection,String status)
	{
		Presence presence = new Presence(Presence.Type.available);
		presence.setStatus(status);
		connection.sendPacket(presence);
	
	}

(12)修改用户头像

有点麻烦,主要是读入图片文件,编码,传输之

[java] view plain copy print ?
  1. publicstaticvoidchangeImage(XMPPConnectionconnection,Filef)throwsXMPPException,IOException{
  2. VCardvcard=newVCard();
  3. vcard.load(connection);
  4. byte[]bytes;
  5. bytes=getFileBytes(f);
  6. StringencodedImage=StringUtils.encodeBase64(bytes);
  7. vcard.setAvatar(bytes,encodedImage);
  8. vcard.setEncodedImage(encodedImage);
  9. vcard.setField("PHOTO","image/jpg"
  10. +encodedImage+"",true);
  11. ByteArrayInputStreambais=newByteArrayInputStream(
  12. vcard.getAvatar());
  13. Imageimage=ImageIO.read(bais);
  14. ImageIconic=newImageIcon(image);
  15. vcard.save(connection);
  16. }
  17. privatestaticbyte[]getFileBytes(Filefile)throwsIOException{
  18. BufferedInputStreambis=null;
  19. try{
  20. bis=newBufferedInputStream(newFileInputStream(file));
  21. intbytes=(int)file.length();
  22. byte[]buffer=newbyte[bytes];
  23. intreadBytes=bis.read(buffer);
  24. if(readBytes!=buffer.length){
  25. thrownewIOException("Entirefilenotread");
  26. }
  27. returnbuffer;
  28. }finally{
  29. if(bis!=null){
  30. bis.close();
  31. }
  32. }
  33. }
public static void changeImage(XMPPConnection connection,File f) throws XMPPException, IOException{
	
		VCard vcard = new VCard();
		vcard.load(connection);
		
	        byte[] bytes;
	      
	            bytes = getFileBytes(f);
	            String encodedImage = StringUtils.encodeBase64(bytes);
	            vcard.setAvatar(bytes, encodedImage);
	            vcard.setEncodedImage(encodedImage);
	            vcard.setField("PHOTO", "image/jpg"
	                    + encodedImage + "", true);
	            
	            
	            ByteArrayInputStream bais = new ByteArrayInputStream(
						vcard.getAvatar());
				Image image = ImageIO.read(bais);
				ImageIcon ic = new ImageIcon(image);
				 
	       
	      
	        vcard.save(connection);
	       
	}
	
      private static byte[] getFileBytes(File file) throws IOException {
        		BufferedInputStream bis = null;
        	try {
            bis = new BufferedInputStream(new FileInputStream(file));
            int bytes = (int) file.length();
            byte[] buffer = new byte[bytes];
            int readBytes = bis.read(buffer);
            if (readBytes != buffer.length) {
                throw new IOException("Entire file not read");
            }
            return buffer;
        } finally {
            if (bis != null) {
                bis.close();
            }
        }
}

(13)用户状态的监听

即对方改变头像,状态,心情时,更新自己用户列表,其实这里已经有smack实现的监听器

[java] view plain copy print ?
  1. nalRosterroster=Client.getRoster();
  2. roster.addRosterListener(
  3. newRosterListener(){
  4. @Override
  5. publicvoidentriesAdded(Collectionarg0){
  6. //TODOAuto-generatedmethodstub
  7. System.out.println("--------EE:"+"entriesAdded");
  8. }
  9. @Override
  10. publicvoidentriesDeleted(Collectionarg0){
  11. //TODOAuto-generatedmethodstub
  12. System.out.println("--------EE:"+"entriesDeleted");
  13. }
  14. @Override
  15. publicvoidentriesUpdated(Collectionarg0){
  16. //TODOAuto-generatedmethodstub
  17. System.out.println("--------EE:"+"entriesUpdated");
  18. }
  19. @Override
  20. publicvoidpresenceChanged(Presencearg0){
  21. //TODOAuto-generatedmethodstub
  22. System.out.println("--------EE:"+"presenceChanged");
  23. }
  24. });
		nal Roster roster = Client.getRoster();
		
		roster.addRosterListener(
			new RosterListener() {

					@Override
					public void entriesAdded(Collection arg0) {
						// TODO Auto-generated method stub
						System.out.println("--------EE:"+"entriesAdded");
					}

					@Override
					public void entriesDeleted(Collection arg0) {
						// TODO Auto-generated method stub
						System.out.println("--------EE:"+"entriesDeleted");
					}

					@Override
					public void entriesUpdated(Collection arg0) {
						// TODO Auto-generated method stub
						System.out.println("--------EE:"+"entriesUpdated");
					}

					@Override
					public void presenceChanged(Presence arg0) {
						// TODO Auto-generated method stub
						System.out.println("--------EE:"+"presenceChanged");
					}   
					
		});
 
 

你可能感兴趣的:(java,即时通信)