本文是接前篇而寫,是以一些前面講過的東西在這裡不再重複。想了解的,直接看前篇。
在這裡我們要講的是如何建立一個帶有密碼認證的“群”。首先,我們要明白在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;
}
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;
}