How to map Enum Types to JSON requests in Spring Boot automatically?

Let’s say you have created a REST service which accepts a JSON request.

And one of the attributes in the request can only have a range of constant values.

For example , the departments an employee can belong to.

And the best way to represent this , is to use an Enum.

But will a Spring REST service allow an enum to be mapped to one of the attributes in a JSON request.

It will!

Spring REST will automatically map the attribute value to the Enum name .

Let’s see this in code and also see how to map an enum value to a JSON attribute instead of the name later.

First , let’s look at the default one – Mapping Json attribute to an Enum name

Consider the below Rest Controller:

package com.springboot.enuminrequest;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EmployeeController {

	@PostMapping("checkEmployee")
	public String checkEmployee(@RequestBody Employee employee) {

		return employee.getDepartment().getDepCode();
	}
}

The above rest service maps incoming Json requests to an Employee model object. The mapping is done automatically by Spring under the hoods.

Below is the employee model class:

package com.springboot.enuminrequest;

public class Employee {

	private String name;

	private Department department;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

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

	/**
	 * @return the department
	 */
	public Department getDepartment() {
		return department;
	}

	/**
	 * @param department the department to set
	 */
	public void setDepartment(Department department) {
		this.department = department;
	}

}

It just takes a name and a Department Enum.

Below is the Department enum:

package com.springboot.enuminrequest;

public enum Department {

	SALES("d1"),

	MARKETING("d2"),

	PRODUCTION("d3");

	private String depCode;

	private Department(String depCode) {

		this.depCode = depCode;
	}

	public String getDepCode() {

		return this.depCode;
	}



}

The enum has three possible values for department.

d1,d2 and d3 are the department codes for the departments SALES,MARKETING and PRODUCTION respectively

Now let’s try hitting the /checkEmployee POST method:

As you see , I am entering the value ‘MARKETING’ for the department field and this is mapped to the enum name ‘MARKETING’ automatically by Spring .

And I am returning the department code in the response for the given department name which is d2.

All is well.

But what if the user wants to pass an enum value and we need to map an enum based on its value and not based on the name( eg) based on the value ‘d2’ and not on the name ‘MARKETING’)

Let’s try hitting the above service with the enum value :

We get an error saying that the value ‘d2’ cannot be mapped to the Department enum since it accepts only the three values (‘SALES’,’MARKETING’ and ‘PRODUCTION’).

How can we make Spring map an enum based on a value?

Jackson comes to the rescue.

Spring Boot automatically adds Jackson dependency if you include Spring boot web starter dependency in pom.xml

All you have to do is create a static method annotated with @JsonCreator in your enum.

This should accept a parameter (the enum value) and return the corresponding enum.

Here is the method:

	@JsonCreator
	public static Department getDepartmentFromCode(String value) {

		for (Department dep : Department.values()) {

			if (dep.getDepCode().equals(value)) {

				return dep;
			}
		}

		return null;
	}

Here is the updated Enum:

package com.springboot.enuminrequest;

import com.fasterxml.jackson.annotation.JsonCreator;

public enum Department {

	SALES("d1"),

	MARKETING("d2"),

	PRODUCTION("d3");

	private String depCode;

	private Department(String depCode) {

		this.depCode = depCode;
	}

	public String getDepCode() {

		return this.depCode;
	}

	@JsonCreator
	public static Department getDepartmentFromCode(String value) {

		for (Department dep : Department.values()) {

			if (dep.getDepCode().equals(value)) {

				return dep;
			}
		}

		return null;
	}

}

This method overrides the default mapping of Enum name to a json attribute . It is important that the annotated method is static else Spring doesn’t consider it.

Let’s hit the REST service with the department code now:

It works!

Thus we can map an Enum to a json attribute both based on its name and value


Posted

in

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading