Monday, December 14, 2009

Crud Operations with Java Web Services, Flex and Flash Builder

 

Java SE 6 has built-in support for web services thanks to JAX-WS 2.0. Using the DCD features in Flash Builder 4, a web service can be easily accessed.  We will build an end-to-end simple CRUD application in Java and Flex 4, where the Java methods are exposed as web service operations. We will take an Employee Class as an example and try to do the crud operations on it, using the Flex UI and Flash Builder 4 for deploying the web services and using it.

Create an Employee table as shown below.

CREATE TABLE `employee` (
  `emp_id` int(11) NOT NULL AUTO_INCREMENT,
  `emp_name` varchar(50) NOT NULL,
  `dept` varchar(50) NOT NULL,
  `emp_sal` int(11) NOT NULL,
  `manager` varchar(50) NOT NULL,
  PRIMARY KEY (`emp_id`)
)

The Employee POJO is shown below.

package com.adobe.objects;

public class SimpleEmployee {
   private int empId;
   private String empName;
   private String dept;
   private int empSal;
   private String manager;
   public SimpleEmployee(int id, String name, String dep, int sal,
        String mgr) {
        this.empId = id;
        this.empName = name;
        this.dept = dep;
        this.empSal = sal;
        this.manager = mgr;
    }
    public SimpleEmployee() {
    // TODO Auto-generated constructor stub
}
    public int getEmpId() {
        return empId;
    }
    public void setEmpId(int id) {
        this.empId = id;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String name) {
        this.empName = name;
    }
    public String getDept() {
        return dept;
    }
    public void setDept(String dep) {
        this.dept = dep;
    }
    public int getEmpSal() {
        return empSal;
    }
    public void setEmpSal(int sal) {
        this.empSal = sal;
    }
    public String getManager() {
        return manager;
    }
    public void setManager(String mgr) {
        this.manager = mgr;
    }

}

The Employee Service with all the operations exposed is as shown below. 

To expose your Java class as a web service, simply:

1) Annotate your Java class with @WebService, @WebMethod.

2) Use the Endpoint class in main()

EmployeeService.Java

package com.adobe.services;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Endpoint;

import com.adobe.objects.SimpleEmployee;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)

