本文是接前篇而写,所以一些前面讲过的东西在这里不再重复。想了解的,直接看前篇。
在这里我们要讲的是如何创建一个带有密码认证的“群”。首先,我们要明白在JXTA中,其中最大的一个特点就是提供共享服务。而身份认证也是其中一种服务,因为在JXTA中已经实现一些基础的服务。而密码服务也已经实现,只是在利用NetGroup创建新的对等组时,其提供的默认的身份认证的服务,是没有认证,即NoneMembershipService,看到这里想来大家也有点明白了,想要实现密码服务,就是把对等组中提供中的默认NoneMembershipService服务,替换成PasswdMembershipService,即可。然后我们把其包含中对等组广告中,还有别忘记了把用户名和密码包含在对等组广告中。以加入者想加入该对等组时进行确认,通过密码认证则通过,不通过,那就不让你登堂入室了。
因为这篇是“JXTA中通过身份认证来加入“群””的后续,所以我只是把创建密码对等组的代码贴出来。只要添加到前篇代码中即可。
//创建带有用户名和密码的“群”
private PeerGroup createPeerGroup(PeerGroup netpg, String groupName,
String login, String passwd) {
//创建该对等组必须要做到以下3点:
//1、创建一个对等组模块实现广告并发布它
//2、创建一个对等组广告并发布它
//3、返回一个对等组对象,它是通过2中的对等组广告来创建的。
PeerGroup tpg = null;
PeerGroupAdvertisement spgAdv ;
//创建对等组模块实现广告
ModuleImplAdvertisement passwdMsMIAdv = createPasswdMembershipPeerGroupModuleImplAdv(netpg);
//在当前对等组发布对等组模块实现广告
DiscoveryService netpgSer = netpg.getDiscoveryService();
try {
netpgSer.publish(passwdMsMIAdv);
netpgSer.remotePublish(passwdMsMIAdv);
} catch (Exception e) {
System.out.println("发布密码关系服务模块实现失败");
System.exit(-1);//退出系统
}
//创建对等组广告
spgAdv = createPeerGroupAdvertisement(passwdMsMIAdv,groupName,login,passwd);
//在父对等组中发布
try {
netpgSer.publish(spgAdv);
netpgSer.remotePublish(spgAdv);
} catch (IOException e) {
System.out.println("发布目标对等组广告失败");
System.exit(-1);
}
//最后创建目标对等组
if(null==spgAdv){
System.err.println("目标对等组广告为空");
}
try {
tpg = netpg.newGroup(spgAdv);
} catch (PeerGroupException e) {
System.out.println("通过对待组广告没有创建目标对等组");
e.printStackTrace();
}
return tpg;
}
private PeerGroupAdvertisement createPeerGroupAdvertisement(
ModuleImplAdvertisement passwdMsMIAdv, String groupName,
String login, String passwd) {
//使用广告工厂创建一个对等组广告
PeerGroupAdvertisement spgAdv = (PeerGroupAdvertisement)AdvertisementFactory.newAdvertisement(PeerGroupAdvertisement.getAdvertisementType());
//在这里使用的是每次都用新的PID代替,当然你也可以使用固定PID,这样每次开始PrivateGroup都产生同一个对等组。
spgAdv.setPeerGroupID(satellaPID);
spgAdv.setModuleSpecID(passwdMsMIAdv.getModuleSpecID());
spgAdv.setName(groupName);
spgAdv.setDescription("对等组使用密码认证");
//现在创建一个结构文档包含用户名和密码信息。用户名和密码加到对等组"Parm"标签中
if(null!=login){
StructuredTextDocument loginAndPasswd = (StructuredTextDocument)StructuredDocumentFactory.newStructuredDocument(new MimeMediaType("text/xml"), "Parm");
String loginAndPasswdString = login+":"+PasswdMembershipService.makePsswd(passwd)+":";
TextElement loginElement = loginAndPasswd.createElement("login",loginAndPasswdString);
loginAndPasswd.appendChild(loginElement);
//创建好包含有用户名和密码的结构文档,现在我们就把它放到对等组广告中
spgAdv.putServiceParam(PeerGroup.membershipClassID, loginAndPasswd);
}
return spgAdv;
}
private ModuleImplAdvertisement createPasswdMembershipPeerGroupModuleImplAdv(
PeerGroup netpg) {
//通过密码关系服务创建一个模块实现广告
//复制一个默认对等组实现广告作为模块实现参数,这样比重新创建一个模块实现广告要容易的多
//我们在这里需要做的就是把关系服务类型从默认类型改为密码关系服务类型
//说白了就是更新对等组所有实现广告中包含的关系服务类型,代码中就是更新AllPurposePeerGroupImplAdvertisement中的membership
//即替换换AllPurposePeerGroupImplAdvertisement中的NoneMembershipService,改变成PasswdMembershipService
ModuleImplAdvertisement apAdv = null;
try {
apAdv = netpg.getAllPurposePeerGroupImplAdvertisement();//获得对等组提供的所有实现广告,即是说对等组所有的服务广告都包含在这里
} catch (Exception e) {
System.out.println("执行复制默认对等组实现广告失败");
System.exit(-1);
}
ModuleImplAdvertisement passwdMembershipPeerGroupModuleImplAdv = apAdv;
ModuleImplAdvertisement passwdMembershipServiceModuleImplAdv = null;
StdPeerGroupParamAdv passwdMembershipPeerGroupParamAdv = null;
try {
passwdMembershipPeerGroupParamAdv = new StdPeerGroupParamAdv(apAdv.getParam());
} catch (Exception e) {
System.out.println("执行上面语句失败");
System.exit(-1);
}
Map apMap = passwdMembershipPeerGroupParamAdv.getServices();
Set set = apMap.keySet();
Iterator iter = set.iterator();
boolean msFound = false;
while(!msFound&&iter.hasNext()){
Object apGSID = iter.next();
if(apGSID.equals(PeerGroup.membershipClassID)){
//默认对等组关系服务实现广告是所有关系服务实现广告的集合,我们在这里要找是的密码关系服务实现广告
ModuleImplAdvertisement apgAdv = (ModuleImplAdvertisement)apMap.get(apGSID);
//创建密码关系服务模块实现广告
passwdMembershipServiceModuleImplAdv = createPasswdMembershipServiceModuleImplAdv(apgAdv);
//删除所有目标关系服务实现
apMap.remove(apGSID);
//用密码关系服务实现来代替默认的关系服务实现,即把对等组关系服务类型改变了,改成密码关系服务类型
apMap.put(PeerGroup.membershipClassID, passwdMembershipServiceModuleImplAdv);
msFound = true;
//现在密码关系服务广告已经完成。让我们通过参数更新,更新关系对等组模块实现广告
passwdMembershipPeerGroupModuleImplAdv.setParam((Element)passwdMembershipPeerGroupParamAdv.getDocument(MimeMediaType.XMLUTF8));
//更新模块实现广告SPID
if(!passwdMembershipPeerGroupModuleImplAdv.getModuleSpecID().equals(PeerGroup.allPurposePeerGroupSpecID)){//如果SpecID=原本的SPID,即没有变,则IDFactory生成一个新的SPID
passwdMembershipPeerGroupModuleImplAdv.setModuleSpecID(IDFactory.newModuleSpecID(passwdMembershipPeerGroupModuleImplAdv.getModuleSpecID().getBaseClass()));
}else{
ID passwdGrpModSpecID = ID.create(URI.create("urn:"+"jxta:uuid-"+"DeadBeefDeafBabaFeedBabe00000001"+"04"+"06"));
passwdMembershipPeerGroupModuleImplAdv.setModuleSpecID((ModuleSpecID)passwdGrpModSpecID);
}
msFound = true;
}
}
return passwdMembershipPeerGroupModuleImplAdv;
}
/**
* 使用到默认模块实现广告中的一些值,而更新SpecID和class及描述,得到一个新的模块实现广告
* @param apgAdv 默认模块实现广告,即getAllPurposePeerGroupImplAdvertisement
* @return
*/
private ModuleImplAdvertisement createPasswdMembershipServiceModuleImplAdv(
ModuleImplAdvertisement apgAdv) {
//为关系服务创建一个新的模块实现广告
ModuleImplAdvertisement passwdMembershipServiceModuleImplAdv = (ModuleImplAdvertisement)AdvertisementFactory.newAdvertisement(ModuleImplAdvertisement.getAdvertisementType());
passwdMembershipServiceModuleImplAdv.setModuleSpecID(PasswdMembershipService.passwordMembershipSpecID);//密码关系服务ID
passwdMembershipServiceModuleImplAdv.setCode(PasswdMembershipService.class.getName());//得到密码关系服务类名称
passwdMembershipServiceModuleImplAdv.setDescription("为关系服务而创建的模块实现广告");//更新模块实现广告描述
passwdMembershipServiceModuleImplAdv.setCompat(apgAdv.getCompat());
passwdMembershipServiceModuleImplAdv.setUri(apgAdv.getUri());
passwdMembershipServiceModuleImplAdv.setProvider(apgAdv.getProvider());
return passwdMembershipServiceModuleImplAdv;
}