Monday 29 August 2016

@ControllerAdvice - @ExceptionHandler (spring 4.1.x)

@ControllerAdvice needs MVC namespace declaration in XML file. Or we can use @EnableWebMvc with @ControllerAdvice annotation.

  • ·         As of Spring 4, @ControllerAdvice can be customized through annotations(), basePackageClasses(), basePackages() methods to select a subset of controllers to assist. I will demonstrate a simple case how to utilize this new feature.
  •  ·         Allows for more concise annotation declarations e.g.: @ControllerAdvice("org.my.pkg") is equivalent to @ControllerAdvice(basePackages="org.my.pkg").
  •  ·         Controllers that belong to those base packages or sub-packages thereof will be included, e.g.: @ControllerAdvice(basePackages="org.my.pkg") or @ControllerAdvice(basePackages={"org.my.pkg", "org.my.other.pkg"}).
  •  @ControllerAdvice(basePackageClasses = io.github.kazuki43zoo.app.AppControllerAdvice.class)



Spring MVC provides a great way to handle exceptions and errors. @ExceptionHandler annotation is core to this feature. For each Spring controller we can simply define a method that automatically gets called if a given exception occurs. For example:
import org.springframework.web.bind.annotation.ExceptionHandler;

//..
@ExceptionHandler(IOException.class)
public String exception(Exception e) {
              
        //..
        return "error";
}
Thus whenever an IOException is raised from any controller method will call the above method exception(). We mapped IOException.class to this method using @ExceptionHandler annotation.
One short coming of this annotation is that it only handles exception getting raised from the controller where it is defined. It will not handle exceptions getting raised from other controllers. However this is a way to overcome this problem. @ControllerAdvice annotation is at your service for that.

@ControllerAdvice annotation
This annotation is used to define @ExceptionHandler@InitBinder, and @ModelAttribute methods that apply to all @RequestMapping methods.
import org.springframework.web.bind.annotation.ControllerAdvice;
//..
@ControllerAdvice
public class ExceptionControllerAdvice {

        @ExceptionHandler(Exception.class)
        public String exception(Exception e) {

               return "error";
        }
}
Thus if we define our @ExceptionHandler annotation on method in @ControllerAdvice class, it will be applied to all the controllers.
One thing worth noting here is that Spring configuration must define mvc namespace in order to identify @ControllerAdvice annotation. Thus you must define following in your spring-servlet.xml file.

<mvc:annotation-driven/>


If you have defined just the <context:annotation-config /> it wouldn’t work. The @ControllerAdvice will simply wont be loaded. So always remember to use <mvc:annotation-driven/> in Spring configuration

This will apply to all the classes which ever uses @RestController as annotation

@ControllerAdvice(annotations=RestController.class)
public class ExceptionControllerAdvice {
        @ExceptionHandler(Exception.class)
        public ResponseEntity<String> getSQLError(Exception exception){
               HttpHeaders headers = new HttpHeaders();
               headers.set("HeaderKey","HeaderDetails");
               return new ResponseEntity<String>("<a href="http://javabeat.net/recommends/rest-with-spring/" class="thirstylink" rel="nofollow" target="_blank" title="Rest">Rest</a> Controller Advice Example",headers,HttpStatus.ACCEPTED);
        }
}


Java - Serializable

11)    Super class with Serializable, will serialize all the objects of the subclass objects.
22)    If Subclass is Serializable interface implemented, then that will serialize all the objects of the super class objects.

You can think of serialization as the process of converting an object instance into a sequence of bytes (which may be binary or not depending on the implementation).
It is very useful when you want to transmit one object data across the network, for instance from one JVM to another.
In Java, the serialization mechanism is built into the platform, but you need to implement theSerializable interface to make an object serializable.
You can also prevent some data in your object from being serialized by marking the attribute astransient.
Finally you can override the default mechanism, and provide your own; this may be suitable in some special cases. To do this, you use one of the hidden features in java.
It is important to notice that what gets serialized is the "value" of the object, or the contents, and not the class definition. Thus methods are not serialized.
Here is a very basic sample with comments to facilitate its reading:
import java.io.Serializable;

// This class implements "Serializable" to let the system know
// Which ever the class extends this class, are also eligible for Serialization.
public class SerializeOne implements Serializable {
    private int ii = 10;

    public int getIi() {
        return ii;
    }

    public void setIi(int ii) {
        this.ii = ii;
    }
}


import java.io.*;
import java.util.*;

public class SerializeEx extends SerializeOne {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  {

        // Create a sample object, that contains the default values.
        SerializeEx instance = new SerializeEx();

        // The "ObjectOutputStream" class have the default
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream(
                // By using "FileOutputStream" we will
                // Write it to a File in the file system
                // It could have been a Socket to another
                // machine, a database, an in memory array, etc.
                new FileOutputStream(new File("o.ser")));

        // do the magic
        oos.writeObject( instance );
        // close the writing.
        oos.close();

        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("o.ser")))) {

            SerializeEx ex = (SerializeEx)in.readObject();
            System.out.println(ex.getIi());

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
 
When we run this program, the file "o.ser" is created and we can see what happened behind.
If we change the value of: someInteger to, for example Integer.MAX_VALUE, we may compare the output to see what the difference is.
Here's a screenshot showing precisely that difference:

Can you spot the differences? ;)
There is an additional relevant field in Java serialization: The serialversionUID but I guess this is already too long to cover it.




Friday 12 August 2016

dropwizard vs spring boot

Dropwizard
Spring Boot
Libraries
Core: Jetty, Jersey, Jackson and Matrics
Others: Guava, Liquibase and Joda Time.

Libraries
Any can be easily plugged
 Spring, JUnit, Logback, Guava. 

DEPENDENCY MANAGEMENT
Dependency Injection
No built in Dependency Injection. Requires a 3rd party dependency injection framework such as Guice, CDI or Dagger.
Dependency Injection
Built in Dependency Injection provided by Spring Dependency Injection container. 

Types of Services i.e. REST, SOAP
Primarily designed for HTTP/REST layer. But has some support for other types of services.

Types of Services i.e. REST, SOAP
As well as supporting REST Spring-boot has support for other types of services such as JMS, Advanced Message Queuing Protocol, SOAP based Web Services to name a few.

PERSISTENCE SUPPORT
It is very tightly coupled with Hibernate.
It uses Spring Data module that is build on JPA 2.1 specification
Another brilliant concept is Repository interface (from Spring Data module) that makes creation of CRUDs
TRANSACTION SUPPORT
Dropwizard comes with @UnitOfWorkannotation which can be applied only to methods in REST resource classes
@Transactional annotation can be applied on any method or class, not only on endpoints, so it gives much more flexibility.
CONFIGURATION MANAGEMENT
Dropwizard supports only YAML. But can integrate with other libraries to get multiple config file support.

SB supports simple .properties and yaml file format.

COMMUNITY SUPPORT


4 times more topics about Spring Boot