47.3. 参数 Converters
概述
使用参数转换器,可以将参数( String
类型)注入 任何类型的 字段、bean 属性或资源方法参数。通过实施并绑定合适的参数转换器,您可以扩展 JAX-RS 运行时,使它能够将参数 String 值转换为目标类型。
自动转换
参数作为 String
的实例接收,因此您始终可以直接将它们注入到字段、bean 属性和 String
类型的方法参数中。另外,JAX-RS 运行时会自动将参数字符串转换为以下类型:
- 原语类型.
-
具有接受单个
String
参数的构造器类型。 -
具有名为
valueOf
或fromString
的静态方法类型,该类型包含一个 String 参数,后者返回类型为 的实例。 -
如果
T
是 2 或 3 中描述的类型之一,则 list<T
>、Set<
<T>。T
> 或 SortedSet
参数转换器
要将参数注入自动转换中未涵盖的类型,您可以为该类型定义自定义 参数转换器。参数转换器是一个 JAX-RS 扩展,可用于定义从 String
转换为自定义类型,并在反向方向中定义从自定义类型转换为 String
。
factory pattern
JAX-RS 参数转换器机制使用工厂模式。因此,您必须根据需要注册一个参数转换器(类型为 javax.ws.rs.ext.ParamConverterProvider
),它会创建一个参数转换器(类型为 javax.ws.rs.ext.ParamConverter
)。
ParamConverter 接口
javax.ws.rs.ext.ParamConverter
接口定义如下:
// Java package javax.ws.rs.ext; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.ws.rs.DefaultValue; public interface ParamConverter<T> { @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public static @interface Lazy {} public T fromString(String value); public String toString(T value); }
要实现自己的 ParamConverter
类,您必须实现这个接口,覆盖 fromString
方法(将参数字符串转换为您的目标类型)以及 toString
方法(将目标类型转换为字符串)。
ParamConverterProvider interface
javax.ws.rs.ext.ParamConverterProvider
接口定义如下:
// Java package javax.ws.rs.ext; import java.lang.annotation.Annotation; import java.lang.reflect.Type; public interface ParamConverterProvider { public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation annotations[]); }
要实现自己的参数 ConverterProvider
类,您必须实施此接口,覆盖 getConverter
方法,这是创建参数 Converter
实例的一个工厂方法。
绑定参数转换器供应商
要将参数转换器提供程序 绑定到 JAX-RS 运行时(使它提供给您的应用),您必须使用 @Provider
注释标注您的实施类,如下所示:
// Java ... import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; @Provider public class TargetTypeProvider implements ParamConverterProvider { ... }
此注解可确保在部署的扫描阶段自动注册您的参数转换器提供程序。
示例
以下示例演示了如何实施 ParamConverterProvider
和 ParamConverter
,它具有将参数字符串转换为 TargetType
类型的功能:
// Java import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Provider; @Provider public class TargetTypeProvider implements ParamConverterProvider { @Override public <T> ParamConverter<T> getConverter( Class<T> rawType, Type genericType, Annotation[] annotations ) { if (rawType.getName().equals(TargetType.class.getName())) { return new ParamConverter<T>() { @Override public T fromString(String value) { // Perform conversion of value // ... TargetType convertedValue = // ... ; return convertedValue; } @Override public String toString(T value) { if (value == null) { return null; } // Assuming that TargetType.toString is defined return value.toString(); } }; } return null; } }
使用参数转换器
现在,您为 TargetType
定义了参数转换程序,现在可以直接将参数注入到 TargetType
字段和参数中,例如:
// Java import javax.ws.rs.FormParam; import javax.ws.rs.POST; ... @POST public Response updatePost(@FormParam("target") TargetType target) { ... }
延迟默认转换
如果您为参数指定默认值(使用 @DefaultValue
注释),您可以选择默认值是否立即转换为目标类型(默认行为),或者仅应在需要时转换默认值(布局转换)。要选择 lazy 转换,请将 @ParamConverter.Lazy
注解添加到目标类型。例如:
// Java import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.DefaultValue; import javax.ws.rs.ext.ParamConverter.Lazy; ... @POST public Response updatePost( @FormParam("target") @DefaultValue("default val") @ParamConverter.Lazy TargetType target) { ... }