DocsJava

Server Integration — Java / Spring Boot

Spring Boot with io.pickpoint:pickpoint (jvm-sdk) — exposes PickPoint to your frontend. The API key lives in an environment variable and never reaches the client.

1

Dependencies (Maven)

<!-- pom.xml -->
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
  </dependency>
  <dependency>
    <groupId>io.pickpoint</groupId>
    <artifactId>pickpoint</artifactId>
    <version>2.0.0</version>
  </dependency>
</dependencies>
2

Configuration and SDK client bean

# application.properties
pickpoint.key=${PICKPOINT_KEY}    # loaded from env var
// PickPointConfig.java
import io.pickpoint.Client;
import io.pickpoint.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PickPointConfig {
    @Bean
    public Client pickpointClient(@Value("${pickpoint.key}") String key) {
        return Client.create(Config.builder().apiKey(key).build());
    }
}
3

Geocoding controller

// GeocodingController.java
import io.pickpoint.Client;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/geo")
public class GeocodingController {
    private final Client pp;

    public GeocodingController(Client pp) { this.pp = pp; }

    // GET /geo/forward?q=Eiffel+Tower&limit=5
    @GetMapping("/forward")
    public Object forward(@RequestParam String q,
                          @RequestParam(defaultValue = "5") int limit,
                          @RequestParam(required = false) String countrycodes,
                          @RequestParam(required = false) String viewbox) {
        Map<String, String> params = new HashMap<>();
        params.put("q", q);
        params.put("limit", String.valueOf(limit));
        if (countrycodes != null) params.put("countrycodes", countrycodes);
        if (viewbox != null)      params.put("viewbox", viewbox);
        return pp.forward(params);
    }

    // GET /geo/reverse?lat=48.85&lon=2.29&zoom=18
    @GetMapping("/reverse")
    public Object reverse(@RequestParam double lat,
                          @RequestParam double lon,
                          @RequestParam(defaultValue = "18") int zoom) {
        return pp.reverse(Map.of(
            "lat", String.valueOf(lat),
            "lon", String.valueOf(lon),
            "zoom", String.valueOf(zoom)
        ));
    }

    // GET /geo/search?q=Baker+St&viewbox=…
    @GetMapping("/search")
    public Object search(@RequestParam String q,
                         @RequestParam(required = false) String viewbox,
                         @RequestParam(defaultValue = "6") int limit) {
        Map<String, String> params = new HashMap<>();
        params.put("q", q);
        params.put("limit", String.valueOf(limit));
        if (viewbox != null) params.put("viewbox", viewbox);
        return pp.search(params);
    }
}
4

Routing controller

// RoutingController.java
import io.pickpoint.Client;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

@RestController
public class RoutingController {
    private final Client pp;

    public RoutingController(Client pp) { this.pp = pp; }

    @PostMapping("/route")
    public Object route(@RequestBody Map<String, Object> body) {
        return pp.route(body);
    }

    @PostMapping("/route/optimized")
    public Object routeOptimized(@RequestBody Map<String, Object> body) {
        return pp.optimizedRoute(body);
    }
}
5

Device tracking - REST

// DeviceController.java
import io.pickpoint.Client;
import io.pickpoint.DeviceListQuery;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/devices")
public class DeviceController {
    private final Client pp;

    public DeviceController(Client pp) { this.pp = pp; }

    @GetMapping
    public Object list() {
        return pp.getDevices().list(new DeviceListQuery());
    }
}
6

Device tracking - WebSocket relay

Mint a client token with mintClientTokens, subscribe with TrackingClient, fan out onLocation events to the browser session:

// TrackingRelayHandler.java — WebSocket subscriber relay
import io.pickpoint.MintKt;
import io.pickpoint.tracking.ListenerAuth;
import io.pickpoint.tracking.TrackingClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.List;

@Component
public class TrackingRelayHandler extends TextWebSocketHandler {
    @Value("${pickpoint.key}")
    private String apiKey;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String deviceUid = session.getUri().getQuery().split("deviceUid=")[1].split("&")[0];

        var pair = MintKt.mintClientTokens(
            io.pickpoint.Config.builder().apiKey(apiKey).build(),
            List.of("devices"),
            600L
        );

        var cfg = io.pickpoint.tracking.Config.builder()
            .endpoint("wss://tracking.pickpoint.io")
            .listener(ListenerAuth.builder().accessToken(pair.getAccessToken()).build())
            .subscribe(List.of(deviceUid))
            .build();

        TrackingClient tracking = TrackingClient.connect(cfg);
        tracking.onLocation(loc -> {
            try {
                var p = loc.getPoint();
                session.sendMessage(new TextMessage(
                    "{\"lat\":" + p.getLatitude() + ",\"lon\":" + p.getLongitude() + "}"
                ));
            } catch (Exception ignored) {}
        });
    }
}

← OverviewNode.js →