当前位置: 首页 > 面试题库 >

无法使用Jersey客户端解组对象的JSON数组

田冥夜
2023-03-14
问题内容

我要解组的单元素JSON数组:

[
   {
      "id":"42",
      "status":"Active",
      "name":"purple monkey dishwasher"
   }
]

相应的Java类(为简便起见,省略了getters和setters方法):

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Badge
{
    @XmlElement(name="id")
    private String id;

    @XmlElement(name="status")
    private Status status;

    @XmlElement(name="name")
    private String name;

    public static enum Status
    {
        Active,
        NotActive
    }
}

发出HTTP请求的Jersey客户代码, 应该 将上述JSON解组为一个元素List<Foo>

Client client = Client.create();
WebResource apiRoot = client.resource("http://localhost:9000/api");
List<Badge> badges = apiRoot.path("/badges").get(new GenericType<List<Badge>>(){});

最后一行,特别是WebResource#get()调用,抛出以下异常

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"status"). Expected elements are <{}badge>
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:253)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:120)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1063)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:498)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480)
    at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:75)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:247)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:181)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:369)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:341)
    at com.sun.jersey.core.provider.jaxb.AbstractListElementProvider.readFrom(AbstractListElementProvider.java:232)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:552)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:522)
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:617)
    at com.sun.jersey.api.client.WebResource.get(WebResource.java:191)
    at com.redacted.badge.client.BadgerImpl.findAllBadges(BadgerImpl.java:105)
    at com.redacted.webapp.admin.BadgeAction.unspecified(BadgeAction.java:40)
    at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:245)
    at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
    at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
    at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
    at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
    at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
    at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
    at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
    at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
    at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:119)
    at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.redacted.webapp.filter.MemberFilter.doFilter(MemberFilter.java:83)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.redacted.webapp.filter.AuthFilter.doFilter(AuthFilter.java:113)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.redacted.webapp.filter.LanguageHandlingFilter.doFilter(LanguageHandlingFilter.java:151)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.redacted.webapp.filter.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:146)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.redacted.webapp.filter.PartnerFilter.doFilter(PartnerFilter.java:59)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.redacted.webapp.filter.SessionStatusFilter.doFilter(SessionStatusFilter.java:113)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at com.googlecode.psiprobe.Tomcat60AgentValve.invoke(Tomcat60AgentValve.java:30)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:680)

我已经尝试在上使用各种注释组合Badge,或者使用数组代替GenericType

List<Badge> badges = Arrays.asList(apiRoot.path("/badges").get(Badge[].class));

或使用中间体ClientResponse

GenericType<List<Badge>> type = new GenericType<List<Badge>>(){};
ClientResponse clientResponse = apiRoot.path("/badges").get(ClientResponse.class);
List<Badge> badges = clientResponse.getEntity(type);

但到目前为止,没有一个解决了这个问题。

更令人困惑的是,我现有的设置在解组其他结构内部的JSON编码时 没有问题Badge,如下所示:

{
   "userid":"123456789",
   "userbadges":[
      {
         "badge":{
              "id":"42",
              "status":"Active",
              "name":"purple monkey dishwasher"
         },
         "earned":"2012-03-06 18:16:18.172"
      }
   ]
}

我究竟做错了什么?


问题答案:

通过使用Jersey
Client实例JacksonJsonProviderMessageBody(Reader|Writer)提供程序,我可以轻松解决此问题:

ClientConfig cfg = new DefaultClientConfig();
cfg.getClasses().add(JacksonJsonProvider.class);
Client client = Client.create(cfg);

Jackson的MessageBodyReader实现似乎比Jersey JSON 的实现更好。

感谢我如何自定义将JAXB对象列表序列化为JSON?把我指向杰克逊的方向。



 类似资料:
  • 问题内容: 如何使用Jersey客户端API将GET请求发送到运行HTTPS协议的服务器。我可以使用任何示例代码吗? 问题答案: 这样构建您的客户 从此博客文章中窃取了更多详细信息:http : //blogs.oracle.com/enterprisetechtips/entry/consumption_restful_web_services_with 有关设置证书的信息,请参见以下已很好回答

  • 类似于Jersey:带有1个元素的Json数组被序列化为object,但在客户端。例如,我收到一个JSON对象,其中一个字段是一个数组,但如果只有一个元素,它就是一个单独的对象。 对 我正在使用 Jersey/Genson 解析/取消编组 JSON。当然,如果JSON与目标类不匹配,我会收到错误(例如) 我已经阅读了很多关于这个错误以及如何在服务器端创建JSON对象时如何避免的信息,但是我没有发现

  • 问题内容: 我有一个JSON,它可以是单个对象或相同对象的数组。有没有一种方法可以使用Gson解析此数据,从而区分单个对象还是数组? 我目前唯一的解决方案是手动解析json并用try catch包围它。首先,我将尝试将其解析为单个对象,如果失败,它将引发异常,然后尝试将其解析为数组。 我不想手动解析它……那将使我永远。这是正在发生的事情的想法。 这是可以是数组或单个对象的对象。 然后在与json响

  • 问题内容: 我试图从JSON数组中获取每个JSON对象。我通过HTTP发布获得此数据。 我知道我的数据是什么样的: 我的示例代码和结构如下所示: 我不确定如何遍历JSON数组并获取JSON对象,然后仅使用JSON对象。 问题答案: 试试这个作为您的结构, 您的名称不正确,顶层名称也不正确。解码为a之后,您可以遍历切片以获取每个切片

  • 我正在将Jackson从1.9.4升级到2.2.0。过渡非常顺利,只是我似乎无法对对象进行数组解析。在1.9.4中,我可以这样做: 在Jackson 2.2.0中,我得到了一个“无法解析方法”编译时错误。Jackson 1.9.4的ObjectMapper头文件包含以下JsonNodes的readValue方法: 和Jackson 2.2.0的头文件: 所以我需要从传递JsonNode切换到Jso

  • 服务器JSON数据显示在活动中使用改造。JSON数据通过gson转换。 给错误:"java.lang.IllegalState异常:预期BEGIN_ARRAY但BEGIN_OBJECT在第1行第2列路径$" JSON格式: 代码: 主要活动。kt