By nghxni

Technical article

HTTP listener and Undertow request routing: one request-response loop

When a LightESB service exposes HTTP APIs, the route XML is only half of the picture — the other half is the runtime listener switch. Using HttpRequestSrv as the example, this article shows how HTTP.Listener, server.port, and system.components=undertowhttp gate Undertow registration, and how a single route closes the request-response loop.

The listener switch lives outside the route XML

In LightESB, Undertow component registration is controlled by configuration, not by the route. HTTP.Listener=true registers Undertow and exposes HTTP routes; HTTP.Listener=false skips registration entirely. Teams decide whether a service is externally reachable without touching a line of route XML.

Three keys in common.config.properties carry the whole decision: server.port sets the runtime listening port, HTTP.Listener switches the listener on, and system.components=undertowhttp enables the Undertow component capability.

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

Two undertow: entries, one strict method guard

HttpRequestSrv defines two Undertow entries in http-request-route.xml:

<from uri="undertow:http://0.0.0.0:{{server.port}}/api/httprequest/test?httpMethodRestrict=POST" />
<from uri="undertow:http://0.0.0.0:{{server.port}}/api/test?httpMethodRestrict=POST"/>

0.0.0.0 listens on all NICs, {{server.port}} injects the environment-level port, and httpMethodRestrict=POST rejects non-POST methods right at the endpoint — a clean entry pattern that keeps business processors focused.

Listener, forwarder, responder: the closed loop

The first route acts as both inbound listener and outbound requester: it receives the external request on /api/httprequest/test, logs the start with servicelog, forwards to the local endpoint /api/test with bridgeEndpoint=true and explicit timeouts, then logs completion and returns the response.

<to uri="servicelog:info?message=开始处理HTTP请求&amp;showBody=true&amp;maxBodyLength=500"/>
<to uri="http://0.0.0.0:18083/api/test?httpMethod=POST&amp;contentType=application/json&amp;bridgeEndpoint=true&amp;connectTimeout=5000&amp;socketTimeout=30000"/>
<to uri="servicelog:info?message=HTTP请求完成&amp;showBody=true&amp;maxBodyLength=5000"/>

The second route handles /api/test and returns a fixed JSON payload — {"message": "HTTP Response Test"} — so the whole loop is verifiable in seconds.

Prove the loop with curl

POST to the entry listener; the route forwards to /api/test and the fixed JSON comes back:

curl -X POST "http://localhost:18083/api/httprequest/test" \
  -H "Content-Type: application/json" \
  -d "\{\"orderId\":\"A1001\",\"amount\":199.9\}"

{"message": "HTTP Response Test"}

To verify the downstream route in isolation, POST an empty body to /api/test directly — it answers with the same fixed response. Entry and completion logs stay visible through servicelog.

Where the loop breaks

API not reachable

Confirm HTTP.Listener=true, that server.port is valid and not occupied, that the route file was loaded, and that startup logs show Undertow registration success.

Port conflict

Another process already binds the same port — or a hot reload did not release the previous context. Free the port and check the release lifecycle.

405 or route miss

The routes restrict to POST, so a GET returns 405. Also check that the request path matches the route URI exactly.

Forward timeout, missing body

Check connectTimeout/socketTimeout and that /api/test is reachable. If logs lack the request body, servicelog needs showBody=true and a larger maxBodyLength.

HTTP route basicsLightESB-Camel repository