Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fromString method of ParamConverter is not called on Null values in JAX-RS

I have written a ParamConverterProvider and a ParamConverter in order to let JAX-RS (Jersey) instantiate an enum in HeaderParam. The converter looks like this

@Provider
public class MyEnumParamConverterProvider implements ParamConverterProvider {


    public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
        if (rawType.equals(MyEnum.class)) {
            return (ParamConverter<T>) new MyEnumParamConverter();
        }
        return null;
    }

    private static class MyEnumParamConverter implements ParamConverter<MyEnum> {

        @Override
        public MyEnum fromString(String enum) {
            return MyEnum.of(enum);
        }

        @Override
        public String toString(MyEnum enum) {
            return enum.toString();
        }
    }
}

However the fromString method is not called when the Header is not sent because on Jersey code in class SingleValueExtractor in method org.glassfish.jersey.server.internal.inject.SingleValueExtractor.extract(MultivaluedMap<String, String>) there is a code on line 82 which checks whether the parameter value is null or not and if it is !=null then the fromString method is called.

public T extract(MultivaluedMap<String, String> parameters) {
        String v = parameters.getFirst(getName());
        if (v != null) {
            try {
                return fromString(v);
            } catch (WebApplicationException ex) {
                throw ex;
            } catch (ProcessingException ex) {
                throw ex;
            } catch (Exception ex) {
                throw new ExtractorException(ex);
            }
        } else {
            return defaultValue();
        }     
}

What I actually want is to circumvent this part and let my fromString get called even on null values because of some special exception handling there.

Is there any way that to that. I don't want to use bean validation like @NotNull so that I handle everything in one place.

like image 261
LAC Avatar asked Nov 17 '15 23:11

LAC


1 Answers

If you can change Jersey versions, I would do so. It seems this behavior occurs 2.13 and prior. 2.14 and later this problem is fixed, where the implementation has changed

@Override
public T extract(MultivaluedMap<String, String> parameters) {
    String v = parameters.getFirst(getName());
    try {
        return fromString((v == null && isDefaultValueRegistered()) 
                                     ? getDefaultValueString() : v);
    } catch (WebApplicationException ex) {
        throw ex;
    } catch (ProcessingException ex) {
        throw ex;
    } catch (IllegalArgumentException ex) {
        return defaultValue();
    } catch (Exception ex) {
        throw new ExtractorException(ex);
    }
}

Where prior, a null would lead to defaultValue() (which is just a null result), now all values get passed to the fromString, which ends up calling your fromString

like image 61
Paul Samsotha Avatar answered Oct 20 '22 12:10

Paul Samsotha