Friday, November 18, 2016

Read excel file from Apache POI (XLS or XLSX format)

In this post I'm going to demonstrate how to read excel file content from Apache POI library. When consider about Microsoft Excel there are two main versions in excel files. One is XLS format which results excel files save on Excel 1997-2003 format and other one is XLSX format which results excel files save Excel workbook format. To read these two formats we need to implement it in two different ways. I'll explain both ways in this post.

Prerequisites 
  1. You should have install java 1.7.
  2. You should have Eclipse installed in your PC.
  3. Your PC should setup Maven installed and configured.

First lets create maven project in Eclipse. Go to File -> New -> Maven Project then tick the check fox for the Create Simple Project (Skip archetype selection) as show on below figure and then click next. On next screen just provide some name for Group ID and Artifact ID then click finished.



First of all we need to add Apache POI dependencies in to project. (https://poi.apache.org/download.html from this link you can get latest version details. For this post I'll use current latest version which is 3.15)  Then add following dependencies for your POM.xml file. This should be based on the file format you are going to read as mentioned in below.

For excel format XLS (1997-2003)
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.15</version>
</dependency>

For excel format XLSX(Workbook)

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.15</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.15</version>
</dependency>

Following main class can be used to read a excel file specified path.


package com.sample;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelReader {

public static void main(String[] args) {
try {
String excelFilePath = "src/main/java/com/sample/Orders.xlsx";  
FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
System.out.println(excelFilePath);
Workbook workbook = getRelevantWorkbook(inputStream, excelFilePath);
Sheet firstSheet = workbook.getSheetAt(0);
       Iterator<Row> iterator = firstSheet.iterator();
        
       while (iterator.hasNext()) {
           Row nextRow = iterator.next();
           Iterator<Cell> cellIterator = nextRow.cellIterator();
           while (cellIterator.hasNext()) {
               Cell cell = cellIterator.next();
               switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue());
break;
default:
break;
}
               System.out.print(" ");
           }
           System.out.println();
       }
        
       workbook.close();
       inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static Workbook getRelevantWorkbook(FileInputStream inputStream, String excelFilePath) throws IOException
{
   Workbook workbook = null;
 
   if (excelFilePath.endsWith("xls")) {
       workbook = new HSSFWorkbook(inputStream);
   } else if (excelFilePath.endsWith("xlsx")) {
       workbook = new XSSFWorkbook(inputStream);
   } else {
       throw new IllegalArgumentException("Incorrect file format");
   }
 
   return workbook;
}

}

I will create excel file with following contents to read from our application.



When you run the main class you will be able to get similar output to below figure,



You can access sample project from following GIT hub location.  




Friday, November 11, 2016

Create simple Web service using CXF and deploy to FUSE

In this post I'm going to show how to develop CXF web service and step by step guide to deploy it to the JBoss FUSE server. While I'm learning the stuff it gave me little bit frustration due to the lack of resources to learn this technology as a beginner. Then I though to put it as blog post so in future any one can refer the guide line.

Prerequisites 
  1. You should have install java 1.8 to support latest jboss-fuse-6.3.0
  2. You should have install JBoss Developer studio
  3. Your PC should setup Maven installed and configured.


01) Lets create the FUSE CXF project

First open the JBoss Developer Studio and go to File-> New -> Fuse Integration Project. Then provide the project name.


Figure 1: Provide the project name


Then select the run time environment of the Fuse server then click next. This should be setup in your JBoss Developer studio. If not you have to setup new run time environment by click on new button.

Figure 2: Select the run time environment

On next interface you have to select "Start with an empty project" and "Spring DSL" as show on below figure.

Figure 3: Select "Start with empty project" and "Spring DSL" as project type
Then click finish and it will take some time to create the project in Development studio. Please note that some times IDE get unresponsive as well. Then you will be able to see similar interface to below figure.

Figure 4: New project interface

Then right click on the "main" folder under src folder and then go to new->Folder, set folder name as "java". Then right click on the java folder and then go to new->Interface. Then provide the name for the service in my demo I'll give as "DemoOrderService" and package as "com.demo.order" then click finish. (show in below figure)

Figure 5: Interface for the service

Then again add two classes in to "java" folder as "Input" and "Output" as show on below figure.

Figure 5: Add DemoOrderSerice interface and Input and Output classes

Then add following content in to Input class.

package com.demo.order;

