ZetCode

Java servlet JSON

最后修改于 2023 年 8 月 24 日

Java servlet JSON 教程展示了如何从 Java servlet 返回 JSON 数据。我们使用 Gson 库来处理 JSON 数据格式。该 Web 应用程序部署在 Jetty 服务器上。

Jetty 是一个开源项目,提供 HTTP 服务器、HTTP 客户端和 Java Servlet 容器。 Gson 是一个开源 Java 库,用于将 Java 对象序列化为 JSON(或从 JSON 反序列化为 Java 对象)。

Java Servlet

Servlet 是一个 Java 类,它响应特定类型的网络请求 - 最常见的是 HTTP 请求。Java servlet 用于创建 Web 应用程序。它们运行在 Tomcat 或 Jetty 等 Servlet 容器中。当今的 Java Web 开发使用构建在 Servlet 之上的框架。

JSON

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。它易于人类阅读和编写,也易于机器解析和生成。JSON 的官方 Internet 媒体类型是 application/json。JSON 文件扩展名是 .json

Java servlet JSON 应用程序

以下 Web 应用程序使用 Java servlet 将数据(城市列表)以 JSON 格式发送到客户端。

pom.xml
src
├── main
│   ├── java
│   │   └── com
│   │       └── zetcode
│   │           ├── model
│   │           │   └── City.java
│   │           ├── service
│   │           │   ├── CityService.java
│   │           │   └── ICityService.java
│   │           ├── util
│   │           │   └── JsonConverter.java
│   │           └── web
│   │               └── GetCities.java
│   ├── resources
│   └── webapp
│       └── index.html
└── test
    └── java

这是项目结构。

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ServletJson</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.0</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.3</version>
            </plugin>

            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>11.0.11</version>
                <configuration>
                    <webApp>
                        <contextPath>/app</contextPath>
                    </webApp>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

这是 Maven POM 文件。我们有两个工件:用于 servlet 的 javax.servlet-api 和用于 Java 中 JSON 处理的 gsonmaven-war-plugin 负责收集 Web 应用程序的所有工件依赖项、类和资源,并将它们打包到 Web 应用程序归档文件 (WAR) 中。

jetty-maven-plugin 是一个有用的 Maven 插件,用于快速开发和测试。它创建 Web 应用程序,启动 Jetty Web 服务器,并将应用程序部署到服务器上。

com/zetcode/model/City.java
package com.zetcode.model;

import java.util.Objects;

public class City {

    private Long id;
    private String name;
    private int population;

    public City(Long id, String name, int population) {
        this.id = id;
        this.name = name;
        this.population = population;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 97 * hash + Objects.hashCode(this.id);
        hash = 97 * hash + Objects.hashCode(this.name);
        hash = 97 * hash + this.population;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final City other = (City) obj;
        if (this.population != other.population) {
            return false;
        }
        if (!Objects.equals(this.name, other.name)) {
            return false;
        }
        return Objects.equals(this.id, other.id);
    }
}

这是 City Bean。它有三个属性:id、name 和 population。

com/zetcode/web/GetCities.java
package com.zetcode.web;

import com.zetcode.model.City;
import com.zetcode.service.CityService;
import com.zetcode.util.JsonConverter;

import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet(name = "GetCities", urlPatterns = {"/GetCities"})
public class GetCities extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException {

        response.setContentType("application/json;charset=UTF-8");

        ServletOutputStream out = response.getOutputStream();

        List<City> cities = new CityService().getCities();

        var converter = new JsonConverter();
        String output = converter.convertToJson(cities);

        out.print(output);
    }
}

这是 GetCities servlet。它从服务类检索数据,并以 JSON 格式将其返回给客户端。

response.setContentType("application/json;charset=UTF-8");

我们将响应对象的 content type 设置为 application/json

ServletOutputStream out = response.getOutputStream();

我们获取 ServletOutputStream,它用于将数据发送到客户端。

List<City> cities = new CityService().getCities();

CityService,我们获取城市列表。

var converter = new JsonConverter();
String output = converter.convertToJson(cities);

我们使用 JsonConverter 将城市列表转换为 JSON 字符串。

out.print(output);

JSON 字符串被写入 ServletOutputStream

com/zetcode/service/ICityService.java
package com.zetcode.service;

import com.zetcode.model.City;
import java.util.List;

public interface ICityService {

    List<City> getCities();
}

ICityService 包含 getCities 合约方法。

com/zetcode/service/CityService.java
package com.zetcode.service;

import com.zetcode.model.City;

import java.util.List;

public class CityService implements ICityService {

    @Override
    public List<City> getCities() {

        var cities = List.of(
                new City(1L, "Bratislava", 432000),
                new City(2L, "Budapest", 1759000),
                new City(3L, "Prague", 1280000),
                new City(4L, "Warsaw", 1748000),
                new City(5L, "Los Angeles", 3971000),
                new City(6L, "New York", 8550000),
                new City(7L, "Edinburgh", 464000),
                new City(8L, "Berlin", 3671000));

        return cities;
    }
}

CityServicegetCities 方法返回一个城市对象列表。

com/zetcode/util/JsonConverter.java
package com.zetcode.util;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.zetcode.model.City;

import java.util.List;

public class JsonConverter {

    private final Gson gson;

    public JsonConverter() {

        gson = new GsonBuilder().create();
    }

    public String convertToJson(List<City> cities) {

        JsonArray jarray = gson.toJsonTree(cities).getAsJsonArray();
        var jsonObject = new JsonObject();
        jsonObject.add("cities", jarray);

        return jsonObject.toString();
    }
}

JsonConverter 将城市列表转换为 JSON 字符串。我们使用 Gson 库。

webapp/index.html
<!DOCTYPE html>
<html>
    <head>
        <title>Home page</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <a href="GetCities">GetCities</a>
    </body>
</html>

主页包含一个调用 servlet 的链接。

$ mvn jetty:run

我们运行 Jetty 服务器并导航到 localhost:8080/app/

使用 curl 创建请求

curl 是一个使用支持的协议之一从服务器传输数据或向服务器传输数据的工具。

$ curl localhost:8080/app/GetCities
[{"id":1,"name":"Bratislava","population":432000},{"id":2,"name":"Budapest","population":1759000},
{"id":3,"name":"Prague","population":1280000},{"id":4,"name":"Warsaw","population":1748000},
{"id":5,"name":"Los Angeles","population":3971000},{"id":6,"name":"New York","population":8550000},
{"id":7,"name":"Edinburgh","population":464000},{"id":8,"name":"Berlin","population":3671000}]

这是输出。使用 curl 命令,我们向 GetCities servlet 发出 HTTP GET 请求。

命名 JSON 数组

如果我们想命名返回的 JSON 数组,我们可以使用以下代码

Gson gson = new GsonBuilder().create();
JsonArray jarray = gson.toJsonTree(cities).getAsJsonArray();
JsonObject jsonObject = new JsonObject();
jsonObject.add("cities", jarray);

out.print(jsonObject.toString());

在 servlet 中,我们将 JSON 数组放入另一个 JSON 对象中,并将属性命名为 cities

在本文中,我们从 Java servlet 发送了 JSON 数据。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写超过 1,400 篇文章和 8 本电子书。我在教学编程方面拥有十多年的经验。

列出所有 Java Servlet 教程