Enums as Request Parameters in Spring Boot Rest

Enums as Request Parameters in Spring Boot Rest thumbnail
145K
By Dhiraj 20 February, 2017

In many enterprise application categorical variable is often required to restrict the user request. In java, we achieve it by using enums. Most of the time we define enums in model classes and expect users to provide the exact enums in the request. This also adds one level of validation in any incoming request to the server. But while using Spring controllers to expose REST endpoints, these enums are not matched directly in the method input as a request parameters because the request we get is in plain String but our controller method is expecting an enum.

In this article, we will take a look into how to accept and parse those String as enum in requet parameters while using Spring REST. We will expose a sample REST endpoint that accepts enum type as a request parameter. We will be using spring boot features to build this app. Though the enums will be defind in capitals, the request String will be in lowercase.

How to Convert String in Request Parameters to Enum

Since, our controller method in Spring REST expects enum as an input parameter instead of a plain String, we need to come up with an idea to convert that String in the request parameter to enums before the controller method handles the request and start executing. Hence, if we want enums as request parameters in spring REST, we need to convert the String in the request to correpsonding enums before the annotated method starts its execution.

Spring provides @InitBinder annotation that identifies methods which initializes the WebDataBinder and this WebDataBinder populates the arguments to the annotated methods. Hence, the easy way is to register some custom editors in Spring which will convert those Strings to enums as request parameter. Now let us see how we can achieve it in spring.We will be exposing a REST endpoint which accepts type of question in the path parameter and return response based on the question type. The question type will be an enum in java.

Maven Dependency

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.devglan</groupId>
    <artifactId>spring-mvc-enum-example</artifactId>
    <version>0.1.0</version>

	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
    </parent>
	
    <dependencies>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
		
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
		
    </dependencies>

</project>

Now let us define our Application.java to take advantage of spring boot features.

@SpringBootApplication Equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes:

Application.java
package com.devglan;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Now let us define our enum.

QuestionCategory.java
package com.devglan.model;

import java.util.Arrays;

public enum QuestionCategory {
	
	CSE("cse"),ECE("ece");
	
	private String value;

	private QuestionCategory(String value) {
		this.value = value;
	}

	public static QuestionCategory fromValue(String value) {
		for (QuestionCategory category : values()) {
			if (category.value.equalsIgnoreCase(value)) {
				return category;
			}
		}
		throw new IllegalArgumentException(
				"Unknown enum type " + value + ", Allowed values are " + Arrays.toString(values()));
	}

}
 Other Interesting Posts
Spring Boot Actuator Complete Guide
Spring Boot Security Custom Login Form Example
Spring Boot Security Hibernate Example
Spring Mvc Anglar Js Example
Working with Spring Boot Jdbc Template
Spring Boot Security Password Encoding using Bcrypt Encoder
Websocket spring Boot Integration Without STOMP

Following is the model class which has enum defined above as a private member variable.

Question.java
package com.devglan.model;

public class Question {
	
	private QuestionCategory type;
	private String question;
	private String answer;
	
	public QuestionCategory getType() {
		return type;
	}
	public void setType(QuestionCategory type) {
		this.type = type;
	}
	public String getQuestion() {
		return question;
	}
	public void setQuestion(String question) {
		this.question = question;
	}
	public String getAnswer() {
		return answer;
	}
	public void setAnswer(String answer) {
		this.answer = answer;
	}

}

Now its time to define our controller - QuestionController.java. The get() method accepts question type as a path param and the question type is an enum. It also registers custom editor annotated with @InitBinder as discussed above at the start of the article. Everytime this api is called, our custom converter will execute and the String in the request parameter will be converted to corresponding enum.

QuestionController.java
package com.devglan.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.devglan.model.Question;
import com.devglan.model.QuestionCategory;
import com.devglan.model.QuestionCategoryConverter;

@RestController
public class QuestionController {

	@RequestMapping(value = "/{type}", method = RequestMethod.GET)
	public List get(@PathVariable(value = "type") QuestionCategory category) {
		return getQuestionsByCategory(category);
	}

	private List getQuestionsByCategory(QuestionCategory category) {
		List questions = new ArrayList();
		Question question = new Question();
		question.setType(category);
		if(category == QuestionCategory.CSE){
			question.setQuestion("What is Operating System.");
			question.setAnswer("This is the answer of what is os.");
		} else if(category == QuestionCategory.ECE){
			question.setQuestion("What is a transistor.");
			question.setAnswer("This is the answer of what is transistor.");
		}
		questions.add(question);
		return questions;
	}
	
	@InitBinder
	public void initBinder(final WebDataBinder webdataBinder) {
		webdataBinder.registerCustomEditor(QuestionCategory.class, new QuestionCategoryConverter());
	}

}

Following is the converter class.

QuestionCategoryConverter.java
package com.devglan.model;

import java.beans.PropertyEditorSupport;

public class QuestionCategoryConverter extends PropertyEditorSupport{

	 public void setAsText(final String text) throws IllegalArgumentException {
	        setValue(QuestionCategory.fromValue(text));
	    }

}

Run Application

1. Run Application.java as a java application

2. Hit the url localhost://8080/ece. You can expect following result with questionType as ECE

enum-request-in-spring-rest

3. Simlarly you can try a request for localhost://8080/cse. You can see the QuestionType as CSE this time.

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download the source

Share

If You Appreciate This, You Can Consider:

We are thankful for your never ending support.

About The Author

author-image
A technology savvy professional with an exceptional capacity to analyze, solve problems and multi-task. Technical expertise in highly scalable distributed systems, self-healing systems, and service-oriented architecture. Technical Skills: Java/J2EE, Spring, Hibernate, Reactive Programming, Microservices, Hystrix, Rest APIs, Java 8, Kafka, Kibana, Elasticsearch, etc.

Further Reading on Spring Boot