2016-06-19 3 views
5

Vert.xウェブサーバーを使用して、Reactアプリを静的コンテンツとして提供しています。これを経路/から配信したい場合は、Reactアプリ内には、表示するページを決定するreact-routerを使用する独自のルーティングがあります。これは私がlocalhost:12001を要求することから始め、それはまた、正しくパスはその時点から変化し処理する場合期待どおりに動作java vert.xウェブサーバーを使用して1ページのrectアプリケーションを提供する

Vertx vertx = Vertx.vertx(); 
HttpServer server = vertx.createHttpServer(); 
Router router = Router.router(vertx); 
router.route().handler(BodyHandler.create()); 
router.route(HttpMethod.POST, "/rest/foo").handler(new FooHandler()); 
router.route(HttpMethod.GET, "/*").handler(StaticHandler.create()).failureHandler(event -> { // This serves up the React app 
    event.response().sendFile("webroot/index.html").end(); 
}); 
server.requestHandler(router::accept).listen(12001); 

は、これまでのところ、私は次のよう持っています。しかし、私がページのいずれかをリフレッシュしようとすると、react routerで処理されたパスがあると、サーバログにエラーが発生します(ページは正しく読み込まれます)。

誰もが問題の内容と解決方法を知っていますか?

SEVERE: Unexpected exception in route 
java.lang.IllegalStateException: Response has already been written 
    at io.vertx.core.http.impl.HttpServerResponseImpl.checkWritten(HttpServerResponseImpl.java:561) 
    at io.vertx.core.http.impl.HttpServerResponseImpl.end0(HttpServerResponseImpl.java:389) 
    at io.vertx.core.http.impl.HttpServerResponseImpl.end(HttpServerResponseImpl.java:328) 
    at co.uk.foo.webserver.server.WebServer.lambda$initialiseRoutes$0(WebServer.java:67) 
    at co.uk.foo.webserver.server.WebServer$$Lambda$4/1197365356.handle(Unknown Source) 
    at io.vertx.ext.web.impl.RouteImpl.handleFailure(RouteImpl.java:227) 
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:76) 
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:94) 
    at io.vertx.ext.web.impl.RoutingContextImpl.doFail(RoutingContextImpl.java:355) 
    at io.vertx.ext.web.impl.RoutingContextImpl.fail(RoutingContextImpl.java:119) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.lambda$sendStatic$2(StaticHandlerImpl.java:198) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl$$Lambda$17/1050258443.handle(Unknown Source) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.wrapInTCCLSwitch(StaticHandlerImpl.java:245) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.getFileProps(StaticHandlerImpl.java:264) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.sendStatic(StaticHandlerImpl.java:184) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.handle(StaticHandlerImpl.java:141) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.handle(StaticHandlerImpl.java:51) 
    at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:221) 
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:78) 
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:94) 
    at io.vertx.ext.web.handler.impl.BodyHandlerImpl$BHandler.doEnd(BodyHandlerImpl.java:155) 
    at io.vertx.ext.web.handler.impl.BodyHandlerImpl$BHandler.end(BodyHandlerImpl.java:141) 
    at io.vertx.ext.web.handler.impl.BodyHandlerImpl.lambda$handle$34(BodyHandlerImpl.java:61) 
    at io.vertx.ext.web.handler.impl.BodyHandlerImpl$$Lambda$14/1403708668.handle(Unknown Source) 
    at io.vertx.core.http.impl.HttpServerRequestImpl.handleEnd(HttpServerRequestImpl.java:411) 
    at io.vertx.core.http.impl.ServerConnection.handleEnd(ServerConnection.java:286) 
    at io.vertx.core.http.impl.ServerConnection.processMessage(ServerConnection.java:404) 
    at io.vertx.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:134) 
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:515) 
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:421) 
    at io.vertx.core.http.impl.VertxHttpHandler.lambda$channelRead$20(VertxHttpHandler.java:80) 
    at io.vertx.core.http.impl.VertxHttpHandler$$Lambda$16/1532360211.run(Unknown Source) 
    at io.vertx.core.impl.ContextImpl.lambda$wrapTask$18(ContextImpl.java:333) 
    at io.vertx.core.impl.ContextImpl$$Lambda$11/511598695.run(Unknown Source) 
    at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:225) 
    at io.vertx.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:80) 
    at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:124) 
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318) 
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:304) 
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:276) 
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:263) 
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318) 
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:304) 
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846) 
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382) 
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) 
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112) 
    at java.lang.Thread.run(Thread.java:745) 

