• Enter Slide 1 Title Here

    This is slide 1 description. Go to Edit HTML of your blogger blog. Find these sentences. You can replace these sentences with your own words.

  • Enter Slide 2 Title Here

    This is slide 2 description. Go to Edit HTML of your blogger blog. Find these sentences. You can replace these sentences with your own words.

  • Enter Slide 3 Title Here

    This is slide 3 description. Go to Edit HTML of your blogger blog. Find these sentences. You can replace these sentences with your own words.

Thursday, July 31, 2008

Java: Numbers only String by removing non numeric characters

With Java, deleting non numeric characters (letters, symbols etc) from a string to produce a numbers-only String is a common requirement in web applications, as application users are used to insert numeric values with non-numeric characters.

For example a phone number will be entered with (-) characters like;
650-212-5710.
A price value may be entered with (,) characters like;
12,500.00

In Java, java.lang.Character class has a method; isDigit() which can be used to identify whether a character is a digit or not. Following method can be used for extracting a numbers-only string.

public static String getOnlyNumerics(String str) {

if (str == null) {
return null;
}

StringBuffer strBuff = new StringBuffer();
char c;

for (int i = 0; i < str.length() ; i++) {
c = str.charAt(i);

if (Character.isDigit(c)) {
strBuff.append(c);
}
}
return strBuff.toString();
}

Calling above method with any String will return a numbers-only string.

Wednesday, July 30, 2008

How to open a .war (web archive) or .jar (java archive) files

With Java we generate .JAR files to bundle a set of resources. For J2EE web applications, we generate .WAR (Web Archive) files for deployments. Both of these are ways of archiving a set of files.

Both these .jar or .war archives are in zip format. So there are plenty of ways to open those files to read the content. One way would be to use any tool that you use to open/extract a .zip file. Next will be to use the Jar command itself.

JAR Command
JAR (command) utility in Java can be used to open/extract these files as follows. Run following command from the folder where you need the content to be extracted by providing the path to the archive.

jar xf <path-to-file>

options:
x - extract the files
f - file to extract

jar xf myWebApp.war
jar xf myProject.jar

Related : Open and read a file inside a war file of a web application with Java

Tuesday, July 29, 2008

Web Services with Apache Axis 1.4 Tutorial: server and client sides

Web services are a handy method of integrating independent systems. Apache Axis is one of the best free tools available for implementing and deploying web services, and also for implementing the web service clients. In this article we will create a simple, but complete web service and a client for this service step-by-step. Article will be explanatory as much as possible to succeed you in implementing it yourself alone after completing this tutorial.

Prerequisites

  • Must be familiar with Java
  • Familiar with basics on a web server like Tomcat
  • Some knowledge in configuring Axis will be an added advantage

System Configuration Requirements

We will be discussing the configuration in brief as our scope is mainly on web services. (If Axis already configured, jump to implementation). If you find any issues on the configuration part, you can refer to Apache Axis site for troubleshooting. (But if you can not solve it yourself do not worry, post the issue under the comments section in this article, and we’ll get back to you).

JDK installation
These examples have been tested on a machine with JDK 1.6 version.

Web Server
You must have a web server installed; and we will be using Tomcat (5.5 version) web server. If you are not having one, better download Tomcat here{link} and install it yourself (it is quite easy to install Tomcat). Now your CATALINA_HOME environment variable should point to the Tomcat installation directory.

Apache Axis 1.4
Download Apache Axis 1.4. Extract the downloaded file and you’ll find a folder named “axis” inside webapps folder.
%Axis_1.4_dir%\webapps\axis
Copy this “axis” folder into your web server’s webapps folder.
%CATALINA_HOME%\webapps

CLASS PATH
Now you must add following libraries into your CLASSPATH environment variable. All of these are available under %Axis_1.4_dir%\lib folder.
  • axis.jar
  • commons-discovery.jar
  • commons-logging.jar
  • jaxrpc.jar
  • log4j-1.2.8.jar
  • saaj.jar
  • wsdl4j.jar
That’s all for configuring Axis 1.4 on your system, quite easy isn’t it? Let’s move on to the implementation part.

Implementation - web service and client

The implementation will consist of two parts. First we will implement web service part; a Calculator will be exposed as a web service. Next a client to use this Calculator web service will be implemented. (Client part starts from here).

Calculator Web Service

