Java: Enum case insensitive Jersey Query Param Binding Java: Enum case insensitive Jersey Query Param Binding spring spring

Java: Enum case insensitive Jersey Query Param Binding


If you're doing it right it shouldn't be a problem. For example in case 3, using a fromString

public static enum Color {    RED, GREEN, BLUE;    public static Color fromString(String param) {        String toUpper = param.toUpperCase();        try {            return valueOf(toUpper);        } catch (Exception e) {            // default behavior is to send 404 on error.            // do something else if you want            throw new WebApplicationException(400);        }    }}

Every enum already has a static valueOf method which tries to match the enum value exactly, so we override this behavior by defining the fromString. We first call toUpperCase() then call valueOf as it's looking for upper case. If anything fails, like a wrong enum value, we send a 400. You can send something else or stick with the normal 404. Up to you.

I already did this, it is not working

Here is a complete test case.

import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.QueryParam;import javax.ws.rs.WebApplicationException;import javax.ws.rs.core.Response;import org.glassfish.jersey.server.ResourceConfig;import org.glassfish.jersey.test.JerseyTest;import static org.junit.Assert.assertEquals;import org.junit.Test;public class EnumTest extends JerseyTest {    public static enum Color {        RED, GREEN, BLUE;        public static Color fromString(String param) {            String toUpper = param.toUpperCase();            try {                return valueOf(toUpper);            } catch (Exception e) {                // default behavior is to send 404 on error.                // do something else if you want                throw new WebApplicationException(400);            }        }    }        @Path("enum")    public static class ColorResource {                @GET        public String color(@QueryParam("color") Color color) {            return color.toString();        }    }        @Override    public ResourceConfig configure() {        return new ResourceConfig(ColorResource.class);    }        @Test    public void doit() {        Response response = target("enum").queryParam("color", "blue").request().get();        assertEquals(200, response.getStatus());        assertEquals("BLUE", response.readEntity(String.class));        response.close();                response = target("enum").queryParam("color", "gReEn").request().get();        assertEquals(200, response.getStatus());        assertEquals("GREEN", response.readEntity(String.class));        response.close();        response = target("enum").queryParam("color", "RED").request().get();        assertEquals(200, response.getStatus());        assertEquals("RED", response.readEntity(String.class));        response.close();                response = target("enum").queryParam("color", "orange").request().get();        assertEquals(400, response.getStatus());        response.close();    }}

Use this dependency

<dependency>    <groupId>org.glassfish.jersey.test-framework.providers</groupId>    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>    <version>2.19</version>    <scope>test</scope></dependency>

UPDATE

Test using @BeanParam

import javax.ws.rs.BeanParam;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.QueryParam;import javax.ws.rs.WebApplicationException;import javax.ws.rs.core.Response;import org.glassfish.jersey.server.ResourceConfig;import org.glassfish.jersey.test.JerseyTest;import static org.junit.Assert.assertEquals;import org.junit.Test;public class EnumTest extends JerseyTest {    public static enum Color {        RED, GREEN, BLUE;        public static Color fromString(String param) {            String toUpper = param.toUpperCase();            System.out.println("--- toUpper " + toUpper + "---");            try {                return valueOf(toUpper);            } catch (Exception e) {                System.out.println(" --- ERROR ---");                // default behavior is to send 404 on error.                // do something else if you want                throw new WebApplicationException(400);            }        }    }        public static class FooQueryParam  {        @QueryParam("color")         private Color color;        public Color getColor() { return color; }        public void setColor(Color color) { this.color = color; }    }        @Path("enum")    public static class ColorResource {                @GET        public String color(@BeanParam FooQueryParam foo) {            return foo.getColor().toString();        }    }        @Override    public ResourceConfig configure() {        return new ResourceConfig(ColorResource.class);    }        @Test    public void doit() {        Response response = target("enum").queryParam("color", "blue").request().get();        assertEquals(200, response.getStatus());        assertEquals("BLUE", response.readEntity(String.class));        response.close();                response = target("enum").queryParam("color", "gReEn").request().get();        assertEquals(200, response.getStatus());        assertEquals("GREEN", response.readEntity(String.class));        response.close();                response = target("enum").queryParam("color", "RED").request().get();        assertEquals(200, response.getStatus());        assertEquals("RED", response.readEntity(String.class));        response.close();                response = target("enum").queryParam("color", "orange").request().get();        assertEquals(400, response.getStatus());        response.close();    }}

The only thing that fails is the error case where I am sending a bad color. It seems with @BeanParam the behavior is different. Instead of the expected 400, there is a 500. The other case sentiviity issues are fine