Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Router issues with Vertx

Good morning, I begin with Vertx for java and I want to create the route example so I copy past the lines but it seems there is something wrong in Router.router(vertex) :

  • The type io.vertx.rxjava.core.Vertx cannot be resolved. It is indirectly referenced from required .class files

    • The method router(Vertx) from the type Router refers to the missing type Vertx

Here is my code :

import io.vertx.core.*;
import io.vertx.rxjava.ext.web.*;
import io.vertx.core.http.HttpHeaders;

public class Test extends AbstractVerticle{

@Override
public void start() throws Exception {

    Vertx vertx=Vertx.vertx();
    Router router = Router.router(vertx);

    Route route1 = router.route("localhost:8080/Orsys/").handler(routingContext -> {

          HttpServerResponse response = routingContext.response();
          response.setChunked(true);

          response.write("Orsys\n");

          routingContext.vertx().setTimer(5000, tid -> routingContext.next());
        });
like image 726
zackzulg Avatar asked Mar 25 '16 16:03

zackzulg


People also ask

What is router in Vertx?

public interface Router extends Handler<HttpServerRequest> A router receives request from an HttpServer and routes it to the first matching Route that it contains. A router can contain many routes. Routers are also used for routing failures.

What is routing context in Vertx?

public interface RoutingContext. Represents the context for the handling of a request in Vert. x-Web. A new instance is created for each HTTP request that is received in the Handler. handle(Object) of the router.


2 Answers

First the Vertx instance in the io.vertx.core.AbstractVerticle class refers to io.vertx.core.Vertx, not io.vertx.rxjava.core.Vertx. So you are supposed to import io.vertx.ext.web.Router rather than io.vertx.rxjava.ext.web.Router, or it won't match.

Second, the Route#route method is not a static method so first you need to create a Router instance:

Router router = Router.router(vertx);

And then invoke the route method:

router.route("/Test1").handler(routingContext -> {
            HttpServerResponse response = routingContext.response();
            response.setChunked(true);
            response.write("Test1 \n");

            routingContext.vertx().setTimer(1000, tid ->  routingContext.next());
        });

Notice that the route method does not accept the absolute URL so you needn't pass the absolute URL. Directly pass the /Test1 URL path and the host and port can be configured when createHttpServer.

Another notice is that if you want to write bytes directly to response, you should add response.setChunked(true) or an exception would be thrown:

java.lang.IllegalStateException: You must set the Content-Length header to be the total size of the message body BEFORE sending any data if you are not using HTTP chunked encoding.

Or this is better(always wnd with end):

router.route("/Test1").handler(routingContext -> {
            HttpServerResponse response = routingContext.response();
            response.putHeader("content-type", "text/html");
            response.end("<h1>Test1</h1>");
        });

By now you have established a simple route, so next step is create a HttpServer:

vertx.createHttpServer()
                .requestHandler(router::accept)
                .listen(8080, "127.0.0.1", res -> {
                    if (res.failed())
                        res.cause().printStackTrace();
                });

Well, the port and host can be passed to the listen method.

So this is the changed correct code:

import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Router;

public class TestVerticle extends AbstractVerticle {

    @Override
    public void start(Future<Void> startFuture) throws Exception {
        Router router = Router.router(vertx);

        router.route("/Test1").handler(routingContext -> {
            HttpServerResponse response = routingContext.response();
            response.setChunked(true);
            response.write("Test1 \n");

            routingContext.vertx().setTimer(1000, tid ->  routingContext.next());
        });

        vertx.createHttpServer()
                .requestHandler(router::accept)
                .listen(8080, "127.0.0.1", res -> {
                    if (res.succeeded())
                        startFuture.complete();
                    else
                        startFuture.fail(res.cause());
                });
    }
}

Run this by deploy the verticle:

public class Application {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        TestVerticle verticle = new TestVerticle();

        vertx.deployVerticle(verticle, res -> {
            if (res.failed())
                res.cause().printStackTrace();
        });
    }
}

So this is only a simple example. And if you want to build a RESTful Service, this article might help: Some Rest with Vert.x

And here is my example of a RESTful Service using Vert.x Web, which may also help:https://github.com/sczyh30/todo-backend-vert.x

I hope these can help you :)

like image 191
Eric Zhao Avatar answered Sep 27 '22 21:09

Eric Zhao


Eric Zhao's answer is great. But I want to add something.

I faced to the same issue with my Vert.x application. It first said Cannot resolve symbol 'Router'. So I import io.vertx.ext.web.Router. But my application didn't import it and said Cannot resolve symbol 'web' and also Cannot resolve symbol 'Router'.

I solved that issue by adding below dependency to my pom.xml .

Maven

<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-web</artifactId>
 <version>3.6.2</version>
</dependency>

Gradle

dependencies {
 compile 'io.vertx:vertx-web:3.6.2'
}
like image 21
CRV Avatar answered Sep 27 '22 20:09

CRV