users@jersey.java.net

_at_QueryParam binding with Java Enum

From: Jeff Schmidt <jas_at_535consulting.com>
Date: Tue, 28 Oct 2008 15:50:08 -0600

Hello:

This seems like such a basic thing to want, that I'm probably just
missing something there. I have a method in a resource defined as:

     @GET
     public AnalysesList getInfoForAllAnalyses(
             @Context UriInfo uriInfo,
             @QueryParam("analysistype") AnalysisType analysisType) {

         ...
     }

AnalysisType is a pretty simple Enum:

@XmlEnum
public enum AnalysisType {

     @XmlEnumValue("Core")
     CORE("Core"),
     @XmlEnumValue("Tox")
     TOX("Tox"),
     @XmlEnumValue("Metabolomics")
     METABOLOMICS("Metabolomics")
     ;

     private final String value;

     AnalysisType(String v) {
         value = v;
     }

     public String value() {
         return value;
     }

     public static AnalysisType fromValue(String v) {
         for (AnalysisType c: AnalysisType.values()) {
             if (c.value.equals(v)) {
                 return c;
             }
         }
         throw new IllegalArgumentException(v.toString());
     }

     /*
     public static AnalysisType valueOf(String typeStr) {
         return AnalysisType.fromValue(typeStr);
     }*/
}

Note this Enum was originally derived from an XML schema used in a
SOAP API (using JAXB xjc), and it created the fromValue() method,
which I assume JAXB uses to bind a String representation to an actual
Enum instance. I would also like to bind a JAX-RS query parameter to
this Enum using Jersey. Making a request with the query parameter
defined as analysistype=CORE works great. However, I want to refer to
the type as "Core" (analysistype=Core) to match the CamelCase XML
standard we're using. However, this results in 404 (Not Found).

  I don't want to have to change the Enum itself and dependent code to
switch from AnalysisType.CORE to AnalysisType.Core. From what I can
tell, a given Java class can be bound by Jersey if it has a static
valueOf(String) method. However, Enum will not let me define this
method as the compiler says its already defined. I'm guessing that's
how Jersey is able to bind as explained earlier; based on the actual
name of the Enum elements. Also, I cannot make a constructor available
to Jersey, given it's an Enum.

Is there a good way to handle this in Jersey? Perhaps there is some
kind of provider or resolver I have to implement on my own?

Thanks,

Jeff
--
Jeff Schmidt