public class SimpleEmployeeService
{
    public SimpleEmployeeService()
    {
    }
     @WebMethod
    public int addEmployee(SimpleEmployee emp)
    {
        int createdEmpId= 0;
        Connection connection = null;

        if(emp == null)
        {
            throw new IllegalArgumentException("Employee object is invalid");
        }
        int empId = emp.getEmpId();
        String empName = emp.getEmpName();
        String dept = emp.getDept();
        int sal = emp.getEmpSal();
        String manager = emp.getManager();
        if(empName == null ||
                dept == null ||
                manager == null)
        {
            throw new IllegalArgumentException("employee object is invalid");
        }
        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("INSERT INTO employee (" +
                        "emp_id, emp_name, dept,emp_sal,manager) " +
                        "VALUES(?,?,?,?,?)");
            statement.setInt(1, empId);
            statement.setString(2, empName);
            statement.setString(3, dept);
            statement.setInt(4, sal);
            statement.setString(5,manager);
            int rowCount = statement.executeUpdate();

            if(rowCount == 1)
            {
                ResultSet rs = statement.getGeneratedKeys();
                if(rs.next())
                {
                    createdEmpId = rs.getInt(1);
                }
            }
        }
        catch(MySQLIntegrityConstraintViolationException multipleEntryException)
        {
            //duplicate entry found
            throw new RuntimeException("Employee entry already exists");
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }       
        return createdEmpId;
    }
     @WebMethod

    public void updateEmployee(SimpleEmployee emp)
    {
        Connection connection = null;

        if(emp == null)
        {
            throw new IllegalArgumentException("Employee object is invalid");
        }

        int empId = emp.getEmpId();
        String empName = emp.getEmpName();
        String dept = emp.getDept();
        int sal = emp.getEmpSal();
        String manager = emp.getManager();
        if(empName == null ||
                dept == null ||
                empId <= 0 ||
                manager == null)
        {
            throw new IllegalArgumentException("Employee object is invalid");
        }
        //update customer address
        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("UPDATE employee SET " +
                        "emp_name = ?," +
                        "dept = ?, " +
                        "manager = ?," +
                        "emp_sal = ? " +
                        "WHERE emp_id = ?");
            statement.setString(1, empName);
            statement.setString(2, dept);
            statement.setString(3, manager);
            statement.setInt(4, sal);
            statement.setInt(5, empId);
            statement.executeUpdate();

        }
        catch(MySQLIntegrityConstraintViolationException multipleEntryException)
        {
            //duplicate entry found
            throw new RuntimeException("Employee entry already exists");
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }               
    }
     @WebMethod
    public boolean deleteEmployee(SimpleEmployee emp)
    {
        boolean result = false;
        Connection connection = null;
        if(emp == null)
        {
            throw new IllegalArgumentException("Employee instance  is invalid");
        }
        int empId = emp.getEmpId();

        if(empId <= 0)
        {
            throw new IllegalArgumentException("Employee id is invalid");
        }

        try
        {
            connection = getConnection();
            PreparedStatement employeeStatement;

            employeeStatement = connection.prepareStatement("DELETE FROM employee WHERE emp_id = ?");
            employeeStatement.setInt(1, empId);
            int rowCount = employeeStatement.executeUpdate();
            if(rowCount == 1)
            {
                result = true;
            }   
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }       
        return result;
    }
     @WebMethod
    public SimpleEmployee getEmployee(int empId)
    {
        SimpleEmployee result = null;
        Connection connection = null;

        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("SELECT * FROM employee WHERE emp_id = ?");
            statement.setInt(1, empId);
            ResultSet rs = statement.executeQuery();
            ArrayList<SimpleEmployee> emps = createEmployeesFromRS(rs);
            if(emps != null && emps.size() > 0 )
            {
                result = emps.get(0);
            }
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }               

        return result;
    }
    public int getEmployeesCount()
    {
        int result = 0;
        SimpleEmployee[] emps = getAllEmployees();
        if(emps != null)
        {
            result = emps.length;
        }
        return result;
    }

    public ArrayList<SimpleEmployee> getEmployeePaged(int startIndex, int numberOfRows)
    {
        ArrayList<SimpleEmployee> employees = new ArrayList<SimpleEmployee>();
        Connection connection = null;

        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("SELECT * FROM employees LIMIT ?, ?");
            statement.setInt(1, startIndex);
            statement.setInt(2, numberOfRows);
            ResultSet rs = statement.executeQuery();
            employees = createEmployeesFromRS(rs);
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }               
        return employees;
    }

    @WebMethod
    public SimpleEmployee[] getAllEmployees()
    {
        ArrayList<SimpleEmployee> employees = new ArrayList<SimpleEmployee>();
        Connection connection = null;

        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("SELECT * FROM employee");
            ResultSet rs = statement.executeQuery();
            employees = createEmployeesFromRS(rs);
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }               
        int len = employees.size();
        SimpleEmployee[] emps = new SimpleEmployee[len];
        employees.toArray(emps);
        return emps;
    }

    private ArrayList<SimpleEmployee> createEmployeesFromRS(ResultSet rs)throws Exception
    {
        ArrayList<SimpleEmployee> emps = new ArrayList<SimpleEmployee>();
        SimpleEmployee emp;
        while(rs.next())
        {
            emp = new SimpleEmployee();
            emp.setEmpId(rs.getInt("emp_id"));
            emp.setEmpName(rs.getString("emp_name"));
            emp.setDept(rs.getString("dept"));
            emp.setEmpSal(rs.getInt("emp_sal"));
            emp.setManager(rs.getString("manager"));
            emps.add(emp);
        }       
        return emps;
    }
    private Connection getConnection()throws Exception
    {
        Connection connection = null;
         try
            {
                Class.forName("org.gjt.mm.mysql.Driver").newInstance();
            }
            catch (Exception e)
            {
                throw e;
            }

            try
            {
                connection = DriverManager.getConnection(
                  "jdbc:mysql://localhost/" + "empdb", "root","");
            }
            catch (SQLException sqlException)
            {
                throw sqlException;
            }       
        return connection;       
    }
    public static void main(String[] args)
    {
        // create and publish an endpoint
        SimpleEmployeeService empService = new SimpleEmployeeService();
        Endpoint endpoint = Endpoint.publish("http://localhost:8080/employee", empService);
    }

}

Create a directory called generated and run apt (Annotation Processing Tool):

apt -cp .;mysql.jar -d generated com\adobe\services\EmployeeService.java
Run your class: java -cp generated;mysql.jar com.adobe.services.EmployeeService


That's it, you have a web server running on localhost:8080 and you can access the WSDL by navigating to http://localhost:8080/employee?wsdl



