使用java从RESTful Web服务使用json字符串结果填充jtable

时间:2014-10-23 10:31:57

标签: java json swing rest jtable

我有一个基于查询输入逐个返回JSON字符串的Web服务,对服务的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();

  }

}`

3 个答案:

答案 0 :(得分:2)

响应是地图。您可以使用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

的更多细节和类似版本

答案 1 :(得分:2)

无论您如何获取数据,都可以使用它构建合适的TableModel并使用该模型构建JTable。在此example中,模型访问Map<String, String>以履行TableModel合同;您可以使用here显示的方法替换获得的Map。由于加载数据可能需要不确定的时间,因此请使用SwingWorker,如图所示here

答案 2 :(得分:1)

这只是垃圾桶和汤姆答案的组合,例如,使用Jackson和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));
    }
}

结果

enter image description here


注意,对于长时间运行的任务(包括许多io任务),例如请求休息资源,您应该使用trashgod所解释的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<Entity>。现在我对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));
    }
}

enter image description here