users@jersey.java.net

[Jersey] Re: get parameter source name in ResourceFilterFactory implementation

From: Jakub Podlesak <jakub.podlesak_at_oracle.com>
Date: Tue, 11 Oct 2011 10:58:03 +0200

Hi Odelya,

There might be a bug related to annotation order.
E.g. where @Required @QueryParam("q") String q
should work, @QueryParam("q") @Required String q
could be broken.

Could you please confirm that the above is the case?
If not, could you please share the resource class source
code, where things are broken for you?

Thanks,

~Jakub

On 9.10.2011 17:55, Odelya Holiday wrote:
> 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!
>