获取 java.lang.IllegalStateException:响应头已发送,同时在 Vert.x 中点击 API

问题描述 投票:0回答:1

我是 vert.x 的新手,正在尝试设置服务器和路由 api。我正在关注本教程:https://youtu.be/sAVJDyQd4j4

这是代码:

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);

    }
}

我收到此错误:

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)

我试图解决这个问题的是:

  1. 在出现此行的所有位置都使用 try catch:routingContext.vertx().setTimer(5000, tid ->routingContext.next());
  2. 还尝试删除 response.write("Hi Human, This is hello2");来自任何地方并将其保留到倒数第二个路由器。

但这两种方法都没有解决问题。知道造成此问题的可能原因是什么并急于解决此问题吗?

java vert.x vertx-httpclient
1个回答
0
投票

第三个路由定义与其他路由定义不同,它包含一个空格:

Route handler3=router.route("/hello ")

因此,当在第二个路由处理程序中调用

routingContext.next()
时,
Router
找不到路由并尝试将状态代码设置为
404

将定义更改为:

Route handler3=router.route("/hello")

错误应该消失。

© www.soinside.com 2019 - 2024. All rights reserved.