Jun 26, 2016 4:22:08 PM io.vertx.ext.web.impl.RoutingContextImplBase 
SEVERE: Unexpected exception in route 
java.lang.IllegalStateException: Head already written 
    at io.vertx.core.http.impl.HttpServerResponseImpl.doSendFile(HttpServerResponseImpl.java:434) 
    at io.vertx.core.http.impl.HttpServerResponseImpl.sendFile(HttpServerResponseImpl.java:334) 
    at io.vertx.core.http.impl.HttpServerResponseImpl.sendFile(HttpServerResponseImpl.java:52) 
    at io.vertx.core.http.HttpServerResponse.sendFile(HttpServerResponse.java:275) 
    at io.vertx.core.http.HttpServerResponse.sendFile(HttpServerResponse.java:262) 
    at co.uk.foo.webserver.server.WebServer.lambda$initialiseRoutes$0(WebServer.java:67) 
    at co.uk.foo.webserver.server.WebServer$$Lambda$4/1197365356.handle(Unknown Source) 
    at io.vertx.ext.web.impl.RouteImpl.handleFailure(RouteImpl.java:227) 
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:76) 
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:94) 
    at io.vertx.ext.web.impl.RoutingContextImpl.doFail(RoutingContextImpl.java:355) 
    at io.vertx.ext.web.impl.RoutingContextImpl.fail(RoutingContextImpl.java:119) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.lambda$sendStatic$2(StaticHandlerImpl.java:189) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl$$Lambda$17/1050258443.handle(Unknown Source) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.getFileProps(StaticHandlerImpl.java:284) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.sendStatic(StaticHandlerImpl.java:184) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.handle(StaticHandlerImpl.java:141) 
    at io.vertx.ext.web.handler.impl.StaticHandlerImpl.handle(StaticHandlerImpl.java:51) 
    at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:221) 
    at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:78) 
    at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:94) 
    at io.vertx.ext.web.handler.impl.BodyHandlerImpl$BHandler.doEnd(BodyHandlerImpl.java:155) 
    at io.vertx.ext.web.handler.impl.BodyHandlerImpl$BHandler.end(BodyHandlerImpl.java:141) 
    at io.vertx.ext.web.handler.impl.BodyHandlerImpl.lambda$handle$34(BodyHandlerImpl.java:61) 
    at io.vertx.ext.web.handler.impl.BodyHandlerImpl$$Lambda$14/1403708668.handle(Unknown Source) 
    at io.vertx.core.http.impl.HttpServerRequestImpl.handleEnd(HttpServerRequestImpl.java:411) 
    at io.vertx.core.http.impl.ServerConnection.handleEnd(ServerConnection.java:286) 
    at io.vertx.core.http.impl.ServerConnection.processMessage(ServerConnection.java:404) 
    at io.vertx.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:134) 
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:515) 
    at io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:421) 
    at io.vertx.core.http.impl.VertxHttpHandler.lambda$channelRead$20(VertxHttpHandler.java:80) 
    at io.vertx.core.http.impl.VertxHttpHandler$$Lambda$16/1532360211.run(Unknown Source) 
    at io.vertx.core.impl.ContextImpl.lambda$wrapTask$18(ContextImpl.java:333) 
    at io.vertx.core.impl.ContextImpl$$Lambda$11/511598695.run(Unknown Source) 
    at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:225) 
    at io.vertx.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:80) 
    at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:124) 
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318) 
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:304) 
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:276) 
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:263) 
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318) 
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:304) 
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846) 
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382) 
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) 
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112) 
    at java.lang.Thread.run(Thread.java:745) 
