GeoServer REST API — Java Integration

Programmatic access to GeoServer configuration, layers, and security settings using the official Java REST client utilities.

â„šī¸
Note: This documentation covers the Java integration for GeoServer's REST API (version 2.26+). The REST API uses standard HTTP methods with XML payloads for configuration changes.

Maven Dependencies

To interact with GeoServer from Java, include the following dependencies. We recommend using the Java 11+ java.net.http module or Apache HttpClient.

pom.xml
<dependencies>
    <!-- Core HTTP Client -->
    <dependency>
        <groupId>org.apache.httpcomponents.client5</groupId>
        <artifactId>httpclient5</artifactId>
        <version>5.3.1</version>
    </dependency>

    <!-- XML Processing for GeoServer Payloads -->
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
        <version>2.17.0</version>
    </dependency>
</dependencies>

Authentication

GeoServer REST API requires authentication for all configuration operations. Basic Authentication is supported out-of-the-box using the admin user or custom roles.

GeoServerAuth.java
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.util.Base64;

public class GeoServerAuth {
    
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "geoserver";
    private static final String BASE_URL = "http://localhost:8080/geoserver/rest";
    
    public static String getAuthHeader() {
        String credentials = USERNAME + ":" + PASSWORD;
        return "Basic " + Base64.getEncoder().encodeToString(credentials.getBytes());
    }
    
    public static HttpRequest.Builder authRequest(HttpRequest.Builder builder) {
        builder.header("Authorization", getAuthHeader());
        return builder;
    }
}

Quick Start: List Workspaces

Here's a complete example of initializing the client and retrieving a list of all configured workspaces.

WorkspaceExample.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;

public class WorkspaceExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("http://localhost:8080/geoserver/rest/workspaces"))
            .header("Authorization", GeoServerAuth.getAuthHeader())
            .header("Accept", "application/xml")
            .GET()
            .build();
            
        HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
        
        if (response.statusCode() == 200) {
            System.out.println("Workspaces:");
            System.out.println(response.body());
        } else {
            System.err.println("Error: " + response.statusCode());
        }
    }
}

Common Operations

The table below outlines common GeoServer resources and their corresponding HTTP methods.

Resource Endpoint Methods Description
Workspaces /rest/workspaces GET, POST List or create workspaces
Data Stores /rest/workspaces/{ws}/datastores GET, POST Manage PostGIS/Shapefile stores
Layers /rest/layers GET, PUT, DELETE Configure layer visibility/CRS
Styles /rest/workspaces/{ws}/styles GET, POST Upload and manage SLD styles
Security /rest/security/roles GET, POST Role-based access control

Working with XML Payloads

GeoServer's REST API uses XML for configuration updates. When creating or updating resources, you must POST/PUT XML documents conforming to GeoServer's schema.

âš ī¸
Important: XML payloads must include the correct namespace declarations. Use the application/xml content type header for all POST/PUT requests.

Creating a Data Store

CreateDataStore.java
String xmlPayload = """
        <dataStore xmlns="http://www.geoserver.org/1.1.0">
            <name>my_postgis_store</name>
            <type>PostGIS</type>
            <connectionParameters>
                <entry key="host">localhost</entry>
                <entry key="port">5432</entry>
                <entry key="database">geo_db</entry>
                <entry key="user">postgres</entry>
                <entry key="passwd">secret</entry>
                <entry key="dbtype">postgis</entry>
            </connectionParameters>
        </dataStore>
        """;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("http://localhost:8080/geoserver/rest/workspaces/myworkspace/datastores"))
    .header("Authorization", GeoServerAuth.getAuthHeader())
    .header("Content-Type", "application/xml")
    .POST(HttpRequest.BodyPublishers.ofString(xmlPayload))
    .build();

Error Handling

Always check HTTP status codes. GeoServer returns descriptive XML error messages in the response body on failure.

ErrorHandling.java
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());

switch (response.statusCode()) {
    case 200, 201, 204 -> System.out.println("Success");
    case 401 -> System.err.println("Unauthorized: Check credentials");
    case 403 -> System.err.println("Forbidden: Insufficient permissions");
    case 404 -> System.err.println("Not Found: Resource does not exist");
    case 500 -> {
        System.err.println("Server Error: " + response.body());
        throw new RuntimeException("GeoServer internal error");
    }
    default -> throw new IOException("Unexpected: " + response.statusCode());
}
đŸšĢ
Production Note: Never hardcode credentials in source code. Use environment variables or a secrets manager for production deployments.

Advanced: Asynchronous Operations

For batch operations or large style uploads, use async client methods to avoid blocking the main thread.

AsyncExample.java
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(response -> {
        if (response.statusCode() == 200) {
            System.out.println("Layer updated successfully");
        }
        return response.statusCode();
    })
    .exceptionally(ex -> {
        System.err.println("Request failed: " + ex.getMessage());
        return -1;
    });