Required parameters on a Resource

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Required parameters on a Resource

DirkM
I'd like to indicate that a query parameter is required. There doesn't seem to be a way to do this using the @QueryParam annotation. Is there a @Required annotation or something similar that I'm missing?
The behaviour that I would expect is that it would return a 400 response if the parameter is missing.

I know of two workarounds:
1. use classes (eg Integer instead of int) and check to see if it's null
I don't really want to do this in every method where I have a required field

2. Write a custom parameter class
I don't want to do that for every field type (RequiredInteger, RequiredString...)

Please let me know if there's a way of requiring a parameter in Jersey.
Thanks,
Dirk
Reply | Threaded
Open this post in threaded view
|

Re: Required parameters on a Resource

Paul Sandoz
Administrator
Hi,

It should be possible to support your own @Required annotation by writing a special StringReaderProvider:

 https://jersey.dev.java.net/nonav/apidocs/1.1.1-ea/jersey/com/sun/jersey/spi/StringReaderProvider.html

Off the top of my head here is some psuedo code:

 @Provider
 public SerializableStringProvider implements StringReaderProvider {
   @Context StringReaderWorkers srw;

   public StringReader getStringReader(Class<?> type, Type genericType, Annotation[] annotations) {
     if (/annotations does not contain @Required/)
       return null;

     annotations = /remove required from annotations/

     final StringReader sr = srw.getStringReaderProvider(type, genericType, annotatons);
     if (sr == null) return null;

     return new StringReader() {
       public Object fromString(String value) {
         if (value == null)
           throw new WebApplicationException(400);
         return sr.fromString(value);         
       }
     }
   }

The above, suitably converted to Java, should work, if it does not then it is a bug we need to fox.

Paul.

On Aug 14, 2009, at 9:04 PM, DirkM wrote:


I'd like to indicate that a query parameter is required. There doesn't seem
to be a way to do this using the @QueryParam annotation. Is there a
@Required annotation or something similar that I'm missing?
The behaviour that I would expect is that it would return a 400 response if
the parameter is missing.

I know of two workarounds:
1. use classes (eg Integer instead of int) and check to see if it's null
I don't really want to do this in every method where I have a required field

2. Write a custom parameter class
I don't want to do that for every field type (RequiredInteger,
RequiredString...)

Please let me know if there's a way of requiring a parameter in Jersey.
Thanks,
Dirk
--
View this message in context: http://n2.nabble.com/Required-parameters-on-a-Resource-tp3446928p3446928.html
Sent from the Jersey mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Required parameters on a Resource

DirkM
I had a go at writing the class, and although in the logs the Provider appears to get picked up, the getStringReader method is never actually called. I'm no expert in generics so perhaps I've missed something obvious. Here's my code:

@Singleton
@Provider
public class SerializableStringProvider implements StringReaderProvider {
    @Context
    StringReaderWorkers srw;

    @Override
    public StringReader getStringReader(Class type, Type genericType, Annotation[] annotations) {

        // Create a copy of the annotations array, without the @Required
        // annotation
        Annotation[] otherAnnotations = new Annotation[annotations.length];
        int i = 0;
        for (Annotation annotation : annotations) {
            if (!annotation.getClass().equals(Required.class)) {
                otherAnnotations[i++] = annotation;
            }
        }

        // If all the annotations were copied, that means none of them was the
        // @Required annotation.
        if (i == annotations.length) {
            return null;
        }

        final StringReader<?> sr = srw.getStringReader(type, genericType, otherAnnotations);
        if (sr == null) {
            return null;
        }

        return new StringReader() {
            public Object fromString(String value) {
                if (value == null) {
                    throw new WebApplicationException(400);
                }
                return sr.fromString(value);
            }
        };
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: Required parameters on a Resource

Paul Sandoz
Administrator
Hi,

I am very very sorry, i led you on a wild goose chase with a late  
Friday email and was not thinking properly :-(

After looking a bit more into the code this is not going to work.  
StringReaderProvider operates on individual parameters (so will be  
called multiple times for collections of stuff) and will only be  
called if there is a non-null value present either because the  
parameter is present or because it has a default value.

The only solutions i can think of are:

1) Jersey supports an @Required annotation; or

2) Exposes a lower-level abstraction of MultivaluedParameterExtractor  
(which is an internally used interface):

      public interface MultivaluedParameterExtractor {
        Object extract(MultivaluedMap<String, String> parameters);
      }

      public interface MultivaluedParameterExtractorProvider { }

      public interface MultivaluedParameterExtractorWorkers { }

      and the same type of pattern can be utilized.

3) One can utilize AOP method-level interceptors to support @Required  
and check for a null value. This solution is
      much better if one needs to take into account more than one value.

I also wonder if there is a more general approach to parameter  
validation we can apply with the bean validation framework.

Currently I am leaning towards option 2. Could you log an issue so we  
can track this?

Thanks,
Paul.

On Aug 14, 2009, at 10:47 PM, DirkM wrote:

