By nghxni

Technical article

PlatformHttp v3.0.0: JSONPath extraction at the entry, stable UTF-8 responses

PlatformHttp v3.0.0 packs an order-transform baseline into one route package: an Undertow HTTP Listener receives order JSON, JSONPath extracts orderId at the entry, servicelog keeps the request observable, and jsonResponseProcessor writes back stable UTF-8 JSON. Here is the design, plus two curls to validate it.

The entry must be strict and observable

Integration services facing upstream systems share four goals: a clear HTTP Listener entry, key fields such as orderId extracted as early as possible, service-level logs for troubleshooting, and stable JSON responses without Chinese encoding issues. PlatformHttp@v3.0.0 covers all four in a single route.

Listener switch, port, and a versioned URL

common.config.properties controls runtime listening: HTTP.Listener=true enables Undertow registration, server.port=18080 fixes the external port, and route endpoints resolve against it at runtime.

server.port=18080
HTTP.Listener=true
system.components=undertowhttp

service.config.properties carries the service identity (service.name=PlatformHttp, service.version=3.0.0). The main entry injects {{service.version}} into the URL and restricts the method, so the final request path is POST /3.0.0/transform/order — API versioning stays explicit in the path.

<from uri="undertow:http://0.0.0.0:{{server.port}}/{{service.version}}/transform/order?httpMethodRestrict=POST" />

Extract once at the entry, reuse downstream

The route extracts orderId three ways — log, exchange property, header — then writes the JSON response:

<log message="orderId (JSONPath): ${jsonpath($.orderId)}"/>
<setProperty name="extractedOrderId"><jsonpath>$.orderId</jsonpath></setProperty>
<setHeader name="OrderId"><jsonpath>$.orderId</jsonpath></setHeader>
<transform><simple>{"status": "success", "message": "请求处理完成"}</simple></transform>
<process ref="jsonResponseProcessor"/>
<setHeader name="Content-Type"><constant>application/json</constant></setHeader>

servicelog tracing

servicelog captures request headers and body, so the entry is observable and link-level troubleshooting does not wait for downstream systems.

Downstream-ready

orderId lands in both the extractedOrderId property and the OrderId header, ready for later routing decisions and downstream forwarding.

Stable UTF-8 write-back

jsonResponseProcessor plus the Content-Type: application/json response header keep Chinese JSON output consistent — no garbled text.

Two curls, real responses

The main transform interface takes an order JSON POST and returns the fixed success response:

curl -X POST "http://localhost:18080/3.0.0/transform/order" \
  -H "Content-Type: application/json" \
  -d "{\"orderId\":\"ORD-20260409-001\",\"amount\":299.50}"

{"status":"success","message":"请求处理完成"}

The second entry, /3.0.0/transform/order1, inlines the extracted orderId into the status field — a direct check that JSONPath extraction works:

curl -X POST "http://localhost:18080/3.0.0/transform/order1" \
  -H "Content-Type: application/json" \
  -d "{\"orderId\":\"ORD-20260409-002\"}"

{"status":"ORD-20260409-002","message":"请求处理完成"}

When the call fails, check in order

  1. Port not reachable: confirm HTTP.Listener=true and server.port=18080, and that no other process occupies 18080.
  2. 405 method rejected: the endpoint sets httpMethodRestrict=POST, so the call must use POST.
  3. Path mismatch: the version segment comes from {{service.version}} — the URL must be /3.0.0/transform/order or /3.0.0/transform/order1.
  4. Garbled Chinese: keep jsonResponseProcessor in the response path and the Content-Type: application/json header.
Transform components guideLightESB-Camel repository