public class LeanS1 extends AbstractVerticle { @Override public void start() throws Exception { Router router = Router.router(vertx); router.route("/test").handler(this::test3); router.route().handler(CookieHandler.create()); router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx))); //...... }
在运行的时候,浏览器输入:localhost:8080/test ,就会报错:
严重: Unexpected exception in route java.lang.NullPointerException at io.robin0909.ann.init.LeanS1.test3(LeanS1.java:47) at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:219) at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:120) at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:120) at io.vertx.ext.web.impl.RouterImpl.accept(RouterImpl.java:79) at io.vertx.core.http.impl.Http1xServerConnection.processMessage(Http1xServerConnection.java:433) at io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:141) at io.vertx.core.http.impl.HttpServerImpl$ServerHandlerWithWebSockets.handleMessage(HttpServerImpl.java:683) at io.vertx.core.http.impl.HttpServerImpl$ServerHandlerWithWebSockets.handleMessage(HttpServerImpl.java:636) at io.vertx.core.net.impl.VertxHandler.lambda$channelRead$1(VertxHandler.java:146) at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:337) at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:195) at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:144) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.vertx.core.http.impl.HttpServerImpl$Http2UpgradeHandler.channelRead(HttpServerImpl.java:952) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.vertx.core.http.impl.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:60) at io.vertx.core.http.impl.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:141) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Unknown Source)
当把sessionHandler设为router的第一个匹配的route时,运行正常,正确代码如下:
public void start() throws Exception { Router router = Router.router(vertx); router.route().handler(CookieHandler.create()); router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx))); router.route("/test").handler(this::test3); //.....
对于router.route().handler(...) 所指定的通用路径处理函数,无论指定了多少个通用路径函数,都会在访问是被顺序执行一遍。 但是对于router.route("/test").handler(...) 所指定的专用路径处理函数,如果指定了多个,那么不会自动全部执行, 只执行第一个。只有遇到routingContext.next();指令的时候才会继续执行下一个处理函数
这点可以通过代码测试。
比如:
public void start() throws Exception { Router router = Router.router(vertx); router.route().handler(CookieHandler.create()); router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx))); router.route("/test").handler(this::test3); router.route("/test").handler(this::test4); router.route("/test").handler(this::test5); //.....
对于上述代码,当在浏览器输入localhost:8080/test的时候, test3的结尾如果没有next指令,test4,test5就不会被执行。
特别注意:如下代码是创建一个路由器,执行多次就创建多个。所以,如果是多个verticle都执行这句,那么他们的session就无法共享
Router router = Router.router(vertx);
原文地址:http://blog.51cto.com/kankan/2101596