JAX-RS 和 java.time.LocalDate 作为输入参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27768866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:59:49  来源:igfitidea点击:

JAX-RS and java.time.LocalDate as input parameter

javajsonHymansonjax-rsjava-8

提问by jorgen.ringen

Problem using JAX-RS and java.time.LocalDate(java8).

使用 JAX-RS 和java.time.LocalDate(java8) 的问题。

I want to pass an object like this into a JAX-RS method using JSON:

我想使用 JSON 将这样的对象传递到 JAX-RS 方法中:

Person {
  java.time.LocalDate birthDay;
}

The exception I get is:

我得到的例外是:

com.fasterxml.Hymanson.databind.JsonMappingException: No suitable constructor found for type [simple type, class java.time.LocalDate]: can not instantiate from JSON object (need to add/enable type information?) at [Source: io.undertow.servlet.spec.ServletInputStreamImpl@21cca2c1; line: 2, column: 3]

com.fasterxml.Hymanson.databind.JsonMappingException:找不到适合类型 [简单类型,类java.time.LocalDate] 的构造函数:无法从 JSON 对象实例化(需要添加/启用类型信息?)在 [来源:io.undertow.servlet.spec.ServletInputStreamImpl@21cca2c1; 行:2,列:3]

How can I create some kind of an interceptor that maps json-dates to java.time.LocalDate? I have tried implemented a MessageBodyReader, but if the LocalDateis a fieldin another class, I have to write a MessageBodyReaderfor each class holding a LocalDate(as far as I've understood).

如何创建某种将 json-dates 映射到的拦截器java.time.LocalDate?我试过实现 a MessageBodyReader,但如果LocalDate是另一个类中的一个字段,我必须MessageBodyReader为每个持有 a 的类编写一个LocalDate(据我所知)。

(Java EE7 (only using the javaee-api and don't want any third party dependencies), JAX-RS, Java 8, Wildfly 8.2)

(Java EE7(仅使用 javaee-api,不需要任何第三方依赖)、JAX-RS、Java 8、Wildfly 8.2)

Any suggestions?

有什么建议?

采纳答案by Paul Samsotha

Normally I'd say to write a Serializer/Deserializer for Hymanson, but since you don't want any other dependencies, you can use a JAXB solutions. Hymanson (with Resteasy) comes with support for JAXB annotations. So what we can do is just write an XmlAdapterto convert from the String to the LocalDate. An example would be something like

通常我会说为 Hymanson 编写一个 Serializer/Deserializer,但由于您不想要任何其他依赖项,您可以使用 JAXB 解决方案。Hymanson(带有 Resteasy)支持 JAXB 注释。所以我们能做的就是写一个XmlAdapter从 String 到LocalDate. 一个例子是这样的

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {

    @Override
    public LocalDate unmarshal(String dateString) throws Exception {
        return LocalDate.parse(dateString, DateTimeFormatter.ISO_DATE);
    }

    @Override
    public String marshal(LocalDate localDate) throws Exception {
        return DateTimeFormatter.ISO_DATE.format(localDate);
    }
}

You can choose any formatting you want, I just used the DateTimeFormatter.ISO_DATE, which will basically look for this format (2011-12-03).

你可以选择任何你想要的格式,我只是使用了DateTimeFormatter.ISO_DATE,它基本上会寻找这种格式(2011-12-03)。

Then all you need to do is annotate the field for getter of the type

然后您需要做的就是为该类型的 getter 注释该字段

public class Person {
    private LocalDate birthDate;

    @XmlJavaTypeAdapter(LocalDateAdapter.class)
    public LocalDate getBirthDate() { return birthDate; }

    public void setBirthDate(LocalDate birthDate) { 
        this.birthDate = birthDate;
    }
}

If you don't want to clutter your model classes with this annotation, then you can simply declare the annotation at the package level.

如果您不想使用此注释使模型类混乱,那么您可以简单地在包级别声明注释。

In a package-info.javafile in the same package as the model class(es), add this

package-info.java与模型类相同的包中的文件中,添加此

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(type = LocalDate.class, 
                        value = LocalDateAdapter.class)
})
package thepackage.of.the.models;

import java.time.LocalDate;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;


Test

测试

@Path("/date")
public class DateResource {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response postPerson(Person person) {
        return Response.ok(DateTimeFormatter.ISO_DATE.format(
                           person.getBirthDate())).build();
    }
}

@Test
public void testResteasy() throws Exception {
    WebTarget target = client.target(
            TestPortProvider.generateURL(BASE_URI)).path("date");
    String person = "{\"birthDate\":\"2015-01-04\"}";
    Response response = target.request().post(Entity.json(person));
    System.out.println(response.readEntity(String.class));
    response.close();
}

Result : 2015-01-04

结果 : 2015-01-04



UPDATE

更新

Also for Hymanson (I know the OP said without dependencies, but this is for others), you can use the Hymanson-datatype-jsr310module. See full solution here

同样对于Hyman逊(我知道 OP 说没有依赖关系,但这是针对其他人的),您可以使用Hymanson-datatype-jsr310模块。在此处查看完整解决方案