Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

Generic Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:


1. Introduction

Simply put, Spring uses property editors heavily for managing conversion between String values and custom Object types; this is based on Java Beans PropertyEditor.

In this tutorial, we'll go over two different use cases for demonstrating automatic property editor binding and custom property editor binding.

2. Automatic Property Editor Binding

Standard JavaBeans infrastructure will automatically discover PropertyEditor classes if they are in the same package as the class they handle. Also, these need to have the same name as that class plus the Editor suffix.

For example, if we create a CreditCard model class, then we should name the editor class CreditCardEditor.

Let's now go through a practical property binding example.

In our scenario, we'll pass a credit card number as a path variable in the request URL, and we'll bind that value as a CreditCard object.

Let's first create the CreditCard model class defining fields rawCardNumber, Bank Identification Number (the first 6-digits), Account Number (digits from 7 to 15) and Check Code (last digit):

public class CreditCard {

    private String rawCardNumber;
    private Integer bankIdNo;
    private Integer accountNo;
    private Integer checkCode;

    // standard constructor, getters, setters

Next, we'll create the CreditCardEditor class. This implements the business logic for converting the credit card number given as a String to a CreditCard object.

The property editor class should extend PropertyEditorSupport and implement the getAsText() and setAsText() methods:

public class CreditCardEditor extends PropertyEditorSupport {

    public String getAsText() {
        CreditCard creditCard = (CreditCard) getValue();
        return creditCard == null ? "" : creditCard.getRawCardNumber();
    public void setAsText(String text) throws IllegalArgumentException {
        if (StringUtils.isEmpty(text)) {
        } else {
            CreditCard creditCard = new CreditCard();
            String cardNo = text.replaceAll("-", "");
            if (cardNo.length() != 16)
                throw new IllegalArgumentException(
                  "Credit card format should be xxxx-xxxx-xxxx-xxxx");
            try {
                creditCard.setBankIdNo( Integer.valueOf(cardNo.substring(0, 6)) );
                creditCard.setAccountNo( Integer.valueOf(
                  cardNo.substring(6, cardNo.length() - 1)) );
                creditCard.setCheckCode( Integer.valueOf(
                  cardNo.substring(cardNo.length() - 1)) );
            } catch (NumberFormatException nfe) {
                throw new IllegalArgumentException(nfe);

The getAsText() method is called when serializing an object to a String, while setAsText() is used to convert a String to another object.

Since these classes are located in the same package, we don't need to do anything else for binding the Editor for type CreditCard.

We can now expose this as a Resource in a REST API; the operation takes a credit card number as a request path variable and Spring will bind that text value as a CrediCard object and pass it as a method argument:

@GetMapping(value = "/credit-card/{card-no}", 
  produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public CreditCard parseCreditCardNumber(
    @PathVariable("card-no") CreditCard creditCard) {
    return creditCard;

For example, for a sample request URL /property-editor/credit-card/1234-1234-1111-0019, we'll get the response:

    "rawCardNumber": "1234-1234-1111-0011",
    "bankIdNo": 123412,
    "accountNo": 341111001,
    "checkCode": 9

3. Custom Property Editor Binding

If we don't have the required type class and the property editor class in the same package or with the expected naming conventions, we'll have to define a custom binding between the required type and the property editor.

In our custom property editor binding scenario, a String value will be passed in the URL as path variable, and we'll bind that value as an ExoticType object which merely keeps the value as an attribute.

As in section 2, let's first create a model class ExoticType:

public class ExoticType {
    private String name;
    // standard constructor, getters, setters

And our custom property editor class CustomExoticTypeEditor which again extends PropertyEditorSupport: 

public class CustomExoticTypeEditor extends PropertyEditorSupport {

    public String getAsText() {
        ExoticType exoticType = (ExoticType) getValue();
        return exoticType == null ? "" : exoticType.getName();
    public void setAsText(String text) throws IllegalArgumentException {
        ExoticType exoticType = new ExoticType();

Since Spring can't detect the property editor, we'll need a method annotated with @InitBinder in our Controller class that registers the editor:

public void initBinder(WebDataBinder binder) {
        new CustomExoticTypeEditor());

Then we can bind the user input to ExoticType object:

  value = "/exotic-type/{value}", 
  produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ExoticType parseExoticType(
  @PathVariable("value") ExoticType exoticType) {
    return exoticType;

For the sample request URL /property-editor/exotic-type/passion-fruit, we'll get the sample response:

    "name": "PASSION-FRUIT"

4. Conclusion

In this quick article, we saw how we could use automatic and custom property editor binding to convert human-readable String values to complex Java types.

The full source code of our examples here is, as always, over on GitHub.

Generic bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

Generic footer banner
Comments are closed on this article!