@JsonFormat for parsing dates in JAX-RS service is ignored

I am trying to pass a date to the JAX-RS service. Checking for other issues, such as: Date format Mapping to JSON Jackson

The answers and documentation show that there is an annotation for Jackson that should allow date formatting.

public class SolutionFilter {
    @MatrixParam("toDate")
    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd", timezone="CET")
    private Date toDate;

    public void setToDate(Date toDate) {
        this.toDate = toDate;
    }
}

After calling the Rest-Service, I get ParseException:

Caused by: java.text.ParseException: Unparseable date: "2016-01-01"
  at java.text.DateFormat.parse(DateFormat.java:366)
  at org.glassfish.jersey.message.internal.HttpDateFormat.readDate(HttpDateFormat.java:137)
  at org.glassfish.jersey.server.internal.inject.ParamConverters$DateProvider$1.fromString(ParamConverters.java:259)

The annotation seems to be ignored. When debugging a parsing method, the template has the value EEE, dd MMM yyyy HH:mm:ss zzzand EEE MMM d HH:mm:ss yyyy.

I am using Spring 4.2.1, Jersey 2.22, which bundles jackson 2.5.4.

How can I get dates processed with the correct template?

: , JSON . , , JAX-RS.

+4
1

ParamConverter. stacktrace, ParamConverters $DateProvider. HttpDateFormat, .

, , . HTTP

/**
 * The date format pattern for RFC 1123.
 */
private static final String RFC1123_DATE_FORMAT_PATTERN = "EEE, dd MMM yyyy HH:mm:ss zzz";
/**
 * The date format pattern for RFC 1036.
 */
private static final String RFC1036_DATE_FORMAT_PATTERN = "EEEE, dd-MMM-yy HH:mm:ss zzz";
/**
 * The date format pattern for ANSI C asctime().
 */
private static final String ANSI_C_ASCTIME_DATE_FORMAT_PATTERN = "EEE MMM d HH:mm:ss yyyy";

, , . - .

@Provider
public class DateParamConverterProvider implements ParamConverterProvider {

    private final String format;

    public DateParamConverterProvider(String dateFormat) {
        this.format = dateFormat;
    }

    @Override
    public <T> ParamConverter<T> getConverter(Class<T> rawType, 
                                              Type genericType, 
                                              Annotation[] annotations) {

        if (rawType != Date.class) { return null; }

        return (ParamConverter<T>) new ParamConverter<Date>() {

            @Override
            public Date fromString(String value) {
                SimpleDateFormat formatter = new SimpleDateFormat(format);
                try {
                    return formatter.parse(value);
                } catch (Exception ex) {
                    throw new WebApplicationException("Bad formatted date", 400);
                }
            }

            @Override
            public String toString(Date date) { 
                return new SimpleDateFormat(format).format(date); 
            }
        };
    }
}

public class DateParamTest extends JerseyTest {

    private static final String FORMAT = "MM-dd-yyyy";

    @Path("date")
    public static class DateResource {
        @GET
        public String get(@MatrixParam("since") Date date) {
            return new SimpleDateFormat(FORMAT).format(date);
        }
    }

    @Override
    public ResourceConfig configure() {
        return new ResourceConfig(DateResource.class)
                .register(new DateParamConverterProvider(FORMAT));
    }

    @Test
    public void should_return_same_date_and_format() {
        final String date = "09-30-2015";
        Response response = target("date").matrixParam("since", date)
                .request().get();
        assertEquals(200, response.getStatus());
        String returnDate = response.readEntity(String.class);
        assertEquals(date, returnDate);
        System.out.println(returnDate);
    }
}

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>${jersey2.version}</version>
    <scope>test</scope>
</dependency>

. :

+3

Source: https://habr.com/ru/post/1609608/


All Articles