Implementing the web service consists of 7 steps. We will be explaining each step in detail.
  1. Functionality provider
  2. Web service’s interface
  3. Java2WSDL - Generate WSDL file
  4. WSDL2Java - Generate server side and client side classes for web service
  5. Bind Web service with Functionality provider
  6. Bundle required classes
  7. Register web service with axis

Project structure

Before starting coding, we'll have a look at the project structure. We are using a separate folder for the project, called "WS-Sample". We will be creating source (.java) files under "WS-Sample\src" folder and storing generated class (.class) files under a "WS-Sample\classes" folder.

1. Functionality provider

First we need to write class with calculator functionality before exposing it as a web service. We have implemented it as a pretty complex high end calculator class, named SimpleCalculator and it's listed below. (It is just a pretty simple class with three methods). This class has no information related to a web service and has been written as a simple independent class. So in the time this class was written, no one has thought of any web service stuff. But we will expose this class as a web service. (Yes, what you guessed is correct. Later you can expose your existing Java classes as web services.)

package org.kamal.wssample;

public class SimpleCalculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
}
We'll compile above class using following command so that the generated .class file will reside in a folder named "classes" while preserving the package structure.

WS-Sample\src> javac -d ..\classes
org\kamal\wssample\SimpleCalculator.java

2. Web service’s interface

Now we should write an interface that defines the services that will be provided by our web service. We will expose only two methods through our service; add() and subtract() methods (although we can expose any number of services within one web service). We did choose only two methods to emphasize the fact that we can control which methods we expose. And we will write this class in a separate package; org.kamal.wssample.ws.

package org.kamal.wssample.ws;

public interface Calculator {
int add (int x, int y);
int subtract(int x, int y);
}
And compile using following command.

WS-Sample\src> javac -d ..\classes
org\kamal\wssample\ws\Calculator.java

3. Java2WSDL - Generate WSDL file

Axis has a tool called Java2WSDL, which generates a WSDL file for a web service using a Java class. We should use the Calculator interface and generate WSDL file as follows. Java2WSDL file requires the Calculator.class file (not Calculator.java) for the operation. Also we will provide the following information.
  • o – name for WSDL file -> calculator.wsdl
  • n – target namespace -> urn:org.kamal.calculator
  • l – url of web service -> http://localhost:8080/axis/services/calculator

WS-Sample\classes> java org.apache.axis.wsdl.Java2WSDL
-o ..\calculator.wsdl
-n urn:org.kamal.calculator
-l http://localhost:8080/axis/services/calculator
org.kamal.wssample.ws.Calculator
This command will generate a file named calculator.wsdl inside your project folder.

4. WSDL2Java - Generate server side and client side classes for web service

Axis has another tool named WSDL2Java, which can generate server side and client side Java classes using a WSDL file. These classes are needed for deploying the web service and for accessing the service by a Java client. This tool must be provided with WSDL file that we generated in the previous step. It needs the following information as well.
  • o – output folder -> src
  • p – package for generated classes -> org.kamal.wssample.ws.generated
  • s – generate server side classes as well

WS-Sample> java org.apache.axis.wsdl.WSDL2Java
-o src
-p org.kamal.wssample.ws.generated
-s
calculator.wsdl
Generated java classes will be saved in org.kamal.wssample.ws.generated package. This tool will generate five Java classes in this case with two .wsdd files as listed below.
  • Calculator.java
  • CalculatorService.java
  • CalculatorServiceLocator.java
  • CalculatorSoapBindingImpl.java
  • CalculatorSoapBindingStub.java
  • deploy.wsdd
  • undeploy.wsdd
Now we should compile those generated classes using the following command.

WS-Sample\src> javac –d ..\classes
org\kamal\wssample\ws\generated\*.java

5. Bind Web service with Functionality provider

As you may have noted; even though we wrote org.kamal.wssample.SimpleCalculator class at the start, we have not used it so far. Now we are going to bind it to the web service.

There is a class named CalculatorSoapBindingImpl inside org.kamal.wssample.ws.generated package. This is the class used to bind our existing SimpleCalculator class to the web service calls. In CalculatorSoapBindingImpl class, there are two methods; add() and subtract(). In this class, we can use the SimpleCalculator to call the actual methods as follows.

package org.kamal.wssample.ws.generated;

import org.kamal.wssample.SimpleCalculator;

public class CalculatorSoapBindingImpl implements
org.kamal.wssample.ws.generated.Calculator {
private SimpleCalculator calc = new SimpleCalculator();
public int add(int a, int b) throws java.rmi.RemoteException {
return calc.add(a, b);
}
public int subtract(int from, int x) throws java.rmi.RemoteException {
return calc.subtract(from, x);
}
}
Just analyze the above class, all method calls are delegated to the actual implementation class SimpleCalculator inside this binding class.

