在@BeanParam 中使用枚举

Using an Enum in @BeanParam

我正在使用这样的@BeanParam:

@GET
public Response listAllPaged(@BeanParam PagedRequest pagedRequest) {
    // Do stuff...
}

bean 本身:

public class PagedRequest {

    @QueryParam("sortOrder")
    @DefaultValue("0")
    public int sortOrder;    
}

现在我想将 sortOrder 的类型更改为以下枚举:

public enum SortOrder {
    ASC("asc"),
    DESC("desc");

    public final String sortOrder;

    SortOrder(String sortOrder) {
        this.sortOrder = sortOrder;
    }
}

但是一旦我这样做:

public class PagedRequest {

    @QueryParam("sortOrder")
    @DefaultValue("asc")
    public SortOrder sortOrder;
}

我的 REST 端点无法再匹配签名和 returns 404。这是为什么?我认为接受单个字符串的构造函数的存在应该允许 JAX-RS 进行转换。

我做错了什么?

更新

我设法让它像这样工作,但它并没有真正回答我最初的问题...

public enum SortOrder {
    ASC,
    DESC;

    public static SortOrder fromString(String param) {
        String toUpper = param.toUpperCase();
        try {
            return valueOf(toUpper);
        } catch (Exception e) {
            return null;
        }
    }
}

Enum.valueOf(String)方法用于解析值。由于您的 SorterOrder 枚举是大写的,因此您需要以大写形式发送参数。

如果您只想传递小写的值,您可以将枚举名称更改为小写,例如SortOrder.asc.

如果您不知道或不想关心参数发送的大小写,您可以使用 ParamConverter.

public class SortOrderParamConverter implements ParamConverter<SortOrder> {
    @Override
    public SortOrder fromString(final String value) {
        if (value != null) {
            return SortOrder.valueOf(value.toUpperCase(Locale.ROOT));
        }
        return SortOrder.ASC;
    }

    @Override
    public String toString(final SortOrder value) {
        return value.name();
    }
}

如果您想要更通用的方法,您可以创建一个 ParamConverter 或所有枚举。

@Provider
public class EnumParamConverterProvider implements ParamConverterProvider {
    @Override
    public <T> ParamConverter<T> getConverter(final Class<T> rawType, final Type genericType,
                                              final Annotation[] annotations) {
        if (!rawType.isEnum()) {
            return null;
        }
        final Enum<?>[] constants = (Enum<?>[]) rawType.getEnumConstants();
        return new ParamConverter<T>() {
            @Override
            @SuppressWarnings("unchecked")
            public T fromString(final String value) {
                if (value == null || value.isEmpty()) {
                    return null;
                }
                for (Enum<?> e : constants) {
                    if (e.name().equalsIgnoreCase(value)) {
                        return (T) e;
                    }
                }
                // No match, check toString()
                for (Enum<?> e : constants) {
                    if (e.toString().equalsIgnoreCase(value)) {
                        return (T) e;
                    }
                }
                return null;
            }

            @Override
            public String toString(final T value) {
                return value != null ? value.toString() : null;
            }
        };
    }
}