Saturday 10 February 2007

Sending a SOAP request to a Web Service via URLConnection


The SOAP request
<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <getUserByEmail xmlns="http://service.w3.ibm.com">
      <iuser>jholy@example.com</iuser>
    </getUserByEmail>
  </soap:Body>
</soap:Envelope>

The Java code


String soapXml = //
java.net.URL url = new java.net.URL("http://localhost:9081/myServiceWAR/services/MyService");
java.net.URLConnection conn = url.openConnection();

// Set the necessary header fields
conn.setRequestProperty("SOAPAction", "http://localhost:9081/myServiceWAR/services/MyService");
conn.setDoOutput(true);

// Send the request
java.io.OutputStreamWriter wr = new java.io.OutputStreamWriter(conn.getOutputStream());
wr.write(soapXml);
wr.flush();

// Read the response
java.io.BufferedReader rd = new java.io.BufferedReader(
new java.io.InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println(line);
}

Friday 2 February 2007

Java Annotations

What are Java Annotations?

Annotations is a new feature from Java 5. Annotations are a kind of comment or meta data you can insert in your Java code. These annotations can then be processed at compile time by pre-compiler tools, or at runtime via Java Reflection. Here is an example of class annotation:

@MyAnnotation(name="someName",  value = "Hello World")
public class TheClass { }

The class TheClass has the annotation @MyAnnotation written ontop. Annotations are defined like interfaces. Here is the MyAnnotation definition:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

public @interface MyAnnotation {
    public String name();
    public String value();
}

The @ in front of the interface marks it as an annotation. Once you have defined the annotation you can use it in your code, as shown in the earlier examples. The two directives in the annotation definition, @Retention(RetentionPolicy.RUNTIME) and@Target(ElementType.TYPE), specifies how the annotation is to be used.

  • @Retention(RetentionPolicy.RUNTIME) means that the annotation can be accessed via reflection at runtime. If you do not set this directive, the annotation will not be preserved at runtime, and thus not available via reflection.
  • @Target(ElementType.TYPE) means that the annotation can only be used ontop of types (classes and interfaces typically). You can also specify METHOD or FIELD, or you can leave the target out alltogether so the annotation can be used for both classes, methods and fields.


An annotation need to have a RetentionPolicy that will be the scope of the annotation where at this point the annotation will be ignored or discarded. The values are RetentionPolicy.SOURCE,RetentionPolicy.CLASS and RetentionPolicy.RUNTIME. When no retention policy defined it will use the default retention policy which is the RetentionPolicy.CLASS.

Annotation with SOURCE retention policy will be retained only in the source code, it available to the compiler when it compiles the class and will be discarded after that. The CLASS retention policy will make the annotation stored in the class file during compilation, but will not available during the runtime. And the RUNTIME retention policy will stored the annotation in the class file during compilation and it also available to JVM at runtime.

All annotations are extending the java.lang.annotation.Annotation interface, which means that java.lang.annotation.Annotation is the super-interface of all annotations.

Class Annotations

You can access the annotations of a class, method or field at runtime. Here is an example that accesses the class annotations:

Class aClass = TheClass.class;
Annotation[] annotations = aClass.getAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotationannotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}

You can also access a specific class annotation like this:

Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotationannotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

 

Method Annotations

Here is an example of a method with annotations:

public class TheClass {
  @MyAnnotation(name="someName",  value = "Hello World")
  public void doSomething(){}
}

You can access method annotations like this:

Method method = ... //obtain method object
Annotation[] annotations = method.getDeclaredAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotationannotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}

You can also access a specific method annotation like this:

Method method = ... // obtain method object
Annotation annotation = method.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotationannotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

Parameter Annotations

It is possible to add annotations to method parameter declarations too. Here is how that looks:

public class TheClass {
  public static void doSomethingElse(
        @MyAnnotation(name="aName", value="aValue"String parameter){
  }
}

You can access parameter annotations from the Method object like this:

Method method = ... //obtain method object
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();

int i=0;
for(Annotation[] annotations : parameterAnnotations){
  Class parameterType = parameterTypes[i++];

  for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotationannotation;
        System.out.println("param: " + parameterType.getName());
        System.out.println("name : " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
  }
}

Notice how the Method.getParameterAnnotations() method returns a two-dimensional Annotation array, containing an array of annotations for each method parameter.

Field Annotations

Here is an example of a field with annotations:


public class TheClass {

  @MyAnnotation(name="someName",  value = "Hello World")
  public String myField = null;
}

You can access field annotations like this:

Field field = ... //obtain field object
Annotation[] annotations = field.getDeclaredAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotationannotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}
Field field = ... // obtain method object
Annotation annotation = field.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotationannotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}