6. Bundle required classes

Now we will create a jar file with all these classes, so that we can use it for deploying our web service. Use the jar command as follows.

WS-Sample\classes> jar cvf ..\calculatorServerSide.jar
org\kamal\wssample\*.class
org\kamal\wssample\ws\*.class
org\kamal\wssample\ws\generated\*.class
Now copy this jar file into %CATALINA_HOME%\webapps\axis\WEB-INF\lib folder.

WS-Sample> copy calculatorServerSide.jar
"%CATALINA_HOME%\webapps\axis\WEB-INF\lib"

We will create another jar file to use in the client side. For the client side we only need the classes that were generated by the WSDL2java tool (which are located inside org\kamal\wssample\ws\generated package), except the CalculatorSoapBindingImpl class.

WS-Sample\classes> jar cvf ..\calculatorClientSide.jar
org\kamal\wssample\ws\generated\CalculatorSoapBindingStub.class
org\kamal\wssample\ws\generated\CalculatorServiceLocator.class
org\kamal\wssample\ws\generated\CalculatorService.class
org\kamal\wssample\ws\generated\Calculator.class

7. Register web service with axis

Axis comes with a tool for registering web services with Axis; it is called AdminClient. Look into org\kamal\wssample\ws\generated folder and you will find two WSDD (web service deployment descriptor) files; deploy.wsdd and undeploy.wsdd. These files were generated by WSDL2Java tool and as used in deploying/undeploying a web service.

Note: (Tomcat) Server must be started before executing the following command.

WS-Sample\src> java org.apache.axis.client.AdminClient
org\kamal\wssample\ws\generated\deploy.wsdd
This command will deploy the web service into axis. Now restart (Tomcat) server.

To verify our web service is deployed correctly; try following url from your browser.
http://localhost:8080/axis/services/calculator?wsdl
(change the port 8080 in url to match the port on your machine)

This will show up a complete wsdl file, and it is the complete definition of the web service that we have deployed.

Now everything on web service (server side) is completed and our web service is successfully deployed.

Web Service client

Now it’s time for us to write a client to access this web service and use provided services. For this we need the calculatorClientSide.jar file that we created in an earlier step.

For the client side we will create a new project folder named “WS-Client” with sub folders named src, classes and lib. Copy the generated calculatorClientSide.jar file into the "WS-Client\lib" folder.


We will create the client as follows. Since our web service exposed two methods, add() and subtract(); client class will use the service and call those add() and subtract() methods.

package org.kamal.wsclient;

import org.kamal.wssample.ws.generated.Calculator;
import org.kamal.wssample.ws.generated.CalculatorService;
import org.kamal.wssample.ws.generated.CalculatorServiceLocator;

public class CalcClient {
public static void main(String[] args) throws Exception {
CalculatorService service = new CalculatorServiceLocator();
Calculator calc = service.getcalculator();
System.out.println("15 + 6 = " + calc.add(15, 6));
System.out.println("15 - 6 = " + calc.subtract(15, 6));
}
}
The above class has not used even a single class that we wrote for Calculator implementation, only a few classes that WSDL2Java tool generated. We have not exposed the server side classes, but just provided a way to get the service from those classes.

Compile the class with following command.

WS-Sample-Client\src> javac -classpath %CLASSPATH%;..\lib\calculatorClientSide.jar
-d ..\classes
org\kamal\wsclient\CalcClient.java
Now we can run our web service client using following command.

WS-Sample-Client\classes> java -cp %CLASSPATH%;.;..\lib\calculatorClientSide.jar
org.kamal.wsclient.CalcClient
You would see the following as the result.

15 + 6 = 21
15 – 6 = 9
Our web service client, CalcClient has accessed the web service and received the results from the operations done by SimpleCalculator class (which is running on server side).

As you can see, generating the client side is much easier than the server side.

Related Articles

Wednesday, July 16, 2008

Java2WDSL & WSDL2Java - java.util.Date not handled consistently

Java2WSDL and WSDL2Java tools in Axis (1.4) are pretty handy tools. Those help you to generate a WSDL from a java class as well as generating stubs/skeletons from a WSDL. But if you are dealing with java.util.Date fields in your code, you must pay some attention.

Java2WSDL

Consider the following java interface which uses java.util.Date as a return type as well as a method parameter.

