【问题标题】:populate a jtable with json string results from a RESTful web service using java使用 java 使用来自 RESTful Web 服务的 json 字符串结果填充 jtable
【发布时间】:2014-10-23 10:31:56
【问题描述】:

我有一个 Web 服务,它根据查询输入一一返回 JSON 字符串,对服务的 GET 请求返回这个(数据库中只有一个条目)

[{"checked":false,"dateposted":"2014-10-23T00:00:00","itemnumber":1,"quantity":5,"stockcheckid":1}]

目前我只是在 while 循环中有这个 System.out.println

我想要做的是能够以一种我可以将它们输入到 jtable 中以显示在客户端应用程序上的方式访问这些结果。我已经阅读了一些关于从 JSON 文件等中读取的指南,但我找不到任何特定于 REST Web 服务的内容。我听说 GSON 提到了很多,我试过了,但我不知道如何让它在这种情况下工作

我还应该提到,该服务还可以以 XML 格式发送这些数据。

我是否以某种方式创建了一个 JSON 文件,将每个新条目附加到它上面?然后从该文件中填充表格?

无论如何,这里是启动 GET 请求的代码。

public static void getRequest(String dataGet) {
  try {
        URL url = new URL("http://localhost:8080/nXXXXXXXXc/webresources/entities.stockchecks/" + dataGet);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Accept", "application/json");

        if (conn.getResponseCode() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                                + conn.getResponseCode());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));

        String output;
        while ((output = br.readLine()) != null) {
                System.out.println(output);
        }

        conn.disconnect();

  } catch (MalformedURLException e) {

        e.printStackTrace();

  } catch (IOException e) {

        e.printStackTrace();

  }

}`

【问题讨论】:

标签: java json swing rest jtable


【解决方案1】:

响应是一张地图。您可以使用 Jackson 将 JSON 映射序列化为 Java 映射,如下所示:

import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JSONtoMap {

    public static final String json = "{\"B\":\"b\",\"C\":\"c\"}";

    public static class POJO{

        private Map<String,String> map = new TreeMap<String,String>();

        @JsonAnyGetter
        public Map<String, String> get() {
            return map;
        }

        @JsonAnySetter
        public void set(String name, String value) {
            map.put(name, value);
        }

    }

    @Test
    public final void test() throws JsonProcessingException, IOException {
        ObjectMapper jsonmapper = new ObjectMapper();
        POJO p = jsonmapper.readValue(json, POJO.class);
        assertEquals(jsonmapper.writeValueAsString(p),json);    
    }

}

我想你可以用 GSON 做类似的事情。另一种选择是,如果您知道 JSON 对象的结构 - 在这种情况下,您创建一个简单的 POJO 版本并反序列化为它,而不是像我上面定义的 POJO 类。

更多细节和支持XML as well as JSON mapping的类似版本

【讨论】:

    【解决方案2】:

    不管你如何获取数据,用它来构造一个合适的TableModel,并使用那个模型来构造JTable。在这个example 中,模型访问Map&lt;String, String&gt; 来履行TableModel 合约;您可以替换使用here 所示方法获得的Map。由于加载数据可能需要不确定的时间,请使用SwingWorker,如here 所示。

    【讨论】:

      【解决方案3】:

      这只是垃圾神和汤姆答案的组合,并举了一个例子,使用杰克逊和 TableModel。我真的只是想尝试一下 camickr 的BeanTableModel/RowTableModel(这是一个通用类,可以帮助我们轻松地从 pojos 创建表模型)(似乎效果很好)。

      更多信息/详情请查看this post

      Entity 类(属性映射到您的 json 中的键)

      public class Entity {
          // field/property names must match to your json keys (with some exceptions)
          // other wise we are required to use further annotations
          private boolean checked;
          private Date dateposted;
          private int itemnumber;
          private int quantity;
          private int stockcheckid;
      
          /*** ----- DO NOT FORGET GETTERS AND SETTERS ---- ***/
      }
      

      主类。注意使用BeanTableModel。你需要从上面的链接下载这个课程以及RowTableModel

      public class JsonTableDemo {
      
          public static void main(String[] args) throws Exception {
              ObjectMapper mapper = new ObjectMapper();
              String json = "[{\"checked\":false,\"dateposted\":\"2014-10-23T00:00:00\",\"itemnumber\":1,\"quantity\":5,\"stockcheckid\":1}]";
              List<Entity> response = mapper.readValue(json, 
                      TypeFactory.defaultInstance().constructCollectionType(
                                                    List.class, Entity.class));
              RowTableModel model = new BeanTableModel<>(Entity.class, response);
              JTable table = new JTable(model) {
                  @Override
                  public Dimension getPreferredScrollableViewportSize() {
                      return getPreferredSize();
                  }
              };
              JOptionPane.showMessageDialog(null, new JScrollPane(table));
          }
      }
      

      结果


      注意,对于长时间运行的任务(包括许多 io 任务),例如请求休息资源,您应该使用 SwingWorker,如垃圾神所解释的那样。当repsonse进来时,你基本上可以addRowRowTableModel实例。例如,如果我们使用与上面相同的 json 响应和模型,我们可以简单地做类似的事情

      response = mapper.readValue(json, 
              TypeFactory.defaultInstance().constructCollectionType(
                                            List.class, Entity.class));
      for (Entity entity : response) {
          model.addRow(entity);
      }
      

      更新

      我还应该提到,该服务还可以以 XML 格式发送这些数据。

      查看您的 json,它是一个对象数组。对于 XML,格式略有不同,因为您必须有一个根文档元素。所以你不能只说

      <entity>
          <prop></prop>
      </entity>
      <entity>
          <prop></prop>
      </entity>
      

      应该是这样的

      <entities>
          <entity>
              <prop></prop>
          </entity>
          <entity>
              <prop></prop>
          </entity>
      </entities>
      

      话虽如此,使用数据绑定,最简单的方法是创建另一个类来包装List&lt;Entity&gt;。现在我对 Jackson 的 XML 能力/特性不太熟悉,但是使用 JAXB,你可以有一个类似的类:

      @XmlRootElement
      @XmlAccessorType(XmlAccessType.FIELD)
      public class Entities {
      
          @XmlElement(name = "entity")
          protected List<Entity> entities;
      
          public List<Entity> getEntities() {
              if (entities == null) {
                  entities = new ArrayList<>();
              }
              return entities;
          }
      
          public void setEntities(List<Entity> entities) {
              this.entities = entities;
          }
      } 
      

      然后您可以将以下 XMl 解组到 Entities 类中。这是一个同时显示 json 和 xml 的更新演示

      public class JsonTableDemo {
      
          public static void main(String[] args) throws Exception {
              ObjectMapper mapper = new ObjectMapper();
              String json = "[{\"checked\":false,\"dateposted\":\"2014-10-23T00:00:00\",\"itemnumber\":1,\"quantity\":5,\"stockcheckid\":1}]";
              List<Entity> response = mapper.readValue(json,
                      TypeFactory.defaultInstance().constructCollectionType(
                              List.class, Entity.class));
              RowTableModel jsonModel = new BeanTableModel<>(Entity.class, response);
              JTable jsonTable = new JTable(jsonModel) {
                  @Override
                  public Dimension getPreferredScrollableViewportSize() {
                      return getPreferredSize();
                  }
              };
      
              String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
                      + "<entities>\n"
                      + "    <entity>\n"
                      + "        <checked>false</checked>\n"
                      + "        <dateposted>2014-10-22T17:00:00-07:00</dateposted>\n"
                      + "        <itemnumber>1</itemnumber>\n"
                      + "        <quantity>5</quantity>\n"
                      + "        <stockcheckid>1</stockcheckid>\n"
                      + "    </entity>\n"
                      + "</entities>";
      
      
              JAXBContext context = JAXBContext.newInstance(Entities.class);
              Unmarshaller unmarshaller = context.createUnmarshaller();
              Entities entities = (Entities)unmarshaller.unmarshal(new StringReader(xml));
              RowTableModel<Entity> xmlModel = new BeanTableModel<>(
                                               Entity.class, entities.getEntities());
              JTable xmlTable = new JTable(xmlModel){
                  @Override
                  public Dimension getPreferredScrollableViewportSize() {
                      return getPreferredSize();
                  }
              };
      
              JPanel panel = new JPanel(new GridLayout(0, 1));
      
              JPanel jsonPanel = new JPanel(new BorderLayout());
              jsonPanel.add(new JLabel("JSON Table", SwingConstants.CENTER), BorderLayout.PAGE_START);
              jsonPanel.add(new JScrollPane(jsonTable));
              panel.add(jsonPanel);
      
              JPanel xmlPanel = new JPanel(new BorderLayout());
              xmlPanel.add(new JLabel("XML Table", SwingConstants.CENTER), BorderLayout.PAGE_START);
              xmlPanel.add(new JScrollPane(xmlTable));
              panel.add(xmlPanel);
      
              JOptionPane.showMessageDialog(null, new JScrollPane(panel));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多