+0

私は、その反応はあなたがリフレッシュするときにブラウザがvert.xバックエンドに存在しないパスを取得しようとするパスを変更するには、新しいURLを生成していると思います。私は、これらのカスタムパスをhtmlファイルにマップするルールを書く必要があると思います。たぶんあなたは生成されたパスを投稿して、あなたのhtmlファイルへの翻訳を助けることができます。 –

+0

ページを更新するときにChromeコンソールで何が起こっているのかを確認します。そこにあなたが見なければならないのは、間違っている必要があります。失敗したリクエストの写真を添付し​​てください。 – haschibaschi

+0

使用しているVert.xのバージョンは? – Vadeg

答えて

1

私はこの問題で、多くの異なるアプローチを試してみましたが、どこにもなっていません。代わりに私は私が望むやり方で動作する私自身のhandlerを書くことに決めました。私は私の元の質問には何の誤りも見られません。

import io.vertx.core.Handler; 
import io.vertx.core.http.HttpServerRequest; 
import io.vertx.ext.web.RoutingContext; 
import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 

public class ReactAppHandler implements Handler<RoutingContext> { 

    private static final Logger LOGGER = LogManager.getLogger(ReactAppHandler.class); 

    private static final String WEB_ROOT_DIR = "webroot"; 
    private static final String INDEX_HTML = "/index.html"; 

    @Override 
    public void handle(RoutingContext event) { 

     HttpServerRequest request = event.request(); 
     String path = event.normalisedPath(); 

     LOGGER.info("Received a request for [" + path + "]."); 

     String requestedFilepath = path; 

     if ("/".equals(requestedFilepath)) { 
      LOGGER.info("Requested file is root path. Remapping to return the index page."); 
      requestedFilepath = INDEX_HTML; 
     } 

     final String fileToCheck = WEB_ROOT_DIR + requestedFilepath; 
     LOGGER.info("Checking if file exists at [" + fileToCheck + "]."); 

     event.vertx().fileSystem().exists(fileToCheck, fileExistsCheck -> { 

      String fileToSend = WEB_ROOT_DIR + INDEX_HTML; 

      if (fileExistsCheck.succeeded() && fileExistsCheck.result()) { 
       LOGGER.info("File exists at path."); 
       fileToSend = fileToCheck; 
      } else { 
       LOGGER.info("Could not find requested file, the index page will be returned instead."); 
      } 

      LOGGER.info("Returning file [" + fileToSend + "]."); 
      request.response().sendFile(fileToSend); 
     }); 
    } 
} 
+0

あなたのハンドラで記述している動作は、あなたが求めているものではありません。あなたがしていたはずのことは、ファイルが存在するかどうかと、それがindex.htmlに再ルーティングされないかどうかをチェックする単純なハンドラです。このようにして、キャッシュサポートなどの静的ハンドラのすべての機能を利用できます。 –

2

ここで、あなたが最後のメソッドを呼び出すべきではないファイルを返すとき:

router.route(HttpMethod.GET, "/*").handler(StaticHandler.create()).failureHandler(event -> { // This serves up the React app 
    event.response().sendFile("webroot/index.html").end(); 
}); 

理由は、ファイルを送信すると、最適化における応答にファイルを送り出すでしょう非同期呼び出しであるということですあなたが最後に電話をしたら、応答は閉じるNOW

あなたのファイルは非常に小さいので、OSはすぐに一度にそれをポンピングすることができます(ブラウザが正しく受信します)が、OSがすでに終了しているときに接続を終了しようとしますそれはあなたのためです。あなたが持っている必要がありますどのような

は次のとおりです。

router.route(HttpMethod.GET, "/*").handler(StaticHandler.create()).failureHandler(event -> { // This serves up the React app 
    event.response().sendFile("webroot/index.html"); 
}); 
+0

ありがとうございます。私はそれを試してみて、これは例外の1つを解決するように見えますが、私はまだ 'java.lang.IllegalStateException:Head already written'エラーが出るようです。 –

関連する問題