public interface MyService {
public java.util.Date getNextDate();
public void updateLastRun(java.util.Date date);
}
When the Java2WDSL tool generates a WSDL for a class with a Date field, it will represent java.util.Date fields as dateTime fields in WSDL. The generated WSDL file would look as follows.

<?xml version="1.0" encoding="UTF-8" ?>
<wsdl:definitions targetNamespace="http://service"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://service" xmlns:intf="http://service"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<!--WSDL created by Apache Axis version: 1.4-->
<wsdl:message name="setOpeningDateResponse">
</wsdl:message>
<wsdl:message name="setOpeningDateRequest">
<wsdl:part name="in0" type="xsd:dateTime" />
</wsdl:message>

<wsdl:message name="getOpenningDateResponse">
<wsdl:part name="getOpenningDateReturn" type="xsd:dateTime" />
</wsdl:message>
<wsdl:message name="getOpenningDateRequest">
</wsdl:message>

<!--rest of the content removed-->
</wsdl:definitions>
I have posted only a part of the WSDL which contains the messages. If you go through the above WSDL, you will see that both java.util.Date fields are represented as "dateTime" fields (type="xsd:dateTime").

WSDL2Java

Now we can generate the Java classes using our WSDL file. WSDL2Java tool will use the WSDL file and generate a set of classes for us. Following is the generated MyService class.

package service;

public interface MyService extends java.rmi.Remote {
public java.util.Calendar getOpenningDate()
throws java.rmi.RemoteException;
public void setOpeningDate(java.util.Calendar in0)
throws java.rmi.RemoteException;
}
See the difference? The generated MyService interface has java.util.Calendar fields instead of java.util.Date.

Since your binding implementation class implements this new interface, you will have some hard time in dealing with this data type changes. May be there's a quick fix which we don't see from here.

We tried this on Axis1.4 and did not try with Axis2.

Related Articles

Thursday, July 10, 2008

Java Sorting: Comparator vs Comparable Tutorial

Java Comparators and Comparables? What are they? How do we use them? This is a question we received from one of our readers. This article will discuss the java.util.Comparator and java.lang.Comparable in details with a set of sample codes for further clarifications.

Prerequisites

  • Basic Java knowledge

System Requirements

  • JDK installed

What are Java Comparators and Comparables?

As both names suggest (and you may have guessed), these are used for comparing objects in Java. Using these concepts; Java objects can be sorted according to a predefined order.
Two of these concepts can be explained as follows.

Comparable

A comparable object is capable of comparing itself with another object. The class itself must implements the java.lang.Comparable interface in order to be able to compare its instances.

Comparator

A comparator object is capable of comparing two different objects. The class is not comparing its instances, but some other class’s instances. This comparator class must implement the java.util.Comparator interface.

Do we need to compare objects?

The simplest answer is yes. When there is a list of objects, ordering these objects into different orders becomes a must in some situations. For example; think of displaying a list of employee objects in a web page. Generally employees may be displayed by sorting them using the employee id. Also there will be requirements to sort them according to the name or age as well. In these situations both these (above defined) concepts will become handy.

How to use these?

There are two interfaces in Java to support these concepts, and each of these has one method to be implemented by user. Those are;
java.lang.Comparable: int compareTo(Object o1)
This method compares this object with o1 object. Returned int value has the following meanings.
  1. positive – this object is greater than o1
  2. zero – this object equals to o1
  3. negative – this object is less than o1
java.util.Comparator: int compare(Object o1, Objecto2)
This method compares o1 and o2 objects. Returned int value has the following meanings.
  1. positive – o1 is greater than o2
  2. zero – o1 equals to o2
  3. negative – o1 is less than o2

Sorting with Collections class

  • java.util.Collections.sort(List) and java.util.Arrays.sort(Object[]) methods can be used to sort using natural ordering of objects.
  • java.util.Collections.sort(List, Comparator) and java.util.Arrays.sort(Object[], Comparator) methods can be used if a Comparator is available for comparison.
The above explained Employee example is a good candidate for explaining these two concepts. First we’ll write a simple Java bean to represent the Employee.
public class Employee {
private int empId;
private String name;
private int age;

public Employee(int empId, String name, int age) {
// set values on attributes
}
// getters & setters
}
Next we’ll create a list of Employees for using in different sorting requirements. Employees are added to a List without any specific order in the following class.
import java.util.*;

