Ebooks

Java servlet JSON tutorial

Java servlet JSON tutorial shows how to return JSON data from a Java servlet. We use Gson library to work with JSON data format. The web application is deployed on Tomcat server.

Apache Tomcat is an open source Java Servlet Container developed by the Apache Software Foundation (ASF). It is the most popular Java web server. Gson is an open source Java library to serialize and deserialize Java objects to (and from) JSON.

Java Servlet

Servlet is a Java class which responds to a particular type of network request - most commonly an HTTP request. Java servlets are used to create web applications. They run in servlet containers such as Tomcat or Jetty. Modern-day Java web development uses frameworks that are built on top of servlets.

JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write and for machines to parse and generate. The official Internet media type for JSON is application/json. The JSON filename extension is .json.

Java servlet JSON application

The following web application uses a Java servlet to send data (list of cities) to the client in JSON format.

$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── zetcode
    │   │           ├── bean
    │   │           │   └── City.java
    │   │           ├── service
    │   │           │   └── CityService.java
    │   │           └── web
    │   │               └── GetCities.java
    │   └── webapp
    │       └── META-INF
    │           └── context.xml
    └── test
        └── java

This is the project structure.

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>com.zetcode</groupId>
    <artifactId>ServletJson</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>ServletJson</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <dependencies>
        
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>
        
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
 
        </plugins>
    </build>
</project>

This is the Maven POM file. We have two artifacts: javax.servlet-api for servlets and gson for JSON processing in Java. The maven-war-plugin is responsible for collecting all artifact dependencies, classes and resources of the web application and packaging them into a web application archive (WAR).

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/ServletJson"/>

In the Tomcat context.xml file, we define the context path. It is the name of the web application.

City.java
package com.zetcode.bean;

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);
    }
}

This is the City bean. It has three attributes: id, name, and population.

GetCities.java
package com.zetcode.web;

import com.zetcode.bean.City;
import com.zetcode.service.CityService;
import com.zetcode.util.JsonConverter;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

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

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

        ServletOutputStream out = response.getOutputStream();

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

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

        out.print(output);
    }
}

This is the GetCities servlet. It retrieves data from a service class and returns them to the client in JSON format.

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

We set the content type of the response object to application/json.

ServletOutputStream out = response.getOutputStream();

We get the ServletOutputStream which is used to send data to the client.

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

From the CityService, we get the list of cities.

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

We convert the list of cities into JSON string with JsonConverter.

out.print(output);

The JSON string is written to the ServletOutputStream.

ICityService.java
package com.zetcode.service;

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

public interface ICityService {
    
    public List<City> getCities();
}

ICityService contains the getCities() contract method.

CityService.java
package com.zetcode.service;

import com.zetcode.bean.City;
import com.zetcode.dao.CityDao;
import com.zetcode.dao.ICityDao;
import java.util.List;

public class CityService implements ICityService {
    
    ICityDao cityDao;
    
    public CityService() {
        
        cityDao = new CityDao();
    }

    @Override
    public List<City> getCities() {

        return cityDao.findAll();
    }
}

The CityService's getCities() method returns a list of city objects. It uses a DAO object to access data.

ICityDao.java
package com.zetcode.dao;

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

public interface ICityDao {
    
    public List<City> findAll();
}

ICityDao contains the findAll() contract method.

CityDao.java
package com.zetcode.dao;

import com.zetcode.bean.City;
import java.util.ArrayList;
import java.util.List;

public class CityDao implements ICityDao {

    @Override
    public List<City> findAll() {
        
        List<City> cities = new ArrayList<>();
        
        cities.add(new City(1L, "Bratislava", 432000));
        cities.add(new City(2L, "Budapest", 1759000));
        cities.add(new City(3L, "Prague", 1280000));
        cities.add(new City(4L, "Warsaw", 1748000));
        cities.add(new City(5L, "Los Angeles", 3971000));
        cities.add(new City(6L, "New York", 8550000));
        cities.add(new City(7L, "Edinburgh", 464000));
        cities.add(new City(8L, "Berlin", 3671000));
        
        return cities;        
    }
}

CityDao is the implementation of ICityDao. For simplicity reasons, we do not connect to the database. We simply return a list of city objects.

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.bean.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();
        JsonObject jsonObject = new JsonObject();
        jsonObject.add("cities", jarray);

        return jsonObject.toString();
    }
}

JsonConverter converts a list of cities into a JSON string. We use the Gson library.

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>

The home page contains a link to call the servlet.

Creating a request with curl

The curl is a tool to transfer data from or to a server, using one of the supported protocols.

$ curl localhost:8084/ServletJson/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}]

This is the output. With the curl command, we issue a HTTP GET request to the GetCities servlet.

Naming the JSON array

In case we wanted to name the returned JSON array, we can use the following code:

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

out.print(jsonObject.toString());

In the servlet, we place the JSON array into another JSON object and name the property cities.

In this tutorial, we have sent JSON data from a Java servlet.

You might also be interested in the following related tutorials: Java Servlet RESTful client, Java Servlet Serving XML tutorial, Java Servlet PDF tutorial, Java RequestDispatcher, Serving plain text from Java servlet, Java servlet check box tutorial, Java servlet image tutorial, Java Servlet HTTP headers, or Java tutorial