users@jersey.java.net

[Jersey] get parameter source name in ResourceFilterFactory implementation

From: Odelya Holiday <odelya_at_grroo.com>
Date: Sun, 9 Oct 2011 17:55:37 +0200

Since there is no required annotation in jersey, I decided to create
my own with the following implementation:

public class RequiredParamFilter implements ResourceFilterFactory {

       /* (non-Javadoc)
        * @see com.sun.jersey.spi.container.ResourceFilterFactory#create(com.sun.jersey.api.model.AbstractMethod)
        */
       @Override
       public List<ResourceFilter> create(AbstractMethod am) {
               //if it's a resource method we need to create a list of required
fields to be checked every time
               if (am instanceof AbstractSubResourceMethod) {
                       ArrayList<String> requiredFields =
getAnnotatedFields(am);
                       return Collections.<ResourceFilter> singletonList(new
Filter(requiredFields));
               }
               return null;
       }

       private ArrayList<String> getAnnotatedFields(AbstractMethod am) {
               ArrayList<String> requiredFields = new ArrayList<String>();
               List<Parameter> parameters =
((AbstractSubResourceMethod) am).getParameters();
               //check if one of the parameters has Required annotation
               if (parameters != null && parameters.size() > 0) {
                       for (Parameter parameter : parameters)
                               if
(parameter.isAnnotationPresent(Required.class)) {

requiredFields.add(parameter.getSourceName());
                               }
               }
               return requiredFields;
       }

       private class Filter implements ResourceFilter, ContainerRequestFilter {

               private final ArrayList<String> requiredParameters;

               protected Filter() {
                       this.requiredParameters = null;
               }

               protected Filter(ArrayList<String> requiredParameters) {
                       this.requiredParameters = requiredParameters;
               }

               // ResourceFilter

               @Override
               public ContainerRequestFilter getRequestFilter() {
                       return this;
               }

               @Override
               public ContainerResponseFilter getResponseFilter() {
                       return null;
               }

               // ContainerRequestFilter

               @Override
               public ContainerRequest filter(ContainerRequest request) {
                       if (requiredParameters != null &&
requiredParameters.size() > 0) {
                               //loop over them and see if the
required parameters are not empty
                               MultivaluedMap<String, String> params =
request.getQueryParameters();
                               StringBuffer missingParams = new StringBuffer();
                               for (String reqParam : requiredParameters) {
                                       List<String> paramValues =
params.get(reqParam);
                                       if (paramValues == null ||
paramValues != null && paramValues.size() == 0)

missingParams.append(reqParam + ",");
                               }
                               if (missingParams.length() > 0)
                                       throw new
WebApplicationException(Response.status(400).entity("Required
parameters are missing: " + missingParams)

.type(MediaType.TEXT_PLAIN).build());
                       }
                       return request;
               }
       }
}

However, since I don't want the user to enter @Required(value) but
only @Required and I will figure the field name based on the
sourceName I wrote:

requiredFields.add(parameter.getSourceName());

However I get: null for parameter.getSourceName and also for getSource
- UNKOWN.

Is it a bug in your code to assign the setSourceName or something is
wrong with my code?

Thanks!