Show Table of Contents
44.3. Parameter Converters
Overview
Using parameter converters, it is possible to inject a parameter (of
String type) into any type of field, bean property, or resource method argument. By implementing and binding a suitable parameter converter, you can extend the JAX-RS runtime so that it is capable of converting the parameter String value to the target type.
Automatic conversions
Parameters are received as instances of
String, so you can always inject them directly into fields, bean properties, and method parameters of String type. In addition, the JAX-RS runtime has the capability to convert parameter strings automatically to the following types:
- Primitive types.
- Types that have a constructor that accepts a single
Stringargument. - Types that have a static method named
valueOforfromStringwith a single String argument that returns an instance of the type. List<T>,Set<T>, orSortedSet<T>, ifTis one of the types described in 2 or 3.
Parameter converters
In order to inject a parameter into a type not covered by automatic conversion, you can define a custom parameter converter for the type. A parameter converter is a JAX-RS extension that enables you to define conversion from
String to a custom type, and also in the reverse direction, from the custom type to a String.
Factory pattern
The JAX-RS parameter converter mechanism uses a factory pattern. So, instead of registering a parameter converter directly, you must register a parameter converter provider (of type,
javax.ws.rs.ext.ParamConverterProvider), which creates a parameter converter (of type, javax.ws.rs.ext.ParamConverter) on demand.
ParamConverter interface
The
javax.ws.rs.ext.ParamConverter interface is defined as follows:
// 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);
}
To implement your own
ParamConverter class, you must implement this interface, overriding the fromString method (to convert the parameter string to your target type) and the toString method (to convert your target type back to a string).
ParamConverterProvider interface
The
javax.ws.rs.ext.ParamConverterProvider interface is defined as follows:
// 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[]);
}
To implement your own
ParamConverterProvider class, you must implement this interface, overriding the getConverter method, which is a factory method that creates ParamConverter instances.
Binding the parameter converter provider
To bind the parameter converter provider to the JAX-RS runtime (thus making it available to your application), you must annotate your implementation class with the
@Provider annotation, as follows:
// Java
...
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
@Provider
public class TargetTypeProvider implements ParamConverterProvider {
...
}
This annotation ensures that your parameter converter provider is automatically registered during the scanning phase of deployment.
Example
The following example shows how to implement a
ParamConverterProvider and a ParamConverter which has the capability to convert parameter strings to and from the TargetType type:
// 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;
}
}Using the parameter converter
Now that you have defined a parameter converter for
TargetType, it is possible to inject parameters directly into TargetType fields and arguments, for example:
// Java
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
...
@POST
public Response updatePost(@FormParam("target") TargetType target)
{
...
}Lazy conversion of default value
If you specify default values for your parameters (using the
@DefaultValue annotation), you can choose whether the default value is converted to the target type right away (default behaviour), or whether the default value should be converted only when required (lazy conversion). To select lazy conversion, add the @ParamConverter.Lazy annotation to the target type. For example:
// 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)
{
...
}
Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.