Wednesday, 28 November 2018

Spring web mvc: custom property editor

This is continuation to my previous post. In this post, I am going to explain how to create a custom property editor and bind it to the controller while doing properties binding.

Spring provides many property editors, to customize the properties binding process.

Below table summarizes the property editors provided by spring framework.

Property Editor
Description
Editor for byte arrays.
Editor for a Character, to populate a property of type Character or char from a String value.
Editor for char arrays.
Editor for java.nio.charset.Charset, translating charset String representations into Charset objects and back.
Property editor for an array of Classes, to enable the direct population of a Class[] property without having to use a String class name property as bridge.
Property editor for java.lang.Class, to enable the direct population of a Class property without recourse to having to use a String class name property as bridge.
Editor for java.util.Currency, translating currency codes into Currency objects.
Property editor for Boolean/boolean properties.
Property editor for Collections, converting any source Collection to a given target Collection type.
Property editor for java.util.Date, supporting a custom java.text.DateFormat.
Property editor for Maps, converting any source Map to a given target Map type.
Property editor for any Number subclass such as Short, Integer, Long, BigInteger, Float, Double, BigDecimal.
Editor for java.io.File, to directly populate a File property from a Spring resource location.
Editor for org.xml.sax.InputSource, converting from a Spring resource location String to a SAX InputSource object.
One-way PropertyEditor which can convert from a text String to a java.io.InputStream, interpreting the given String as a Spring resource location (e.g.
Editor for java.util.Locale, to directly populate a Locale property.
Editor for java.nio.file.Path, to directly populate a Path property instead of using a String property as bridge.
Editor for java.util.regex.Pattern, to directly populate a Pattern property.
Custom PropertyEditor for Properties objects.
One-way PropertyEditor which can convert from a text String to a java.io.Reader, interpreting the given String as a Spring resource location (e.g.
PropertyEditor implementation for standard JDK ResourceBundles.
Custom PropertyEditor for String arrays.
Property editor that trims Strings.
Editor for java.util.TimeZone, translating timezone IDs into TimeZone objects.
Editor for java.net.URI, to directly populate a URI property instead of using a String property as bridge.
Editor for java.net.URL, to directly populate a URL property instead of using a String property as bridge.
Editor for java.util.UUID, translating UUID String representations into UUID objects and back.
Editor for java.time.ZoneId, translating zone ID Strings into ZoneId objects.

In any case, if you feel these property editors are not satisfying your use case, you can create custom property editor by extending PropertyEditorSupport class.

For example, you are developing a student registration form, you are expecting the user to enter his/her name in capital letters, but user may or may not enter the name in capital letters. To address this use case, you can create a custom property binder and convert the name to upper case, before binding the request parameter to actual java model object.

How to create a custom property editor?
You can create a custom property editor, by extending the class 'PropertyEditorSupport'.

For example, below custom editor trims and convert the string to upper case.

public class StudentNameEditor extends PropertyEditorSupport {
         @Override
         public void setAsText(String text) {
                  setValue(text.trim().toUpperCase());
         }
}

How to register a custom property editor?
Below statements register custom editor to the field ‘userName’.
@InitBinder
public void customizeBinding(WebDataBinder dataBinder) {
         dataBinder.registerCustomEditor(String.class, "userName", new StudentNameEditor());
}

Find the below working application.

HelloWorldController.java
package com.sample.myApp.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.sample.myApp.model.Student;
import com.sample.myApp.propertyEditors.StudentNameEditor;

@Controller
public class HelloWorldController {

 @InitBinder
 public void customizeBinding(WebDataBinder dataBinder) {
  dataBinder.registerCustomEditor(String.class, "userName", new StudentNameEditor());
 }

 @RequestMapping("/registration")
 public String getRegistrationpage() {
  return "registration";
 }

 @RequestMapping("/registerMe")
 public ModelAndView getHelloMessage(@ModelAttribute("studentInfo") Student student, BindingResult bindingResult) {
  if (bindingResult.hasErrors()) {
   ModelAndView modelAndView = new ModelAndView("registration");
   return modelAndView;
  }

  ModelAndView modelAndView = new ModelAndView("welcome");

  modelAndView.addObject("message", "Dear User, your details are registered");

  return modelAndView;
 }

}

Student.java
package com.sample.myApp.model;

import java.util.Date;
import java.util.List;

public class Student {
 private String userName;
 private int age;
 private List<String> hobbies;
 private Date dateOfBirth;

 public Date getDateOfBirth() {
  return dateOfBirth;
 }

 public void setDateOfBirth(Date dateOfBirth) {
  this.dateOfBirth = dateOfBirth;
 }

 public String getUserName() {
  return userName;
 }

 public void setUserName(String userName) {
  this.userName = userName;
 }

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public List<String> getHobbies() {
  return hobbies;
 }

 public void setHobbies(List<String> hobbies) {
  this.hobbies = hobbies;
 }

}

StudentNameEditor.java
package com.sample.myApp.propertyEditors;

import java.beans.PropertyEditorSupport;

/**
 * 
 * @author Krishna
 * 
 *         Convert the user entered name to upper case and trim.
 *
 */
public class StudentNameEditor extends PropertyEditorSupport {
 @Override
 public void setAsText(String text) {
  setValue(text.trim().toUpperCase());
 }
}

Create registration.jsp, welcome.jsp files under WEB-INF/jsp folder.


registration.jsp
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>User Information Page</title>
</head>

<body>
 <h2 style="color:red;"><form:errors path="studentInfo.*" /></h2>

 <form method="post" action="/springdemo/registerMe" id="f1">
  <table>
   <tr>
    <td>User Name :</td>
    <td><input type="text" name="userName" value="" /></td>
   </tr>
   <tr>
    <td>Age :</td>
    <td><input type="text" name="age" value="" /></td>
   </tr>
   <tr>
    <td>Hobbies :</td>
    <td><select multiple name="hobbies">
      <option value="cricket">Cricket</option>
      <option value="chess">Chess</option>
      <option value="football">Football</option>
      <option value="tennis">Tennis</option>
    </select></td>
   </tr>
   
   <tr>
    <td>Date Of Birth</td>
    <td><input type="text" name="dateOfBirth" value="" /></td>
   </tr>
   <tr>
    <td><input type="submit" name="submit" value="submit"
     style="font-size: 18px;" /></td>
   </tr>
  </table>
 </form>

</body>
</html>

welcome.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Hello World Spring Web MVC</title>
</head>
<body>
 <h1>${message}</h1>

 <h3>
  User Name : ${studentInfo.userName} <br /> 
  Age : ${studentInfo.age} <br />
  Hobbies: ${studentInfo.hobbies} <br />
  Date Of Birth: ${studentInfo.dateOfBirth}
 </h3>
</body>
</html>

Create web.xml, HelloWorld-servlet.xml files under WEB-INF folder.


web.xml
<web-app id="WebApp_ID" version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <display-name>Spring MVC Hello WorldApplication</display-name>

 <servlet>
  <servlet-name>HelloWorld</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>HelloWorld</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>

</web-app>

HelloWorld-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 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-3.0.xsd
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

 <context:component-scan
  base-package="com.sample.myApp" />

 <bean
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/jsp/" />
  <property name="suffix" value=".jsp" />
 </bean>

</beans>

Create index.jsp file under webapp folder.


index.jsp
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>Welcome Page</title>
</head>

<body>
 <h3>Dear Student, click on below button to register yourself</h3>
 <form method="post" action="/springdemo/registration" id="f1">
  <input type="submit" name="submit" value="submit"
   style="font-size: 18px;" />
 </form>
</body>
</html>

Project structure looks like below.
Run the application on server. You can able to see below screen.

Click on ‘submit’ button to register.

Fill the form and click on submit button. You can able to see the name ‘krishna’ in upper case.
Previous                                                 Next                                                 Home

No comments:

Post a Comment