不对 JAX-RS 中的 Null 值调用 ParamConverter 的 fromString 方法
fromString method of ParamConverter is not called on Null values in JAX-RS
为了让 JAX-RS (Jersey) 在 HeaderParam 中实例化一个枚举,我写了一个 ParamConverterProvider 和一个 ParamConverter。转换器看起来像这样
@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();
}
}
}
然而,当没有发送 Header 时,不会调用 fromString 方法,因为在 Jersey 代码中 class SingleValueExtractor in method org.glassfish.jersey.server.internal.inject.SingleValueExtractor.extract(MultivaluedMap<String, String>)
第 82 行有一段代码检查参数值是否为null 与否,如果它是 !=null 则调用 fromString 方法。
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();
}
}
我真正想要的是绕过这部分,让我的 fromString 甚至在空值上被调用,因为那里有一些特殊的异常处理。
有什么办法吗?我不想使用像 @NotNull 这样的 bean 验证,这样我就可以在一个地方处理所有事情。
如果您可以更改 Jersey 版本,我会这样做。这种行为似乎发生在 2.13 及之前。 2.14 及更高版本修复了此问题,其中 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);
}
}
之前,null 会导致 defaultValue()
(这只是一个 null
结果),现在 所有 值都传递给 fromString
,最终调用 你的 fromString
为了让 JAX-RS (Jersey) 在 HeaderParam 中实例化一个枚举,我写了一个 ParamConverterProvider 和一个 ParamConverter。转换器看起来像这样
@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();
}
}
}
然而,当没有发送 Header 时,不会调用 fromString 方法,因为在 Jersey 代码中 class SingleValueExtractor in method org.glassfish.jersey.server.internal.inject.SingleValueExtractor.extract(MultivaluedMap<String, String>)
第 82 行有一段代码检查参数值是否为null 与否,如果它是 !=null 则调用 fromString 方法。
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();
}
}
我真正想要的是绕过这部分,让我的 fromString 甚至在空值上被调用,因为那里有一些特殊的异常处理。
有什么办法吗?我不想使用像 @NotNull 这样的 bean 验证,这样我就可以在一个地方处理所有事情。
如果您可以更改 Jersey 版本,我会这样做。这种行为似乎发生在 2.13 及之前。 2.14 及更高版本修复了此问题,其中 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);
}
}
之前,null 会导致 defaultValue()
(这只是一个 null
结果),现在 所有 值都传递给 fromString
,最终调用 你的 fromString