I am new to vert.x and trying to setup server and route apis. I am following this tutorial: https://youtu.be/sAVJDyQd4j4
Here is the code:
package com..vertx;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.Router;
public class Main {
public static void main(String[] args) {
// System.out.println("Hello world!");
Vertx vertx=Vertx.vertx();
Router router=Router.router(vertx);
// router.route("/something")
// .handler(routingContext->{
// HttpServerResponse response=routingContext.response();
// response.putHeader("content-type","text/plain");
// response.end("Hi Human, it's vertx you just made");
// });
Route handler1=router.route("/hello")
.handler(routingContext->{
HttpServerResponse response=routingContext.response();
response.setChunked(true); //for multiple routes, using setchunked, this is going to stream the data like reactive application where we can push the data from server to UIs
response.write("Hi Human, This is hello1");
//The below part is where we are using vertex and a scheduler to identify is there any thing else to match.
// Using which we are not going to immediately call the next router,
// rather just add the vertex code to sy that after this particular router, allow us to the next when,
// this like adding filters and going through a chaining process.
routingContext.
vertx()
.setTimer(5000, tid -> routingContext.next()); //5sec timer, and us the routingContext to go to the next router, so this basically does the search for the next router with the same name.
});
Route handler2=router.route("/hello")
.handler(routingContext->{
HttpServerResponse response=routingContext.response();
//we dont need to chunk it here, as we have already chunked it above
//response.setChunked(true); //for multiple routes, using setchunked, this is going to stream the data like reactive application where we can push the data from server to UIs
response.write("Hi Human, This is hello2");
//The below part is where we are using vertex and a scheduler to identify is there any thing else to match.
// Using which we are not going to immediately call the next router,
// rather just add the vertex code to sy that after this particular router, allow us to the next when,
// this like adding filters and going through a chaining process.
routingContext.
vertx()
.setTimer(5000, tid -> routingContext.next()); //5sec timer, and us the routingContext to go to the next router, so this basically does the search for the next router with the same name.
});
Route handler3=router.route("/hello ")
.handler(routingContext->{
HttpServerResponse response=routingContext.response();
//we dont need to chunk it here, as we have already chunked it above
//response.setChunked(true); //for multiple routes, using setchunked, this is going to stream the data like reactive application where we can push the data from server to UIs
response.write("Hi Human, This is hello3");
response.end();
});
HttpServer httpServer=vertx.createHttpServer();
httpServer.requestHandler(router).listen(8091);
}
}
And I am getting this error:
SEVERE: Unhandled exception
java.lang.IllegalStateException: Response head already sent
at io.vertx.core.http.impl.Http1xServerResponse.checkHeadWritten(Http1xServerResponse.java:709)
at io.vertx.core.http.impl.Http1xServerResponse.setStatusCode(Http1xServerResponse.java:149)
at io.vertx.ext.web.impl.RoutingContextImpl.checkHandleNoMatch(RoutingContextImpl.java:156)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:142)
at com.yashkirat.zee.vertx.Main.lambda$null$2(Main.java:49)
at io.vertx.core.impl.VertxImpl$InternalTimerHandler.handle(VertxImpl.java:948)
at io.vertx.core.impl.VertxImpl$InternalTimerHandler.handle(VertxImpl.java:919)
at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55)
at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:158)
at io.vertx.core.impl.ContextInternal.emit(ContextInternal.java:194)
at io.vertx.core.impl.VertxImpl$InternalTimerHandler.run(VertxImpl.java:937)
at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:153)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:750)
What I have tried to fix this is:
But both of the methods didn't fix it. Any idea what could be the possible cause for this and hot to fix this?
The third route definition is different from others, it contains a space:
Route handler3=router.route("/hello ")
So when routingContext.next()
is invoked in the second route handler, the Router
does not find a route and tries to set the status code to 404
.
Change the definition to:
Route handler3=router.route("/hello")
And the error should go away.