Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 如何将Joda DateTime对象作为HTTP POST的消息体传递给Jersey REST端点?_Json_Jaxb_Jersey_Jodatime_Moxy - Fatal编程技术网

Json 如何将Joda DateTime对象作为HTTP POST的消息体传递给Jersey REST端点?

Json 如何将Joda DateTime对象作为HTTP POST的消息体传递给Jersey REST端点?,json,jaxb,jersey,jodatime,moxy,Json,Jaxb,Jersey,Jodatime,Moxy,我想将org.joda.time.DateTime作为json帖子的消息体传递给Jersey端点。我的球衣用的是莫西。我已经创建了一个自定义XmlAdapter来实现这一点,但我不清楚如何连接这个适配器。我发现的自定义适配器示例在要发布的对象上使用注释,但我不能这样做(我不能在DateTime类上放置注释,因为我不能操作它的源代码) 我正在使用Jersey测试框架来测试这一点 我的球衣终点: @POST @Path("/{memberId}") @Produces(MediaType.APPLI

我想将org.joda.time.DateTime作为json帖子的消息体传递给Jersey端点。我的球衣用的是莫西。我已经创建了一个自定义XmlAdapter来实现这一点,但我不清楚如何连接这个适配器。我发现的自定义适配器示例在要发布的对象上使用注释,但我不能这样做(我不能在DateTime类上放置注释,因为我不能操作它的源代码)

我正在使用Jersey测试框架来测试这一点

我的球衣终点:

@POST
@Path("/{memberId}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResultBean recordDate(@PathParam("memberId") Long memberId, DateTime dateTime) {
    // TODO stuff happens
    return new ResultBean(memberId, dateTime);
}
我的球衣测试:

public class FooEndpointImplTest extends JerseyTest {

@Test
public void testWithDate() {
    Long memberId = 1L;
        DateTime date = new DateTime();
        Entity<DateTime> dateEntity = Entity.json(date);
        ResultBean result = target(
                "/" + memberId)
                .request().post(dateEntity, ResultBean.class);
        assertNotNull(result);
    }
}
public类测试扩展了JerseyTest{
@试验
public void testWithDate(){
长成员ID=1L;
DateTime日期=新的日期时间();
实体dateEntity=Entity.json(日期);
结果Bean结果=目标(
“/”+成员ID)
.request().post(dateEntity,ResultBean.class);
assertNotNull(结果);
}
}
和我的适配器:

package foo;

import javax.xml.bind.annotation.adapters.XmlAdapter;

import org.joda.time.DateTime;

public class DateTimeAdapter extends XmlAdapter<String, DateTime> {

    @Override
    public DateTime unmarshal(String v) throws Exception {
        Long millis = Long.parseLong(v);
        return new DateTime(millis);
    }

    @Override
    public String marshal(DateTime v) throws Exception {
        return Long.toString(v.getMillis());
    }

}
package-foo;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
导入org.joda.time.DateTime;
公共类DateTimeAdapter扩展了XmlAdapter{
@凌驾
公共DateTime解组器(字符串v)引发异常{
Long-millis=Long.parseLong(v);
返回新的日期时间(毫秒);
}
@凌驾
公共字符串封送处理程序(DateTime v)引发异常{
返回Long.toString(v.getMillis());
}
}

当我按原样运行这个测试时,我得到一个500错误。

第一件事:您需要一个用于joda DateTime的
MessageBodyReader/Writer

如果没有一些调整,JSON序列化日期时间的POST看起来将无法工作。Gson序列化的日期时间如下所示:

{ "iMillis": 1414507195233,
  "iChronology": {
    "iBase": {
        "iBase": {
            ...
        },
        "iParam": {
            ...
        }}}}
如果您尝试使用Gson再次反序列化它,Gson将失败,因为
org.joda.time.Chronology
->
iChronology
没有默认的非arg构造函数,Gson需要反序列化该对象。Afaig,在使用任何标准反序列化程序反序列化DateTime时,您都会遇到这样的问题

因此,我最终创建了基于

阅读器:

/。。。
导入org.joda.time.DateTime;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.datatype.joda.JodaModule;
@使用(MediaType.APPLICATION_JSON)
公共类JodaTimeBodyReader实现MessageBodyReader{
私有静态ObjectMapper mapper=新ObjectMapper();
公共JodaTimeBodyReader(){
registerModule(新的JodaModule());
}
@凌驾
公共布尔值可读取(类类型、类型genericType、注释[]注释、MediaType MediaType){
返回类型==DateTime.class;
}
@凌驾
public DateTime readFrom(类类型、类型genericType、注释[]注释、MediaType MediaType、多值Map HttpHeader、InputStream entityStream)引发IOException、WebApplicationException{
试一试{
返回mapper.readValue(entityStream,DateTime.class);
}捕获(例外e){
抛出新的ProcessingException(“反序列化org.joda.time.DateTime时出错。”,e);
}
}
}
作者:

/。。。
导入org.joda.time.DateTime;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.datatype.joda.JodaModule;
@提供者
@使用(MediaType.APPLICATION_JSON)
公共类JodaTimeBodyWriter实现MessageBodyWriter{
私有静态ObjectMapper mapper=新ObjectMapper();
公共JodaTimeBodyWriter(){
registerModule(新的JodaModule());
}
@凌驾
公共布尔值可写(类类型、类型genericType、注释[]注释、MediaType MediaType){
返回类型==DateTime.class;
}
@凌驾
public long getSize(日期时间t、类类型、类型genericType、注释[]注释、MediaType MediaType){
//JAX-RS 2.0已弃用,Jersey运行时已忽略
返回0;
}
@凌驾
public void writeTo(日期时间t、类类型、类型genericType、注释[]注释、MediaType MediaType、多值Map HttpHeader、OutputStream entityStream)引发IOException、WebApplicationException{
试一试{
write(mapper.writeValueAsBytes(t));
}捕获(例外e){
抛出新的ProcessingException(“将org.joda.time.DateTime序列化到输出流时出错”,e);
}
}
}
两者都在ResourceConfig中注册

编写器将以1414507195233(yap,而不是JSON)进行响应,如果您将其发回资源,您将获得有效的DateTime

如果您获得了一个JSON,就像我上面的示例一样,那么现在可以升级读取器来解析iMillis的JSON并使用Long值。对于时区,您也可以使用
dateTime.withZone(…)
来设置值

我使用过的Maven依赖项:

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.5</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-joda</artifactId>
    <version>2.4.0</version>
</dependency>

乔达时间
乔达时间
2.5
com.fasterxml.jackson.datatype
jackson数据类型joda
2.4.0
泽西岛2.12

希望这能有所帮助

而不是:

@POST
@Path("/{memberId}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResultBean recordDate(@PathParam("memberId") Long memberId, DateTime dateTime) {
    // TODO stuff happens
    return new ResultBean(memberId, dateTime);
}
你可以做:

@POST
@Path("/{memberId}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResultBean recordDate(@PathParam("memberId") Long memberId, DateTimeWrapper dateTimeWrapper) {
    // TODO stuff happens
    return new ResultBean(memberId, dateTime);
}
其中
DateTimeWrapper
看起来像。由于
DateTime
对象现在是一个属性,而不是顶层,因此
XmlAdapter
将应用

@XmlAccessorType(XmlAccessType.FIELD)
public class DateTimeWrapper {

    @XmlValue
    @XmlJavaTypeAdapter(YourDateTimeAdapter.class)
    private DateTime value;

}

Jackson和MOXy是两个不同的JSON提供者。我不明白你的意思。问题是如何通过,而不是如何通过与莫西。你的解决方案将工作,但是,它需要杰克逊,而OP写“我的球衣使用莫西”。错误是什么?你能给我们看看stacktrace吗?谢谢@Blaise,这肯定会有用的。我希望找到一种不用添加任何包装的方法。考虑到我找不到只使用config的方法,这可能是最好的方法。@MarkS-您可以编写自己的
MessageBodyReader
/
MessageBodyWriter
,但您需要