Using Java Spring Boot and RestTemplate.
To use the CubeMaster API, you need an API key (TokenID) for authentication. Here's how to get started:
TokenID (e.g., abc123xyz789). Copy this key and store it securely, as it will be used in the HTTP headers of your API requests.Note: The TokenID will be used in the HTTP headers of your POST request for authentication.
Create a Spring Boot project to handle API requests using RestTemplate:
pom.xml:<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
application.properties file in src/main/resources to store the API key and endpoint:
cubemaster.api.url=https://api.cubemaster.net/loads
cubemaster.api.token=your_token_id_here
UI Element: Spring Boot’s embedded Tomcat server provides a lightweight environment to test API calls without needing a separate UI framework initially.
A RESTful API (Representational State Transfer) is a way for applications to communicate over the internet using standard HTTP methods:
The CubeMaster API uses the POST method for the /loads endpoint to create a new load. RESTful APIs typically:
In this guide, we’ll send a JSON request to https://api.cubemaster.net/loads and receive a JSON response with load details.
Assume your customer’s legacy database stores order/shipment data (e.g., items, dimensions, quantities). Use Spring Data JPA to fetch this data:
package com.example.model;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class OrderItem {
@Id
private String name;
private double length;
private double width;
private double height;
private double weight;
private int quantity;
private String color;
// Getters and Setters
}
package com.example.repository;
import com.example.model.OrderItem;
import org.springframework.data.jpa.repository.JpaRepository;
public interface OrderItemRepository extends JpaRepository<OrderItem, String> {
}
package com.example.service;
import com.example.model.OrderItem;
import com.example.repository.OrderItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class OrderService {
@Autowired
private OrderItemRepository repository;
public List<OrderItem> getOrderItems() {
return repository.findAll();
}
}
This data will be mapped to the CubeMaster API’s Cargoes array in the request JSON.
Define Java classes to represent the request JSON structure:
package com.example.model;
public class Cargo {
private String name;
private double length;
private double width;
private double height;
private double weight;
private String orientationsAllowed;
private boolean turnAllowedOnFloor;
private int qty;
private String colorKnownName;
// Getters and Setters
}
package com.example.model;
public class Container {
private String vehicleType;
private String name;
private double length;
private double width;
private double height;
private String colorKnownName;
// Getters and Setters
}
package com.example.model;
public class Rules {
private boolean isWeightLimited;
private boolean isSequenceUsed;
private String fillDirection;
private String calculationType;
// Getters and Setters
}
package com.example.model;
import java.util.List;
public class LoadRequest {
private String title;
private String description;
private List<Cargo> cargoes;
private List<Container> containers;
private Rules rules;
// Getters and Setters
}
UI Element: These models act as the data structure for your backend logic, not requiring direct UI components but enabling JSON serialization via Jackson.
Use RestTemplate to send the POST request with TokenID in headers:
package com.example.service;
import com.example.model.LoadRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class CubeMasterService {
private final RestTemplate restTemplate;
@Value("${cubemaster.api.url}")
private String apiUrl;
@Value("${cubemaster.api.token}")
private String tokenId;
public CubeMasterService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public ResponseEntity<String> createLoad(LoadRequest request) {
HttpHeaders headers = new HttpHeaders();
headers.set("TokenID", tokenId);
headers.set("Content-Type", "application/json");
HttpEntity<LoadRequest> entity = new HttpEntity<>(request, headers);
return restTemplate.exchange(apiUrl, HttpMethod.POST, entity, String.class);
}
}
package com.example.controller;
import com.example.model.LoadRequest;
import com.example.service.CubeMasterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoadController {
@Autowired
private CubeMasterService service;
@PostMapping("/create-load")
public ResponseEntity<String> createLoad(@RequestBody LoadRequest request) {
return service.createLoad(request);
}
}
{
"Title": "New Mixed Truck Load",
"Description": "Hello Web API",
"Cargoes": [
{
"Name": "ITEM001",
"Length": 72,
"Width": 30,
"Height": 75,
"Weight": 1002.45,
"OrientationsAllowed": "OrientationsAll",
"TurnAllowedOnFloor": false,
"Qty": 16,
"ColorKnownName": "Brown"
},
{
"Name": "ITEM002",
"Length": 27.31,
"Width": 37.5,
"Height": 76.67,
"Weight": 521.45,
"OrientationsAllowed": "OrientationsAll",
"TurnAllowedOnFloor": false,
"Qty": 28,
"ColorKnownName": "Aqua"
},
{
"Name": "SKU0005",
"Length": 27.31,
"Width": 9.5,
"Height": 75.67,
"Weight": 501.45,
"OrientationsAllowed": "OrientationsAll",
"TurnAllowedOnFloor": true,
"Qty": 24,
"ColorKnownName": "Beige"
},
{
"Name": "SKU0005",
"Qty": 23
},
{
"Name": "SKU0008",
"Qty": 34
}
],
"Containers": [
{
"VehicleType": "Dry",
"Name": "53FT-Intermodal",
"Length": 630,
"Width": 98,
"Height": 106,
"ColorKnownName": "Blue"
}
],
"Rules": {
"IsWeightLimited": true,
"IsSequenceUsed": false,
"FillDirection": "FrontToRear",
"CalculationType": "MixLoad"
}
}
UI Element: The @RestController exposes an endpoint (/create-load) that can be triggered via tools like Postman or a simple frontend form.
Process the API response to extract useful data (e.g., load summary, graphics):
package com.example.model;
public class LoadResponse {
private String status;
private String message;
private String calculationError;
private Document document;
private LoadSummary loadSummary;
private List<FilledContainer> filledContainers;
// Getters and Setters
public static class Document {
private String title;
private String description;
private double calculationTimeInSeconds;
// Other fields, getters, setters
}
public static class LoadSummary {
private int cargoesLoaded;
private int piecesLoaded;
private double volumeLoaded;
private double weightLoaded;
// Other fields, getters, setters
}
public static class FilledContainer {
private String name;
private LoadSummary loadSummary;
private Graphics graphics;
// Other fields, getters, setters
public static class Graphics {
private Images images;
// Getters, setters
public static class Images {
private String path3DDiagram;
private String pathComposite;
// Getters, setters
}
}
}
}
public LoadResponse createLoad(LoadRequest request) {
HttpHeaders headers = new HttpHeaders();
headers.set("TokenID", tokenId);
headers.set("Content-Type", "application/json");
HttpEntity<LoadRequest> entity = new HttpEntity<>(request, headers);
ResponseEntity<LoadResponse> response = restTemplate.exchange(apiUrl, HttpMethod.POST, entity, LoadResponse.class);
if (response.getStatusCode().is2xxSuccessful()) {
LoadResponse loadResponse = response.getBody();
System.out.println("Status: " + loadResponse.getStatus());
System.out.println("Message: " + loadResponse.getMessage());
System.out.println("Volume Loaded: " + loadResponse.getLoadSummary().getVolumeLoaded());
return loadResponse;
} else {
throw new RuntimeException("API call failed: " + response.getStatusCode());
}
}
{
"status": "succeed",
"message": "Engine created. 5 cargoes. 1 empty containers. Calculation started. Calculation ended. The load built successfully. The load saved to the cloud database.",
"calculationError": "InvalidCargoSize",
"document": {
"title": "New Mixed Truck Load",
"description": "Hello Web API",
"calculationTimeInSeconds": 0.6152743,
"createdBy": "CHANG@LOGEN.CO.KR",
"createdAt": "2023-02-11T01:17:01.7392204+09:00"
},
"loadSummary": {
"cargoesLoaded": 68,
"piecesLoaded": 68,
"volumeLoaded": 5261723.4606,
"weightLoaded": 42674.59999999999
},
"filledContainers": [
{
"name": "#1 53FT-Intermodal",
"loadSummary": {
"cargoesLoaded": 68,
"volumeLoaded": 5261723.4606,
"weightLoaded": 42674.59999999999
},
"graphics": {
"images": {
"path3DDiagram": "https://api.cubemaster.net/runtimes/b28413ca_51ed_44c9_b92e_13147363fd61.PNG",
"pathComposite": "https://api.cubemaster.net/runtimes/7eb09974_2f1d_41bc_9371_2002658dce07.PNG"
}
}
}
]
}
UI Element: You can extend this to return the response to a frontend (e.g., displaying path3DDiagram images in a web page).
Ensure your API integration is robust by monitoring and debugging:
package com.example.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class CubeMasterService {
private static final Logger logger = LoggerFactory.getLogger(CubeMasterService.class);
public LoadResponse createLoad(LoadRequest request) {
logger.info("Sending request to CubeMaster API: {}", request);
// ... existing code ...
logger.info("Received response: {}", response.getBody());
return response.getBody();
}
}
try {
return restTemplate.exchange(apiUrl, HttpMethod.POST, entity, LoadResponse.class);
} catch (Exception e) {
logger.error("Error calling CubeMaster API: {}", e.getMessage());
throw new RuntimeException("API call failed", e);
}
/create-load endpoint with the request JSON.restTemplate.exchange call to inspect request/response data.UI Element: Logs can be viewed in the console or integrated into a monitoring tool like ELK Stack for a production environment.