ZK And JAX WS

From Documentation
ZK And JAX WS

Author
Nushree Allie-Cader, Java Developer, Effective Intelligence
Nushree.jpg
"Nushree graduated from London Met University with BSc Hons in Computer Science and Information Systems. She lectured in Computer Studies and moved to the mobile tech sector participating in Marketing campaigns, data mining and development of web applications for well known Digital Media Houses. She worked in the medical sector and middleware solutions for a large South African Medical Scheme administrator. She is now Head Java developer at Effective Intelligence working directly with the developments heads to design and implement of their architecture."

Date
February 21, 2012
Version
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

  1. The ZKOSS Front End
  2. The JavaEE Backend used to create the webservice
  3. 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

Login.png

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.

Webserviceclient.png

/**
 * 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

Comments



Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.