public class Util {

public static List<Employee> getEmployees() {

List<Employee> col = new ArrayList<Employee>();

col.add(new Employee(5, "Frank", 28));
col.add(new Employee(1, "Jorge", 19));
col.add(new Employee(6, "Bill", 34));
col.add(new Employee(3, "Michel", 10));
col.add(new Employee(7, "Simpson", 8));
col.add(new Employee(4, "Clerk",16 ));
col.add(new Employee(8, "Lee", 40));
col.add(new Employee(2, "Mark", 30));

return col;
}
}

Sorting in natural ordering

Employee’s natural ordering would be done according to the employee id. For that, above Employee class must be altered to add the comparing ability as follows.
public class Employee implements Comparable<Employee> {
private int empId;
private String name;
private int age;

/**
* Compare a given Employee with this object.
* If employee id of this object is
* greater than the received object,
* then this object is greater than the other.
*/
public int compareTo(Employee o) {
return this.empId - o.empId ;
}
// ….
}
The new compareTo() method does the trick of implementing the natural ordering of the instances. So if a collection of Employee objects is sorted using Collections.sort(List) method; sorting happens according to the ordering done inside this method.

We’ll write a class to test this natural ordering mechanism. Following class use the Collections.sort(List) method to sort the given list in natural order.
import java.util.*;

public class TestEmployeeSort {

public static void main(String[] args) {
List coll = Util.getEmployees();
Collections.sort(coll); // sort method
printList(coll);
}

private static void printList(List<Employee> list) {
System.out.println("EmpId\tName\tAge");
for (Employee e: list) {
System.out.println(e.getEmpId() + "\t" + e.getName() + "\t" + e.getAge());
}
}
}
Run the above class and examine the output. It will be as follows. As you can see, the list is sorted correctly using the employee id. As empId is an int value, the employee instances are ordered so that the int values ordered from 1 to 8.
EmpId Name Age
1 Jorge 19
2 Mark 30
3 Michel 10
4 Clerk 16
5 Frank 28
6 Bill 34
7 Simp 8
8 Lee 40

Sorting by other fields

If we need to sort using other fields of the employee, we’ll have to change the Employee class’s compareTo() method to use those fields. But then we’ll loose this empId based sorting mechanism. This is not a good alternative if we need to sort using different fields at different occasions. But no need to worry; Comparator is there to save us.

By writing a class that implements the java.util.Comparator interface, you can sort Employees using any field as you wish even without touching the Employee class itself; Employee class does not need to implement java.lang.Comparable or java.util.Comparator interface.

Sorting by name field

Following EmpSortByName class is used to sort Employee instances according to the name field. In this class, inside the compare() method sorting mechanism is implemented. In compare() method we get two Employee instances and we have to return which object is greater.
public class EmpSortByName implements Comparator<Employee>{

public int compare(Employee o1, Employee o2) {
return o1.getName().compareTo(o2.getName());
}
}
Watch out: Here, String class’s compareTo() method is used in comparing the name fields (which are Strings).

Now to test this sorting mechanism, you must use the Collections.sort(List, Comparator) method instead of Collections.sort(List) method. Now change the TestEmployeeSort class as follows. See how the EmpSortByName comparator is used inside sort method.
import java.util.*;

public class TestEmployeeSort {

public static void main(String[] args) {

List coll = Util.getEmployees();
//Collections.sort(coll);
//use Comparator implementation
Collections.sort(coll, new EmpSortByName());
printList(coll);
}

private static void printList(List<Employee> list) {
System.out.println("EmpId\tName\tAge");
for (Employee e: list) {
System.out.println(e.getEmpId() + "\t" + e.getName() + "\t" + e.getAge());
}
}
}
Now the result would be as follows. Check whether the employees are sorted correctly by the name String field. You’ll see that these are sorted alphabetically.
EmpId Name Age
6 Bill 34
4 Clerk 16
5 Frank 28
1 Jorge 19
8 Lee 40
2 Mark 30
3 Michel 10
7 Simp 8

Sorting by empId field

Even the ordering by empId (previously done using Comparable) can be implemented using Comparator; following class does that.
public class EmpSortByEmpId implements Comparator<Employee>{

public int compare(Employee o1, Employee o2) {
return o1.getEmpId() - o2.getEmpId();
}
}

Explore further

Do not stop here. Work on the followings by yourselves and sharpen knowledge on these concepts.
  1. Sort employees using name, age, empId in this order (ie: when names are equal, try age and then next empId)
  2. Explore how & why equals() method and compare()/compareTo() methods must be consistence.
If you have any issues on these concepts; please add those in the comments section and we’ll get back to you.

Related Articles