Enterprise Java

Converting JAX-RS parameters with ParamConverters

If you want JAX-RS to automatically convert parameters such as query params, path params, or others, you need to create a ParamConverter. Primitive types, strings, and types who define certain conversion methods, such as a valueOf(String) method, are automatically converted. Here’s how to define a converter for LocalDates.

One gotcha I ran into a few times — besides the fact that I helped specifying the standard in the expert group :-) — is that you need to register a LocalDateParamConverterProvider as JAX-RS @Provider which then forwards the parameter to the actual converter. This behavior differs from the MessageBodyWriter or ExceptionMapper types, for example.

The following two classes are required to automatically convert LocalDate types:

import javax.ws.rs.ext.ParamConverter;
import java.time.LocalDate;

public class LocalDateConverter implements ParamConverter<LocalDate> {

    @Override
    public LocalDate fromString(String value) {
        if (value == null)
            return null;
        return LocalDate.parse(value);
    }

    @Override
    public String toString(LocalDate value) {
        if (value == null)
            return null;
        return value.toString();
    }

}

package com.sebastian_daschner.coffee_shop;

import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.time.LocalDate;

@Provider
public class LocalDateParamConverterProvider implements ParamConverterProvider {

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

}

Once the converter and provider are registered, we can use the LocalDate type as parameter for our resource methods:

@Path("test")
@ApplicationScoped
public class TestResource {

    @GET
    public String testIndex(@QueryParam("date") LocalDate date) {
        return "hello, " + date;
    }

    @GET
    @Path("{date}")
    public String test(@PathParam("date") LocalDate date) {
        return "hello, " + date;
    }

}

However, we’re already having conversations in the ongoing JAX-RS specification process to enable both automatic conversion for Java time types, as well as registering converters without the provider, so this solution might be simplified in the future.

Check out the GitHub repository for Jakarta RESTful Web Services and the linked resources to join the discussion.

Published on Java Code Geeks with permission by Sebastian Daschner, partner at our JCG program. See the original article here: Converting JAX-RS parameters with ParamConverters

Opinions expressed by Java Code Geeks contributors are their own.

Sebastian Daschner

Sebastian Daschner is a self-employed Java consultant and trainer. He is the author of the book 'Architecting Modern Java EE Applications'. Sebastian is a Java Champion, Oracle Developer Champion and JavaOne Rockstar.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button