Sunday, November 29, 2015

Drag and Drop using GWT



Drag and drop can be an important feature in web apps. It allows adding a human touch to UIs. Drag and drag can be easily implemented using Html5 and Javascript, and also using other frameworks such as jquery. For Java web development, GWT provides a good solution. GWT have added a native feature to enable drag and drop for widgets and components. We are going to walk through it in this tutorial.

As the name implies, drag and drop has two sides: the element to be dragged, and the element to be dropped on.

To enable drag for any widget or component in GWT, we have to use the addDragHandler method. For example:
Image image = new Image("images/car.png");
image.addDragStartHandler(new DragStartHandler(){
   @Override
 public void onDragStart(DragStartEvent event) {
       // required: data to be transferred to the drop handler
              event.setData("text", image.getElement().getInnerHTML()); 
   }});
Not all elements have the addDragHandler by default. If an element is not implementing the DragHandler interface, the developper needs to add the handler to the DOM handlers:

        

image.addDomHandler(new DragStartHandler(){
     @Override
     public void onDragStart(DragStartEvent event) {
         // required: data to be transferred to the drop handler
   event.setData("text", image.getElement().getInnerHTML());
    }}, DragStartEvent.getType());
For the drop, we need to implement two handlers: DropHandler and DragOverHandler. Suppose we want to use a FlowPanel as a drop target:

          

FlowPanel target = new FlowPanel();

target.addDomHandler(new DragOverHandler() {
           @Override
           public void onDragOver(DragOverEvent event) {
               //Do something like changing background
       }
   }, DragOverEvent.getType());
   
    target.addDomHandler(new DropHandler() {
      @Override
      public void onDrop(DropEvent event) {
          // required
       event.preventDefault();
        
          // get the data out of the event
          String data = event.getData("text");
          Image image = new Image(data);
   
      }
  }, DropEvent.getType());
That's it. Now we can drag the Image into the FlowPanel.



There are other GWT libraries that implements Drag and Drop out of the box such as: 

It is advised for developpers to roll their own drag and drop in order not to depend on any implementation. 

Friday, November 20, 2015

Paris Open Source Summit Review


I have had the chance to hop into the the Paris Open Source Summit, and I wanted to share my experience. Some of the big players like RedHat, OpenSuse, Microsoft,.. were present which seems like a good reason to go there ,but after attending couple of seminars, it seems like most of the presentations were oriented towards "commercial" open source. For a java developper like myself, I was expecting more code talks. The few things that caught my interest:

        - Storage and Network features in the new Docker 1.9 version released in the 3rd of November:
Docker now gives its containers the possibility of attaching storage and of being accessible through the network. According to their blog, Docker Engine 1.9 includes a completely redesigned volume system that makes them much easier to use and brings plugins to the forefront. Storage can be manipulated using "docker volume" command. Network was introduced as an experimental feature since last June, and is now in the stable release of Docker Engine and ready to use in production.

- A demonstration of Salt, which is a configuration/build automation tool like Puppet and Chef.


- A demonstration of OpenID Connect which is an identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.

Friday, November 13, 2015

Custom form validation in Spring



Validation is an important step in handling forms which is one of the important aspects of building a web application. Spring MVC allow form validation in two different ways:
- By using annotations( using javax and Hibernate validators)
- Without annotation ( by implementing Validator interface)

In this tutorial, we will go through the second method which allows more customization of rules. 

Requirements:
- Eclipse
- Maven
- Spring MVC
- Jetty for testing the application( or any other web server of your choice)

First of all, we are going to create the application skelton by chosing: maven-archetype-webapp. 

  
We are going to use our usual PoJo:
public class Person {

 private String firstname;
 
 private String lastName;

 private int age;
 
 private String departement;
 
 
 /**
  * @return the firstname
  */
 public String getFirstname() {
  return firstname;
 }

 /**
  * @param firstname the firstname to set
  */
 public void setFirstname(String firstname) {
  this.firstname = firstname;
 }

 /**
  * @return the lastName
  */
 public String getLastName() {
  return lastName;
 }

 /**
  * @param lastName the lastName to set
  */
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 /**
  * @return the age
  */
 public int getAge() {
  return age;
 }

 /**
  * @param age the age to set
  */
 public void setAge(int age) {
  this.age = age;
 }

 /**
  * @return the departement
  */
 public String getDepartement() {
  return departement;
 }

 /**
  * @param departement the departement to set
  */
 public void setDepartement(String departement) {
  this.departement = departement;
 }
 
}

Let's suppose we need  a form to add a new person to the database. We can divide our view layer into two views: one for inputing the data (index.jsp), and the second one for confirmation ( add.jsp).

index.jsp


Notice that we have used Spring form tag instead of HTML regular form tag because we want to bind the form data to our Person object. Also, the form tag has a pre defined error tag that allows displaying errors on the page if any. 

Now we can create our validator. The rules that we are going to implement are as follow: 

- No field must be empty
- age must be an integer between 18 and 120

To create a custom validator, we need to implement Spring Validator interface. 

@Component
public class PersonValidator implements Validator {

 public boolean supports(Class arg0) {
  // TODO Auto-generated method stub
  return Person.class.equals(arg0);
 }


 public void validate(Object object, Errors errors) {
  Person person = (Person)object;
  
  ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstname", "person.firstname.empty");
  ValidationUtils.rejectIfEmptyOrWhitespace(errors, "lastName", "person.lastName.empty");
  ValidationUtils.rejectIfEmptyOrWhitespace(errors, "age", "person.age.empty");
  ValidationUtils.rejectIfEmptyOrWhitespace(errors, "departement", "person.departement.empty");
  
  if(person.getAge() < 18 || person.getAge() > 120){
   errors.rejectValue("age", "person.age.notValid");
  }
 }

}


We used @component because we want to use @autowired on our validator when we instantiate it from the controller. Notice also, that we used some error messages (person.firstname.empty,person.lastName.empty,...) that we will configure later. ValidationUtils will look for these message in the application context, so we have to make sure that they are available, otherwise Spring will throw an exception on form submission. The next step is building our controller:

@Controller
public class FormController {
 
 @Autowired
 PersonValidator personValidator;
 
  @InitBinder
     private void initBinder(WebDataBinder binder) {
         binder.setValidator(personValidator);
     }
  
 @RequestMapping(value="/", method = RequestMethod.GET)
 public String displayForm(Map model){
  Person person = new Person();
  model.put("person", person);
  return "index";
 }
 
 @RequestMapping(value="/add", method = RequestMethod.POST)
 public String submitForm(@Validated @ModelAttribute("person") Person person,
            BindingResult result, Map model){
  
  
  if(result.hasErrors()){
   return "index";
  }
  return "add";
 }

}

We have used @Initbinder to set our form validator. @Initbinder is used in general for populating command and form object arguments of annotated handler methods.

Finally we need to add our error messages and configure our beans:
File: validation.properties

person.firstname.empty=First name must not be empty
person.lastName.empty=Last name must not be empty
person.age.empty=age must not be empty
person.age.notValid=age must be between 18 and 120
person.departement.empty=departement must not be empty
typeMismatch.int=age must be a number.

We have added typeMismatch.int to override Spring Message for type mismatch ( integer parsing exception) which displays a long exception message that is not suited to display in a web page.

Our bean configuration file "mvc-dispatcher-servlet.xml":



our file structure looks like:



we can run our application by typing "mvn jetty:run" in eclipse or command line.

if we click add without filling in the right values, we get:


otherwise;




Full example at: https://github.com/zak905/springformvalidation