public class Input {
private String fName;
private String lName;
private String age;
private String country;
public String getfName() {
return fName;
}
public void setfName(String fName) {
this.fName = fName;
}
public String getlName() {
return lName;
}
public void setlName(String lName) {
this.lName = lName;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}


Add following content in to Output class.


package com.demo.order;

public class Output {
private String name;
private String status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}


And add following content in to the DemoOrderService interface.

package com.demo.order;

public interface DemoOrderService {
Output provideOrder(Input input);
}


Then double click on the "camel-context.xml" file in the "src\main\resources\META-INF\spring\" directory. Then click on the source section as show in below figure.

Figure 6: Click on the source section as show in above

Then update the beans declaration as below. I have added bold section in to the bean definition.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:cxf="http://camel.apache.org/schema/cxf"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd        
    http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd        
    http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd    ">

Then add following section just after the beans definition,to define the web service in our application.

<cxf:cxfEndpoint address="http://localhost:9292/cxf/order"
        id="demoOrderEndpoint" serviceClass="com.demo.order.DemoOrderService"/>

Then inside the camel-context delete the existing content and add following content

        <route id="cxf">
            <!-- route starts from the cxf webservice in POJO mode -->
            <from id="demoOrderEndpointListener" uri="cxf:bean:demoOrderEndpoint"/>
            <recipientList id="dispatchToCorrectRoute">
                <simple>direct:${header.operationName}</simple>
            </recipientList>
        </route>


Then add the following route details after that. In here direct:provideOrder refer to the provideOrder method in the service interface.


        <route id="Order">
            <from id="statusIncidentStarter" uri="direct:provideOrder"/>
            <log id="logStatusIncident" message="OrderDetails Call"/>
        </route>

Then right click on the java folder and add new class call "OrderProcessor" add following content in to that class. Note that this class should be extend org.apache.camel.Processor class and should override the process method.

package com.demo.order;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class OrderProcessor  implements Processor {

@Override
public void process(Exchange exchange) throws Exception {
Input input = exchange.getIn().getBody(Input.class);
Output output=new Output();
output.setName(input.getfName()+" "+input.getlName());
output.setStatus("OK");
exchange.getOut().setBody(output);
}

}


Then add this bean in to camel-context.xml before the beans declaration.

    <bean
        class="com.demo.order.OrderProcessor" id="orderProcessor"/>

Then update the Order route as below in there we refer the bean which we defined on above step by id on the bean definition.

        <route id="Order">
            <from id="statusIncidentStarter" uri="direct:provideOrder"/>
            <log id="logStatusIncident" message="OrderDetails Call"/>
            <process ref="orderProcessor"/>
        </route>

Whole camel context.xml will have following content.

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

<!-- Configures the Camel Context-->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:cxf="http://camel.apache.org/schema/cxf"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd        
    http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd        
    http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd    ">
    
    <cxf:cxfEndpoint address="http://localhost:9292/cxf/order"
        id="demoOrderEndpoint" serviceClass="com.demo.order.DemoOrderService"/>
    <bean
        class="com.demo.order.OrderProcessor" id="orderProcessor"/>
        
    <camelContext id="_camelContext1" xmlns="http://camel.apache.org/schema/spring">
        <route id="cxf">
            <!-- route starts from the cxf webservice in POJO mode -->
            <from id="demoOrderEndpointListener" uri="cxf:bean:demoOrderEndpoint"/>
            <recipientList id="dispatchToCorrectRoute">
                <simple>direct:${header.operationName}</simple>
            </recipientList>
        </route>
        <route id="Order">
            <from id="statusIncidentStarter" uri="direct:provideOrder"/>
            <log id="logStatusIncident" message="OrderDetails Call"/>
            <process ref="orderProcessor"/>
        </route>
    </camelContext>
</beans>



Now we have completed the development of our Demo service lets build our application and deploy it in to the Fuse server.

Then go to the project root directory using command line and then enter following command.

mvn clean install

Then you will see the build success message and then open the FUSE console by double click on the  fuse.bat file. Then install our application in fuse server by type and enter following command. 

osgi:install -s mvn:com.mycompany/camel-spring/1.0.0-SNAPSHOT

Then go to the http://localhost:8181/cxf/ URL then you will be able to see similar interface to below figure. (http://localhost:9292/cxf/order?wsdl this will be the our service wsdl according to the configurations) 


Then lets test our web service on SOAP UI. Open the SOAP UI interface and go to New -> New SOAP Project. Provide a name for the project and provide wsdl as http://localhost:9292/cxf/order?wsdl. (Please refer below figure)

Figure 8: New SOAP project

Then double click on the request node on left panel under the

Figure 8: SOAP UI project request and response.

You can access the code from following link on GIT repository.