杰瑞科技汇

Java如何对接ArcGIS Server?

Of course! Using Java with ArcGIS Server is a powerful and common pattern for organizations that have a strong Java development ecosystem. It allows you to build custom web applications, geoprocessing services, and integrate ArcGIS Server capabilities into larger enterprise systems.

Java如何对接ArcGIS Server?-图1
(图片来源网络,侵删)

Here’s a comprehensive guide covering the key aspects, from architecture to practical code examples.


Core Concepts: How Java Interacts with ArcGIS Server

There are two primary ways Java interacts with ArcGIS Server:

A. Java Web Applications (Client-Side)

This is the most common approach. You build a standard Java web application (using a framework like Spring Boot, Jakarta EE, or a simple Servlet) that acts as a client to ArcGIS Server services.

  • How it works: Your Java application makes standard HTTP requests (REST or SOAP) to the ArcGIS Server REST API or SOAP API.
  • What you can do:
    • Query Services: Execute SQL-like queries on feature services to get data.
    • Render Maps: Request map images (PNG, JPG) or vector data (JSON) from a map service.
    • Geocode Addresses: Send addresses to a geocoding service and get back coordinates.
    • Execute Geoprocessing Tools: Run complex analysis tools exposed as geoprocessing services.
    • Manage Services: (With admin credentials) start, stop, or upload services.
  • Key Libraries: You don't need any special Esri Java libraries for this. You use standard Java HTTP clients like java.net.HttpURLConnection, the Apache HttpClient library, or a modern reactive client like WebClient (from Spring WebFlux).

B. Java Server Object Extension (SOE) (Server-Side)

This is a more advanced, "plugging-in" approach. An SOE is a Java component that you deploy directly to the ArcGIS Server site. It extends the functionality of a map service.

