泽西杰克逊解散了JSON

时间:2016-08-30 17:12:21

标签: json jersey jackson jax-rs

我正在开发一个嵌入式运动衫实例,它将运行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);
    

    }

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

    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不能这样做。

    有没有让我错过的设置告诉Jackson / Jersey为JSON双向进行?

2 个答案:

答案 0 :(得分:0)

尝试删除const State state = _sourceModel->data(index, Qt::UserRole).toInt(&); return state == Valid; ,因为您应该将其作为实体主体传递 - 而不是查询参数。

@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
}

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

答案 1 :(得分:0)

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

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