【问题标题】:Jersey: list of JSON objects泽西岛:JSON 对象列表
【发布时间】:2011-10-04 13:40:22
【问题描述】:

我试图在我的 Jersey 实现资源类中检索这样的对象集合:

@POST
@Path("/send")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String sendEmails(ArrayList<AnyEmail> email) {
    //emailManager.sendEmail(email);
    return "success";
}

我在`AnyEmail 上方有@XmlRootElement

但是,当我使用 REST 客户端工具这样发布时:

 emails : [
       {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"},
       {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"}
      ]

我明白了:

<html><head><title>Apache Tomcat/7.0.22 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server encountered an internal error () that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>javax.servlet.ServletException: Servlet execution threw an exception
</pre></p><p><b>root cause</b> <pre>java.lang.Error: Error: could not match input
    com.sun.jersey.json.impl.reader.JsonLexer.zzScanError(JsonLexer.java:491)
    com.sun.jersey.json.impl.reader.JsonLexer.yylex(JsonLexer.java:736)

已编辑
现在我尝试了:

 "emails" : [
           {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"},
           {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"}
          ]

我得到:

    SEVERE: Servlet.service() for servlet [Jersey Web Application] in context with path [/API] threw exception
java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.get(ArrayList.java:324)
    at com.sun.jersey.json.impl.reader.JsonXmlStreamReader.valueRead(JsonXmlStreamReader.java:165)
    at com.sun.jersey.json.impl.reader.JsonXmlStreamReader.readNext(JsonXmlStreamReader.java:330)

【问题讨论】:

  • 我相信你应该发送 JSON 数组而不是 JSON 对象。尝试仅发送 [{...},{...}] 段作为请求实体。
  • 当我这样做时,我得到:javax.ws.rs.WebApplicationException:javax.xml.bind.UnmarshalException - 带有链接异常:[javax.xml.bind.UnmarshalException:意外元素(uri:“ ”,本地:“身体”)。预期元素是 ]

标签: json rest jersey


【解决方案1】:

为什么不使用简单的 Java 数组???

[
   {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"},
   {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"}
]

然后是下面的方法:

@POST
@Path("/send")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String sendEmails(AnyEmail[] emails) {
    //emailManager.sendEmail(emails);
    return "success";
}

这应该可以解决问题...

【讨论】:

    【解决方案2】:

    这应该是可行的:

    {
    "anyEmail" : [
           {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"},
           {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"}
           ]
    }
    

    此外,您可能希望使用 POJO 方法,这是 JSON 的首选方法 - 请参阅此处:https://jersey.java.net/documentation/1.18/json.html

    基于 JAXB 的 JSON 支持在某些极端情况下存在各种问题,因为 XML(设计用于 JAXB)和 JSON 之间没有 1:1 的映射。

    【讨论】:

    • 在映射 JSON 表示法的情况下,这是可消耗的格式,对吧?如果使用 natural ,只传递一个 JSON 数组应该可以吗?
    【解决方案3】:

    我既不是 Jersey 也不是 Json 专家,但您是否尝试过使用完整的 JSON 对象,即:

    {
    "emails" : [
           {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"},
           {"body": "Testing the web service", "header": "Hi", "footer": "<br/>test"}
          ]
    }
    

    (在电子邮件中添加大括号和引号)。

    【讨论】:

    • 这听起来好多了。 “错误请求”是预期的返回代码。我想在这里输入,例如 AnyEmail 可以映射到 {"body": "", "header": "", "footer": ""} 吗?没有其他想法;)
    【解决方案4】:

    我遇到了同样的问题。您必须包装 AnyEmail 类。

    这可以帮助你:https://blogs.oracle.com/japod/entry/missing_brackets_at_json_one

    【讨论】:

      【解决方案5】:

      // 客户端

      package com.project.rest.model;
      
      import java.util.HashSet;
      import java.util.Set;
      
      public class Client {
      
          private Long id;
          private String email;
          private String lang;
      
          public Client() {
          }
      
          public Client(Long id) {
          this.id = id;
          }
      
          public Client(Long id, String email, String lang) {
          this.id = id;
          this.email = email;
          this.lang = lang;
          }
      
          public Long getId() {
          return id;
          }
      
          public void setId(Long id) {
          this.id = id;
          }
      
          public String getEmail() {
          return email;
          }
      
          public void setEmail(String email) {
          this.email = email;
          }
      
          public String getLang() {
          return lang;
          }
      
          public void setLang(String lang) {
          this.lang = lang;
          }
      
      
          @Override
          public String toString() {
          return "Client [id=" + id + ", email=" + email + ", lang=" + lang + "]";
          }
      
      }
      

      //客户端服务

      package com.project.rest;
      
      import java.util.List;
      
      import javax.ws.rs.Consumes;
      import javax.ws.rs.GET;
      import javax.ws.rs.POST;
      import javax.ws.rs.Path;
      import javax.ws.rs.PathParam;
      import javax.ws.rs.Produces;
      import javax.ws.rs.core.MediaType;
      import javax.ws.rs.core.Response;
      
      import com.project.rest.model.Client;
      
      @Path("/client")
      public class ClientService {
      
          @POST
          @Path("/sendList")
          @Consumes(MediaType.APPLICATION_JSON)
          @Produces(MediaType.APPLICATION_JSON)
          public Response consumeJSONList(List<Client> clientList) {
      
              String output = "consumeJSONList Client : " + clientList.toString() + "\n\n";
      
              return Response.status(200).entity(output).build();
          }
      
      }
      

      //JerseyClient

      package com.project.rest;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import javax.ws.rs.core.MediaType;
      
      import com.project.rest.model.Client;
      import com.project.rest.model.Device;
      import com.sun.jersey.api.client.ClientResponse;
      import com.sun.jersey.api.client.WebResource;
      import com.sun.jersey.api.client.config.ClientConfig;
      import com.sun.jersey.api.client.config.DefaultClientConfig;
      import com.sun.jersey.api.json.JSONConfiguration;
      
      public class JerseyClient {
      
      public static void main(String[] args) {
      
      try {
      
          List<Client> clientList = new ArrayList<Client>();
          clientList.add(new Client(1L, "pruebas@pruebas.com", "es"));
          clientList.add(new Client(2L, "pruebas@pruebas.com", "es"));
          clientList.add(new Client(3L, "pruebas@pruebas.com", "es"));
      
          ClientConfig clientConfig = new DefaultClientConfig();
      
          clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
      
          com.sun.jersey.api.client.Client c = com.sun.jersey.api.client.Client.create(clientConfig);
      
          WebResource webResource = c.resource("http://localhost:8080/project_rest/rest/client/sendList");
      
          ClientResponse response = webResource.accept("application/json").type("application/json").post(ClientResponse.class, clientList);
      
          if (response.getStatus() != 200) {
          throw new RuntimeException("Failed sendClientList: HTTP error code : " + response.getStatus());
          }
      
          String output = response.getEntity(String.class);
      
          System.out.println("sendClientList... Server response .... \n");
          System.out.println(output);
      
      } catch (Exception e) {
      
          e.printStackTrace();
      
      }
      }
      }
      

      //POM.xml

      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.8.2</version>
          <scope>test</scope>
      </dependency>
      
      <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-bundle</artifactId>
          <version>1.10-b01</version>
      </dependency>
      
      <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-server</artifactId>
          <version>1.17.1</version>
      </dependency>
      <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-core</artifactId>
          <version>1.17.1</version>
      </dependency>
      <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-servlet</artifactId>
          <version>1.17.1</version>
      </dependency>
      <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-json</artifactId>
          <version>1.18.1</version>
      </dependency>
      <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>0.99</version>
      </dependency>
      

      【讨论】:

        【解决方案6】:

        我正在使用 Jersey 1.17,可以接收具有以下签名的 JSON 对象列表,并使用 Google 的 gson 库将它们转换为我的 POJO 对象列表,没有任何问题。使用 wrapper 来包装 POJO 对象的列表,当然是不自然的,也是不利的。

           @POST
        @Consumes(MediaType.APPLICATION_JSON)
        @Produces({"application/x-javascript", MediaType.APPLICATION_JSON})
        public Response doSomething(@Context HttpServletRequest httpServletRequest, JSONArray listOfJSONObjects) {
            Gson gson = new GsonBuilder().create();
            List < MYPOJOClass > myPojoObjectList = gson.fromJson(listOfJSONObjects.toString(), new TypeToken < List < MYPOJOClass >> () {}.getType());
        

        【讨论】:

          猜你喜欢
          • 2013-03-13
          • 2015-09-07
          • 2011-10-14
          • 2015-01-05
          • 1970-01-01
          • 2014-10-06
          • 1970-01-01
          • 2011-08-02
          • 2012-09-19
          相关资源
          最近更新 更多