Now the FlashBuilder will do the rest.




  1. Create a new Flex Project, type in a project name and hit Finish.


  2. In the bottom part of Flash Builder, choose the Data/Services tab and click on "Connect to Data/Service".


  3. Pick Web Service, hit Next.


  4. Paste the WSDL URL http://localhost:8080/employee?wsdl as the "WSDL URI" and hit Finish.


  5. Flash Builder 4 will verify the WSDL and show you a list of operations you can select. Hit Finish.



The Flex code is as shown below. You can generate this with just few clicks in the Flash Builder.



<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo"


    minWidth="1024" minHeight="768" xmlns:employee="services.employee.*" xmlns:valueObjects="valueObjects.*">


    <fx:Script>


     <![CDATA[


            import mx.events.FlexEvent;


            import mx.controls.Alert;


            import spark.events.IndexChangeEvent;


            protected function list_creationCompleteHandler(event:FlexEvent):void


            {


                getAllEmployeesResult.token = employee.getAllEmployees();


                getAllEmployeesResult2.token = employee.getAllEmployees();


            }


            protected function list_changeHandler(event:IndexChangeEvent):void


            {


                simpleEmployee = list.selectedItem as SimpleEmployee;


            }


            protected function button_clickHandler(event:MouseEvent):void


            { 
                addEmployeeResult.token = employee.addEmployee(simpleEmployee);


            }


            protected function button2_clickHandler(event:MouseEvent):void


            {


                updateEmployeeResult.token = employee.updateEmployee(simpleEmployee);


            }


            protected function button3_clickHandler(event:MouseEvent):void


            {


                deleteEmployeeResult.token = employee.deleteEmployee(simpleEmployee);


            }


            protected function button4_clickHandler(event:MouseEvent):void


            {


                list_creationCompleteHandler(null);


            }


        ]]>


    </fx:Script>


    <fx:Declarations>


        <s:CallResponder id="getAllEmployeesResult"/>


        <employee:Employee id="employee" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>


        <s:CallResponder id="getAllEmployeesResult2"/>


        <valueObjects:SimpleEmployee id="simpleEmployee" empId="{parseInt(empIdTextInput.text)}" empSal="{parseInt(empSalTextInput.text)}"/>


        <s:CallResponder id="addEmployeeResult" result="list_creationCompleteHandler(null)"/>


        <s:CallResponder id="updateEmployeeResult" result="list_creationCompleteHandler(null)"/>


        <s:CallResponder id="updateEmployeeResult2" result="list_creationCompleteHandler(null)"/>


        <s:CallResponder id="deleteEmployeeResult" result="list_creationCompleteHandler(null)"/>


        <s:CallResponder id="getEmployeeResult"/>


    </fx:Declarations>


    <s:Panel title="Employees" x="61" y="78" width="124" height="387">


        <s:List id="list" x="0" y="10" width="100%" height="100%" borderVisible="false" creationComplete="list_creationCompleteHandler(event)" dataProvider="{getAllEmployeesResult2.lastResult}" labelField="empName" change="list_changeHandler(event)"></s:List>


    </s:Panel>


    <s:Panel title="Employee Info" x="193" y="78" width="379" height="387">


        <mx:Form x="0" y="10" width="377" height="300">


            <mx:FormItem label="Dept">


                <s:TextInput id="deptTextInput" text="@{simpleEmployee.dept}"/>


            </mx:FormItem>


            <mx:FormItem label="EmpId">


                <s:TextInput id="empIdTextInput" text="{simpleEmployee.empId}"/>


            </mx:FormItem>


            <mx:FormItem label="EmpName">


                <s:TextInput id="empNameTextInput" text="@{simpleEmployee.empName}"/>


            </mx:FormItem>


            <mx:FormItem label="EmpSal">


                <s:TextInput id="empSalTextInput" text="{simpleEmployee.empSal}"/>


            </mx:FormItem>


            <mx:FormItem label="Manager">


                <s:TextInput id="managerTextInput" text="@{simpleEmployee.manager}"/>


            </mx:FormItem>


        </mx:Form>


        <s:HGroup x="66" y="309" height="46" verticalAlign="middle" contentBackgroundColor="#938F8F">


            <s:Button label="Add" id="button"   click="button_clickHandler(event)"/>


            <s:Button label="Update" id="button2"  click="button2_clickHandler(event)"/>


            <s:Button label="Delete" id="button3"  click="button3_clickHandler(event)"/>


            <s:Button label="Get" id="button4"   click="button4_clickHandler(event)"/>


        </s:HGroup>


    </s:Panel>


</s:Application>

No comments: