Форматирование LocalDateTime для JAX-RS - PullRequest
0 голосов
/ 17 мая 2018

Я использую resteasy-jaxrs в сочетании с jackson-datatype-jsr310 для сериализации LocalDateTime в ответе.Это прекрасно работает для свойств в моих классах, потому что я могу добавить необходимую аннотацию, такую ​​как

@XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
public LocalDateTime getExpirationDate() {
    return expirationDate;
}

, используя LocalDateTimeAdapter

public class LocalDateTimeAdapter extends XmlAdapter<String, LocalDateTime> {
    @Override
    public LocalDateTime unmarshal(String s) throws Exception {
        return LocalDateTime.parse(s);
    }

    @Override
    public String marshal(LocalDateTime dateTime) throws Exception {
        return dateTime.toString();
    }
}

В json я получаю что-то вроде

"expirationDate": "2026-07-17T23:59:59"

Но у меня есть карта объектов, и эта карта также может иметь элементы типа LocalDateTime, и для них нет аннотаций, и поэтому я получаю полный объект в ответе json, например

"effectiveDate":       {
  "dayOfMonth": 1,
  "dayOfWeek": "FRIDAY",
  "month": "JUNE",
  "year": 2018, ...

Isесть ли способ отформатировать каждое поле LocalDateTime, независимо от того, откуда оно взято?

ОБНОВЛЕНИЕ после ответа Павла

Поскольку я уже использую com.fasterxml.jackson.datatype: зависимость jackson-datatype-jsr310, я добавил класс ObjectMapperContextResolver и удалил аннотацию из моего свойства LocalDateTime.К сожалению, все LocalDateTimes теперь снова сериализованы как полный объект.В комментариях к посту я увидел, что кто-то добавил контекстный параметр в web.xml, чтобы подобрать ObjectMapperContextResolver.После добавления этого в мой web.xml это выглядит следующим образом.

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
    <display-name>Servlet 3.1 Web Application</display-name>
    <listener>
        <listener-class>com.kopi.web.InitListener</listener-class>
    </listener>
    <context-param>
        <param-name>resteasy.resources</param-name>
        <param-value>com.kopi.utils.ObjectMapperContextResolver</param-value>
    </context-param>
</web-app>

Теперь, после добавления context-param resteasy.resources, веб-приложение больше не запускается из-за

SEVERE: Servlet [com.kopi.rest.RestApplication] in web application [/kopi] threw load() exception
java.lang.RuntimeException: RESTEASY003130: Class is not a root resource.  It, or one of its interfaces must be annotated with @Path: com.kopi.utils.ObjectMapperContextResolver implements:  javax.ws.rs.ext.ContextResolver
    at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:179)
    at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:158)
    at org.jboss.resteasy.core.ResourceMethodRegistry.addPerRequestResource(ResourceMethodRegistry.java:77)
    at org.jboss.resteasy.spi.ResteasyDeployment.registration(ResteasyDeployment.java:482)
    at org.jboss.resteasy.spi.ResteasyDeployment.startInternal(ResteasyDeployment.java:279)
    at org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:86)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.init(ServletContainerDispatcher.java:119)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.init(HttpServletDispatcher.java:36)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1194)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1110)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1000)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4902)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5212)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:724)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:700)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:596)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1805)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

В других комментариях я видел, что версии могут быть проблемой.Поэтому я сейчас использую

org.jboss.resteasy:resteasy-jaxrs 3.5.1.Final
org.jboss.resteasy:resteasy-jackson-provider 3.5.1.Final
org.jboss.resteasy:resteasy-servlet-initializer 3.5.1.Final
com.fasterxml.jackson.datatype:jackson-datatype-jsr310 2.9.5

Спасибо, копи

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

@XmlJavaTypeAdapter может применяться ко всей упаковке ( см. Документ ).

Когда аннотация @XmlJavaTypeAdapter определена на уровне пакета, она относится ко всем ссылкам из пакета на @ XmlJavaTypeAdapter.type ().

Попробуйте добавить файл package-info.java рядом с классом, в котором есть карта. Учитывая, что пакет класса com.acme.beans, а пакета адаптера - com.acme.adapters, содержимое файла должно быть примерно таким:

@XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
package com.acme.beans;

import com.acme.adapters.LocalDateTimeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
0 голосов
/ 17 мая 2018

Вместо XmlAdapter, который необходимо объявить для отдельных свойств, вы можете просто настроить его глобально с Джексоном, используя ContextResolver.Здесь вы можете настроить ObjectMapper и зарегистрировать JavaTimeModule с помощью картографа.Эта конфигурация будет глобальной, поэтому вам не нужно использовать XmlAdapter.Чтобы увидеть, как вы можете настроить это, вы можете увидеть это сообщение .

...