You can define two routes, one for your controller (to receive the post data) and one for serving your exact javascript file.
A more standard solution is to have a route dedicated to serve all the assets (including your javascript app). For this, look at the following answer: Routing template format for undertow
Undertow.builder().addHttpListener(8080, "0.0.0.0")
.setHandler(Handlers.path()
// Controllers
.addPrefixPath("/controller", Handlers.routing()
.post("/{id}", exchange -> {
String id = exchange.getQueryParameters().get("id").getFirst();
}))
// Serve your file, preserving any route information
.addPrefixPath("/app.js", exchange -> {
Path p = Paths.get("/path/to/app.js");
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/javascript");
exchange.getResponseSender().send(
ByteBuffer.wrap(Files.readAllBytes(p))
)})
).build().start();
With this example, your controller will be available at the route /controller/{id} and your javascript file will be served directly.
Note that this way of serving file is not optimal, it works if files are not too large. For a better way of serving files, one can play with Undertow's PathResource and PathResourceManager classes.