>
> I had a go at writing the class, and although in the logs the Provider
> appears to get picked up, the getStringReader method is never actually
> called. I'm no expert in generics so perhaps I've missed something  
> obvious.
> Here's my code:
>
> @Singleton
> @Provider
> public class SerializableStringProvider implements  
> StringReaderProvider {
>    @Context
>    StringReaderWorkers srw;
>
>    @Override
>    public StringReader getStringReader(Class type, Type genericType,
> Annotation[] annotations) {
>
>        // Create a copy of the annotations array, without the  
> @Required
>        // annotation
>        Annotation[] otherAnnotations = new  
> Annotation[annotations.length];
>        int i = 0;
>        for (Annotation annotation : annotations) {
>            if (!annotation.getClass().equals(Required.class)) {
>                otherAnnotations[i++] = annotation;
>            }
>        }
>
>        // If all the annotations were copied, that means none of  
> them was
> the
>        // @Required annotation.
>        if (i == annotations.length) {
>            return null;
>        }
>
>        final StringReader<?> sr = srw.getStringReader(type,  
> genericType,
> otherAnnotations);
>        if (sr == null) {
>            return null;
>        }
>
>        return new StringReader() {
>            public Object fromString(String value) {
>                if (value == null) {
>                    throw new WebApplicationException(400);
>                }
>                return sr.fromString(value);
>            }
>        };
>    }
> }
> --
> View this message in context: http://n2.nabble.com/Required-parameters-on-a-Resource-tp3446928p3447394.html
> Sent from the Jersey mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Required parameters on a Resource

DirkM
Paul Sandoz wrote
The only solutions i can think of are:

1) Jersey supports an @Required annotation; or
2) Exposes a lower-level abstraction of MultivaluedParameterExtractor  
3) One can utilize AOP method-level interceptors to support @Required  
and check for a null value.
I would assume that requiring a parameter is a common enough use case that many people would want to use it, although if this issue hasn't come up before perhaps I'm mistaken. If it is a common use case, option 1 makes the most sense to me.

If there are situations in which users want to do more complex things with parameter validation, then perhaps some kind of abstraction layer like you suggested would be useful.

Paul Sandoz wrote
Could you log an issue so we can track this?
I found this wiki page about using the Issue Tracker through Eclipse. But it looks like I have to create an account on Collabnet, install an Eclipse plugin and also create an account on Java.net. I wasn't able to install the plugin due to some subversion dependencies that I can't update because of our behind-the-times set up in the office.

Is there a web based version of the Issue Tracker?

Cheers,
Dirk
Reply | Threaded
Open this post in threaded view
|

Re: Required parameters on a Resource

Paul Sandoz
Administrator

On Aug 18, 2009, at 4:05 PM, DirkM wrote:



Paul Sandoz wrote:

The only solutions i can think of are:

1) Jersey supports an @Required annotation; or
2) Exposes a lower-level abstraction of MultivaluedParameterExtractor  
3) One can utilize AOP method-level interceptors to support @Required  
and check for a null value.


I would assume that requiring a parameter is a common enough use case that
many people would want to use it, although if this issue hasn't come up
before perhaps I'm mistaken. If it is a common use case, option 1 makes the
most sense to me.

We have discussed parameter validation before on the list, the solution you propose did not arise and we mostly said use something like bean validation and/or AOP method interceptors. I think the latter becomes more compelling when we utilize beans holding a set of parameters, especially for form parameters (there is an open issue for such support).



If there are situations in which users want to do more complex things with
parameter validation, then perhaps some kind of abstraction layer like you
suggested would be useful.


Paul Sandoz wrote:

Could you log an issue so we can track this?


I found this
http://wikis.sun.com/display/Jersey/Accessing+Jersey+Issues+Tracker+using+Eclipse+IDE
wiki page  about using the Issue Tracker through Eclipse. But it looks like
I have to create an account on Collabnet, install an Eclipse plugin and also
create an account on Java.net. I wasn't able to install the plugin due to
some subversion dependencies that I can't update because of our
behind-the-times set up in the office.

Is there a web based version of the Issue Tracker?


Yes, but you will still require an account on java.net to create an issue. Also, as is ever so common java.net is currently having one its slower (i say slower because it is always slow) periods. When things are working correctly and at normal slowness you can visit:


and on the right hand side you should see a link to issues (or search for the word "issue" on that page).

Paul.
Reply | Threaded
Open this post in threaded view
|

Re: Required parameters on a Resource

DirkM
Ok I've added an issue:
https://jersey.dev.java.net/issues/show_bug.cgi?id=351
Thanks again for your help.
Dirk
Reply | Threaded
Open this post in threaded view
|

Re: Required parameters on a Resource

Paul Sandoz
Administrator

On Aug 18, 2009, at 9:23 PM, DirkM wrote:

>
> Ok I've added an issue:
> https://jersey.dev.java.net/issues/show_bug.cgi?id=351

Thanks!
Paul.

> Thanks again for your help.
> Dirk
> --
> View this message in context: http://n2.nabble.com/Required-parameters-on-a-Resource-tp3446928p3468037.html
> Sent from the Jersey mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]