Java如何对接ArcGIS Server?-图2
(图片来源网络,侵删)
  • How it works: The SOE is compiled into a .jar file and uploaded to ArcGIS Manager. Once enabled, it exposes new custom REST endpoints that are part of the map service itself (e.g., https://myserver/arcgis/rest/services/MyMap/MapServer/extent/mySOE).
  • What you can do:
    • Custom Data Sources: Connect the map service to a non-standard data source (e.g., a real-time IoT feed, a custom database).
    • Advanced Rendering: Implement custom server-side rendering logic that isn't possible out-of-the-box.
    • Custom Spatial Operations: Perform complex spatial analysis or custom geometry operations on the server.
  • Key Libraries: You must use the ArcGIS Server Java SOE SDK, which provides a framework and base classes for your extension.

Architecture Overview

+-----------------------+      +-------------------------+      +---------------------+
|                       |      |                         |      |                     |
|  Java Web Application |----->|   ArcGIS Server REST API |----->|   ArcGIS Server     |
|  (e.g., Spring Boot)  |      |   (HTTPS/JSON)          |      |   (Map, Feature,    |
|                       |      |                         |      |   GP, Geocode)      |
+-----------------------+      +-------------------------+      +----------+----------+
      ^  |                                                       ^          |
      |  | (Requests image, data, or executes a tool)            |          | (Hosts the SOE)
      |  |                                                       |          |
      |  +-------------------------------------------------------+----------+
      | (Client makes direct REST calls)
      |
      v
+------------------------------------------------------------------+
|  Java Server Object Extension (SOE)                               |
|  - Deployed directly to ArcGIS Server                             |
|  - Extends a specific map service                                 |
|  - Exposes custom REST endpoints                                  |
+------------------------------------------------------------------+

Practical Example 1: Java Web App as a Client (Spring Boot)

This is the most recommended approach for new development. We'll use Spring Boot for its simplicity and powerful features.

Goal: Query a public feature service for all earthquakes within a specific extent and print the results.

Step 1: Set up your Spring Boot Project

Use the Spring Initializr with:

  • Project: Maven
  • Language: Java
  • Spring Boot: A recent stable version (e.g., 3.x.x)
  • Dependencies:
    • Spring Web
    • Spring Boot DevTools (optional, for auto-reload)

Step 2: Add Dependencies

In your pom.xml, add the Jackson Databind dependency to easily handle JSON. Spring Web usually includes this, but it's good to be explicit.

Java如何对接ArcGIS Server?-图3
(图片来源网络,侵删)
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Jackson is included by spring-boot-starter-web, but good to be aware of -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Step 3: Create a Service to Handle ArcGIS Server Communication

Create a new Java class, ArcgisService.java.

package com.example.demo.service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@Service
public class ArcgisService {
    // Use a RestTemplate for making HTTP calls. In a real app, make this a bean.
    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();
    // The public USGS earthquake service
    private static final String FEATURE_SERVICE_URL = "https://services1.arcgis.com/0MSEUqKaxRlEPj5g/arcgis/rest/services/Earthquakes_from_last_7_days/FeatureServer/0/query";
    public JsonNode getEarthquakesInExtent(double xmin, double ymin, double xmax, double ymax) {
        // 1. Build the query parameters
        Map<String, String> params = new HashMap<>();
        params.put("f", "json"); // Request JSON response
        params.put("where", "1=1"); // Select all features
        params.put("returnGeometry", "true");
        params.put("spatialRel", "esriSpatialRelIntersects");
        params.put("geometry", String.format("[%s,%s,%s,%s]", xmin, ymin, xmax, ymax));
        params.put("geometryType", "esriGeometryEnvelope");
        params.put("inSR", "4326"); // WGS84
        params.put("outFields", "*"); // Return all fields
        // 2. Make the GET request
        // RestTemplate will automatically build the URL with the parameters
        String responseJson = restTemplate.getForObject(FEATURE_SERVICE_URL, String.class, params);
        // 3. Parse the JSON response
        try {
            return objectMapper.readTree(responseJson);
        } catch (Exception e) {
            throw new RuntimeException("Failed to parse ArcGIS Server response", e);
        }
    }
}

Step 4: Create a Controller to Expose an Endpoint

Create a RestController, EarthquakeController.java.

package com.example.demo.controller;
import com.example.demo.service.ArcgisService;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/earthquakes")
public class EarthquakeController {
    @Autowired
    private ArcgisService arcgisService;
    // Example endpoint: http://localhost:8080/api/earthquakes/in-extent?xmin=-120&ymin=30&xmax=-110&ymax=40
    @GetMapping("/in-extent")
    public JsonNode getEarthquakesInExtent(
            @RequestParam double xmin,
            @RequestParam double ymin,
            @RequestParam double xmax,
            @RequestParam double ymax) {
        System.out.println("Querying for earthquakes in extent: " + xmin + "," + ymin + "," + xmax + "," + ymax);
        return arcgisService.getEarthquakesInExtent(xmin, ymin, xmax, ymax);
    }
}

Step 5: Run and Test

  1. Run your SpringBootApplication.java class.
  2. Open your browser or a tool like Postman/curl and go to: http://localhost:8080/api/earthquakes/in-extent?xmin=-150&ymin=20&xmax=-50&ymax=60

You should get a JSON response containing the earthquake features within the bounding box of North America.


Practical Example 2: Simple Java SOE

This is more complex and requires the ArcGIS Server SDK.

Goal: Create a simple SOE that returns a custom message when you call its REST endpoint.

Step 1: Get the SDK

Download the ArcGIS Server Java SOE SDK from the Esri Customer Care portal or your Esri software download page. It includes the necessary JAR files and documentation.

Step 2: Set up your Project

  1. Create a new Java project in your IDE (IntelliJ/Eclipse).
  2. Add the JAR files from the SDK's lib directory to your project's classpath. Key JARs include:
    • arcgis_server_soe.jar
    • commons-logging.jar
    • log4j.jar
    • stax-api.jar
    • wstx-asl.jar

Step 3: Write the SOE Code

Create a Java class that extends esriSOEExtension.

package com.example.soe;
import com.esri.arcgis.server.SOESupport;
import com.esri.arcgis.server.SOESupport.*;
// This annotation is crucial for the SOE to be discovered by ArcGIS Server
@com.esri.arcgis.server.SOESupport.SOEExtension(
    extensionName = "HelloJavaSOE",
    productName = "ArcGIS",
    productVersion = "11.0" // Use your ArcGIS Server version
)
public class HelloJavaSOE extends esriSOEExtension {
    // This method is called when the SOE is initialized
    @Override
    public void init(String propertiesPath) throws Exception {
        super.init(propertiesPath);
        // You can load configuration from a properties file here
        System.out.println("HelloJavaSOE Initialized!");
    }
    // This is where you define your custom REST operation
    @SOEOperation(
        displayName = "GetGreeting", // The name that appears in the REST endpoint
        description = "Returns a friendly greeting from a Java SOE."
    )
    public void getGreeting(
            SOEInputData inputData,
            SOEOutputData outputData,
            SOEContext context) throws Exception {
        // Set the HTTP response properties
        outputData.setContentType("text/plain");
        outputData.setCharSet("utf-8");
        // Write the response content
        outputData.getOutputStream().write("Hello from a Java Server Object Extension!".getBytes());
    }
}

Step 4: Build and Deploy

  1. Compile your code and package it into a HelloJavaSOE.jar file.
  2. Open ArcGIS Manager for your ArcGIS Server site.
  3. Go to Site > Add Extension.
  4. Browse to your HelloJavaSOE.jar file and upload it.
  5. Find your map service in the Services tab, click Extensions, and enable HelloJavaSOE for that service.

Step 5: Test the SOE

Once enabled, you can call your new REST endpoint: https://<your-server-name>:<port>/arcgis/rest/services/YourMapService/MapServer/extensions/HelloJavaSOE/GetGreeting?f=json

The response will be:

{
  "data": "Hello from a Java Server Object Extension!",
  "value": "Hello from a Java Server Object Extension!"
}

Best Practices and Considerations

  • Use Modern Java: Java 11 or 17 is recommended for better performance and security.
  • Client-Side First: For 95% of use cases, building a Java web application as a client to the ArcGIS Server REST API is simpler, more flexible, and easier to debug than an SOE. You can deploy and update your Java app independently of your GIS server.
  • SOEs for Deep Integration: Choose an SOE only when you need to tightly couple custom logic directly with a map service's state or rendering pipeline. They are harder to develop, deploy, and debug.
  • Security: When dealing with secured services, use token-based authentication. Your Java app will first need to get a token from the ArcGIS Server's token service and then include that token in the header of all subsequent API calls.
  • Asynchronous Operations: For long-running geoprocessing tasks, use the job model. Your Java app will submit a job, get a jobId, and then poll the service for the job's status until it's complete.
  • Error Handling: Always check the JSON response from ArcGIS Server for an error object. It will contain details about any failures.

Summary: Client vs. SOE

Feature Java Web App (Client) Java Server Object Extension (SOE)
Deployment Deployed to any Java servlet container (Tomcat, JBoss, Spring Boot embedded). Deployed directly to the ArcGIS Server site via ArcGIS Manager.
Architecture Decoupled. The app and GIS server are separate. Tightly coupled. The SOE is part of the map service.
Development Simpler. Uses standard web development practices. More complex. Requires the Esri SOE SDK and understanding of ArcGIS internals.
Debugging Easier. Debug the web app in your IDE like any other Java app. Harder. Requires attaching a debugger to the ArcGIS Server process.
Use Case General-purpose web apps, dashboards, data integrators. Extending map service capabilities (custom data, rendering, analysis).
Flexibility High. Can integrate with any other system or API. Low. Limited to the context of the map service it's attached to.
分享:
扫描分享到社交APP
上一篇
下一篇