繁体   English   中英

泽西杰克逊解散了JSON

[英]Jersey Jackson unmarshall JSON

我正在开发一个嵌入式泽西实例,它将运行JAXB RESTful服务。 我已经为Jackson配置了两个步骤:

  1. 将此添加到我的POM

     <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.23.2</version> </dependency> 
  2. 在我的应用程序中注册它

     public HandheldApplication() { scripts.add(HandheldServer.class); scripts.add(BasicScript.class); // Add JacksonFeature. scripts.add(JacksonFeature.class); scripts.add(LoggingFilter.class); 

    }

我有一个复杂的对象来回传递,如下所示:

package com.ziath.handheldserver.valueobjects;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.*;

@SuppressWarnings("restriction")
@XmlRootElement
public class Widget {

private String key;
private String name;
private List<String> options = new ArrayList<String>();
private String value;
private String type;

public Widget(){
    super();
}

public Widget(String key, String name, List<String> options, String value,
        String type) {
    super();
    this.key = key;
    this.name = name;
    this.options = options;
    this.value = value;
    this.type = type;
}

public String getKey() {
    return key;
}
public void setKey(String key) {
    this.key = key;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public List<String> getOptions() {
    return options;
}
public void setOptions(List<String> options) {
    this.options = options;
}
public String getValue() {
    return value;
}
public void setValue(String value) {
    this.value = value;
}
public String getType() {
    return type;
}
public void setType(String type) {
    this.type = type;
}

}

当我在GET方法中执行它时,如下所示:

@Override
@GET
@Path("getKeys")
@Produces(MediaType.APPLICATION_JSON)
public List<Widget> getKeys(@QueryParam(value = "page") int page) 

这很好,我得到了JSON; 但是当我执行它时,它是一个PUT,如下所示:

@Override
@PUT
@Path("validateKeys")
@Produces({MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_JSON)
public boolean validateKeys(@QueryParam(value = "page")int page, @QueryParam(value = "widgets")List<Widget> widgets) 

当我执行PUT来访问这个方法时,我得到一个堆栈跟踪如下:

Caused by: org.glassfish.jersey.internal.inject.ExtractorException: Error un-marshalling JAXB object of type: class com.ziath.handheldserver.valueobjects.Widget.
    at org.glassfish.jersey.jaxb.internal.JaxbStringReaderProvider$RootElementProvider$1.fromString(JaxbStringReaderProvider.java:195)
    at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.convert(AbstractParamValueExtractor.java:139)
    at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.fromString(AbstractParamValueExtractor.java:130)
    at org.glassfish.jersey.server.internal.inject.CollectionExtractor.extract(CollectionExtractor.java:88)
    at org.glassfish.jersey.server.internal.inject.CollectionExtractor$ListValueOf.extract(CollectionExtractor.java:107)
    at org.glassfish.jersey.server.internal.inject.QueryParamValueFactoryProvider$QueryParamValueFactory.provide(QueryParamValueFactoryProvider.java:89)
    ... 38 more
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.]
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:563)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:249)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:140)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:123)
    at org.glassfish.jersey.jaxb.internal.JaxbStringReaderProvider$RootElementProvider$1.fromString(JaxbStringReaderProvider.java:190)
    ... 43 more

所以在我看来,杰克逊正确地将我的POJO 编组为JSON,但试图将其解组为XML。 请注意,我切换到杰克逊远离MOXy,因为我需要能够处理来回收集的集合,显然MOXy不能这样做。

是否有一个我错过的设置告诉杰克逊/泽西为JSON双向走?

尝试删除@QueryParam(value = "widgets")因为你应该将它作为实体体传递 - 而不是查询参数。

@PUT
@Path("validateKeys")
@Produces({MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_JSON)
public boolean validateKeys(@QueryParam(value = "page")int page, List<Widget> widgets) 

你也可以制作包装类:

@XmlRootElement
public class Widgets {

    private List<Widget> widgets; 

    // other fields, setters and getters
}

接着:

@PUT
@Path("validateKeys")
@Produces({MediaType.APPLICATION_JSON})
@Consumes(MediaType.APPLICATION_JSON)
public boolean validateKeys(@QueryParam(value = "page")int page, Widgets widgets) 

我建议阅读一些关于REST设计的讨论,因为你在路径中使用动词:

我在QueryParam和FormParam之间切换,试图让其中一个工作。 如果我使用FormParam,我还需要将消耗更改为APPLICATION_FORM_URLENCODED。

实际问题是Jackson的默认解组是使用XML,因为它被标记为XML资源 - 拿出来! 我终于设法通过使用静态fromString方法来解决如何从JSON解组。 然后处理清单; 我不能使用包装器类,因为它需要高度交叉语言,并且使用列表暴露包装器会使Python,C#等的实现变得复杂。使用包装器接受列表的方法是发布名称param(在这种情况下是小部件)多次。 然后将针对fromString方法调用传入的每个JSON。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM