Java:Enum不区分大小写的Jersey Query Param Binding

时间:2015-10-26 23:50:08

标签: java spring rest java-ee jersey

我试图覆盖/实现JSR311中的所有属性,但Jersey绑定似乎敏感

  1. 是原始类型
  2. 拥有一个接受单个String参数的构造函数
  3. 有一个名为valueOf或fromString的静态方法,它接受一个String参数(例如,参见Integer.valueOf(String))
  4. Be List,Set或SortedSet,其中T满足上面的2或3。生成的集合是只读的。
  5. 如何使针对枚举不敏感的泽西绑定?

    编辑:

    以下是代码:

    枚举:

    public enum Color {
    
        GREEN,
    
        BLUE;
    
        public Color fromString(String param) {
            String toUpper = param.toUpperCase();
            try {
                return valueOf(toUpper);
            } catch (Exception e) {
                return null;
            }
        }
    }
    

    Bean Param:

     public class FooQueryParam {
            @QueryParam(value = "color")
            private Color color;
    
            public Color getColor() {
                return color;
            }
    
            public void setStatus(Color Color) {
                this.color = color;
            }
        }
    

    资源:

    public Response get(@BeanParam FooQueryParam fooQueryParam) {
                //... 
    }
    

1 个答案:

答案 0 :(得分:7)

如果你做得对,那应该不是问题。例如,在案例3中,使用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);
        }
    }
}

每个枚举都有一个静态valueOf方法,它试图精确匹配枚举值,因此我们通过定义fromString来覆盖此行为。我们先调用toUpperCase() 然后调用valueOf,因为它正在查找大写字母。如果有任何失败,例如错误的枚举值,我们会发送400.您可以发送其他内容或坚持使用正常的404.由您决定。

  

我已经这样做了,它无法正常工作

这是一个完整的测试用例。

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();
    }
}

使用此依赖

<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

使用@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();
    }
}

唯一失败的是我发送错误颜色的错误情况。似乎@BeanParam行为不同。而不是预期的400,有500.其他案件的情感问题很好