2

I have an Enum like below

public enum Customer {

    RETAIL("retail"),
    FREELANCER("FreeLancer"),
    MARKET("market"),
    PUBLICATION("publication");

    private String contentType;
    private static final Map<String,Customer> contentTypeMap;

    public String getContentType(){
        return this.contentType;
    }

    static {
        Map<String,Customer> map = new ConcurrentHashMap<>();
        for(Customer type : Customer.values ()){
            map.put (type.getContentType (),type);
        }
        contentTypeMap = map;
    }

    Customer(String contentType){
        this.contentType=contentType;
    }

    public static Customer getContentType(String contentType){
        return contentTypeMap.get (contentType);
    }

}

This enum represents the type of customer.

We have an API that return the customer details

@RequestMapping(value="/getData", method=RequestMethod.GET, produces="application/json")
public BatchResponse triggerBatchJob(
        @RequestParam(value="updateFrom", required=false) @DateTimeFormat(pattern="yyyyMMdd") String updateFrom,
        @RequestParam(value="updateTo", required=false) @DateTimeFormat(pattern="yyyyMMdd") String updateTo,
        @RequestParam(value="customerType") (VALIDATE_HERE)String customerType) {
    // ...
}

I need to validate the customerType value to be the ones present in the Enum, Is there a way to validate the same with the method declaration as I have done in the case of date rather than method body by using getContentType method or something.

Please help.

Lucie
  • 127
  • 1
  • 2
  • 12
  • It's already validated for you by Spring i.e. if you pass any value that doesn't match available values then this endpoint will return error message. If you are looking up for special validations customized for your application, please mention what type of additional validations you want. – Vinay Prajapati Mar 11 '19 at 09:02

2 Answers2

4

Change your method to following:

@RequestMapping(value="/getData", method=RequestMethod.GET, produces="application/json")
public BatchResponse triggerBatchJob(
        @RequestParam(value="updateFrom", required=false) @DateTimeFormat(pattern="yyyyMMdd") String updateFrom,
        @RequestParam(value="updateTo", required=false) @DateTimeFormat(pattern="yyyyMMdd") String updateTo,
        @RequestParam(value="customerType") CustomerType customerType) {
    // ...
}

i.e. customerType type should be CustomerType not String. Now only values those match enum will be mapped.

Note:- The values will have to be provided is specific format i.e. enum name itself e.g. in your case FREELANCER,RETAIL, PUBLICATION etc values should be passed in request.

Edit

As requested by OP below is customizing the enum handling from String:

Add @initBinder in the controller and add following method:

@InitBinder
    public void initBinder(final WebDataBinder webdataBinder) {
        webdataBinder.registerCustomEditor(Customer.class, new CustomerConverter());
    }

and declare a converter class as below:

import java.beans.PropertyEditorSupport;

public class CustomerConverter extends PropertyEditorSupport{

     public void setAsText(final String text) throws IllegalArgumentException {
         System.out.println("--->"+Customer.getContentType(text));
            setValue(Customer.getContentType(text));
        }¡¡
}

Added System.out.println to show that value is interpreted and printed as expected.

Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86
0

A simple null check will do

Customer customer = Customer.getContentType(customerType);
if (customer == null) {
     throw new Exception("Invalid Customer type");// use validation exception 
}
Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • Thanks for the reply, If possible, I need to do this in method declaration itself Not in the body. I guess this would have to be done in method body – Lucie Mar 11 '19 at 09:09