ZK And JAX WS
Nushree Allie-Cader, Java Developer, Effective Intelligence
February 21, 2012
ZK 5.0.10
Introduction
This article is aimed at showing a very simple way to integrate JAX-WS with ZK. The basis to do so is by providing a login screen with authentication and authorization being performed via webservice interaction with the back end ejb.
The session handling is based on the Small Talk: Handling the Login Process using ZK MVC and Sessions[1]
Preface
Netbeans 6.9.1 was the IDE of choice for the project as well as Glassfish v3.1.
JAXB 2.2( JAXB 2.2 and JAXB-ENDORCED are both shipped with Netbeans as a library) is the only other external library required to run this application.
In order to clearly show the steps required to use JaxWS with ZKOSS, the code base for this SmallTalk are split into 3 components
- The ZKOSS Front End
- The JavaEE Backend used to create the webservice
- The JavaSE application containing JaxB objects
The Process
Creation of webservices from existing EJB's was selected for this application. JAXB was used to handle the xml interaction for its simplicity in this context. The corresponding WSDL was then created directly in the EJB project.
- Firstly the ZKOSS screens were created using ZK EE 5.0.10.
- Controllers for the corresponding screens are then created using Java directly.
The xsd's were created and then the JavaSE application was created in order to retain JaxB objects.
- The JavaSE application needs to be built and included in the application as a jar.
- If Glassfish is being used, it is advisable to place the JavaSE application jar directly in the server domain lib and access it from there in further references.
The EJB project is then created to handle the database interactions for user authentication and authorization.
- The xml marshalling and unmarshalling is handled here on receipt of web service interaction.
- Finally, the webservice itself is created from the existing EJB exposed methods and a WSDL is generated and the EJB is deployed.
(In order to successfully run this application, the WSDL url needs to be set correctly)
The last step is to make the ZK application into a new webservice client.
- Import the WSDL and thereby access to the exposed methods is granted.
- Include the JavaSE application jar as a library
- Calls to the webservice methods can now take place within the controller classes or DAO's.
The login.zul
The LoginController.java
The controller will interact with the UserCredentialManager at this point the only thing that the controller will handle is ensuring that the required input (username and password) is not blank.
/**
* On click of the login button, doLogin method will execute
* @param event
*/
public void onClick$loginButton(Event event) {
doLogin();
}
/**
* Method that will initiate the login action
* Input values are taken from front end and passed to the manager for processing
*/
private void doLogin() {
UserCredentialManager mgmt = UserCredentialManager.getIntance(Sessions.getCurrent());
//add checks to ensure that no empty data is passed to the backend for processing
mgmt.login(usernameTxtbox.getValue().trim(), passwordTxtbox.getValue().trim());
if (mgmt.isAuthenticated()) {
execution.sendRedirect("index1.zul");
} else {
mesgLbl.setValue("The UserName or Password provided is invalid.");
}
}
The UserCredentialManager.java
The UserCredentialManager will ensure that the session is current. Login method of the manager is executed on click of Login button. The input is mashalled to xml and web service call is made Output of webservice call is unmarshalled and User model is set with permissions and associated information, if required, derived from the xml output
public synchronized void login(String username, String password) {
try {
//make the xml for the service
ServiceRequest srq = new ServiceRequest(new ServiceRequest.RequestData(username, password));
String xmlInput = XmlHandler.constructGenericServiceResultXml(ServiceRequest.class, srq);
//call the web service that will handle the authentication and authorization
String xmlOutput = verifyAndGetPermissions(xmlInput);
//get the result from the call
ServiceResult sres = (ServiceResult) XmlHandler.unMarshallObjectFromXML(ServiceResult.class, xmlOutput);
if (sres.getServiceStatus().getStatusCode().equalsIgnoreCase("100")) {
User tempUser = new User(username, password, sres.getRequestResult().getPermissions());
tempUser.setRemoteAddy(Executions.getCurrent().getSession().getRemoteAddr());
tempUser.setRemoteHost(Executions.getCurrent().getSession().getRemoteHost());
user = tempUser;
//setting userinfo as a global attrib
Executions.getCurrent().getSession().setAttribute("userInfo", user);
} else {
//error occured
user = null;
}
} catch (Exception ex) {
Logger.getLogger(UserCredentialManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
By making the ZK application a new web service client, we are able to import a selected WSDL. Once the WSDL import has completed, the ZK application has access to the exposed methods.
/**
* This is the webservice call
* created after the import of wsdl
* @param xmlInput
* @return String xmlOuput
*/
private static String verifyAndGetPermissions(java.lang.String xmlInput) {
com.ei.webui.service.ZKSmallTalk service = new com.ei.webui.service.ZKSmallTalk();
com.ei.webui.service.SmallTalkSample port = service.getSmallTalkSamplePort();
return port.verifyAndGetPermissions(xmlInput);
}
The UserAccessEJB.java
The UserAccessEJB will be used to interact with a secure database and will be turned into our webservice. The method selected to be exposed will be able to perform all authentication and authorization for user login.
/**
* This method performs verification and access allocation
* <br>After decryption and unmarshalling of xml, credential validity and permission verification occurs
* Output is xml as string containing on success permissions for user else a fail status.</br>
* @param String xmlInput
* @return String xmlOutput
*/
@Override
public String verifyAndGetPermissions(String xmlInput) {
String output = "";
try {
//first format the string to object
ServiceRequest sr = (ServiceRequest) XmlHandler.unMarshallObjectFromXML(ServiceRequest.class, xmlInput);
//do the verifications
boolean isValid = isUserCredentialValid(sr.getRequestData().getUsername(), sr.getRequestData().getPassword());
if (isValid) {
//get the permissions
List<PermissionModel> permissionList = getPermissionList(sr.getRequestData().getUsername());
List<Permissions> xmlPermissions = new ArrayList<Permissions>();
//testing
for (PermissionModel p : permissionList) {
//populate the final model for output even if the list is empty, still successful verification
Permissions permXml = new Permissions(p.getPersmission(), p.getPermissionId());
xmlPermissions.add(permXml);
}
//set status code successful
ServiceResult reqRes = new ServiceResult(new ServiceStatus("100", "Operation Successful"), new ServiceResult.RequestResult(xmlPermissions));
//marshall it
output = XmlHandler.constructGenericServiceResultXml(ServiceResult.class, reqRes);
} else {
//send back status that reads credentails are invalid
ServiceResult reqRes = new ServiceResult(new ServiceStatus("200", "User Credentials Invalid"), new ServiceResult.RequestResult());
//marshall it
output = XmlHandler.constructGenericServiceResultXml(ServiceResult.class, reqRes);
}
} catch (Exception e) {
e.printStackTrace();
//populate the output with blank stubs and exception status
//never send back nothing! poor loney users
ServiceResult reqRes = new ServiceResult(new ServiceStatus("99", "Operation Failed"), new ServiceResult.RequestResult());
try {
//marshall it
output = XmlHandler.constructGenericServiceResultXml(ServiceResult.class, reqRes);
} catch (Exception ex) {
Logger.getLogger(UserAccessEJB.class.getName()).log(Level.SEVERE, null, ex);
}
}
return output;
}
References
Downloads
- Full SmallTalk Code at SourceForge EI_ZKSmallTalk.7z
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |