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=undertowhttpTwo 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请求&showBody=true&maxBodyLength=500"/>
<to uri="http://0.0.0.0:18083/api/test?httpMethod=POST&contentType=application/json&bridgeEndpoint=true&connectTimeout=5000&socketTimeout=30000"/>
<to uri="servicelog:info?message=HTTP请求完成&showBody=true&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.