• vert.x笔记:3.使用vert.x发布restful接口


    原文及更多文章请见个人博客:http://heartlifes.com

    vert.x重要概念介绍:

    在第2偏笔记中,我们写了第一个vert.x的hello world代码,这里,我们把代码中用到的几个重要概念解释下。

    Vertx基类:

    Vertx类,是所有vert.x代码的入口,官方代码注释为:

    The entry point into the Vert.x Core API.
    

    即该类是所有vert.x core包API的总入口,简单理解就是,所有核心功能的API,都需要该类去调用,所有的核心功能也都需要该类提供环境上下文。

    HttpServer:

    官方注释:

    An HTTP and WebSockets server
    

    http/https/websockets服务器,vert.x发布restful服务,不需要tomcat提供servlet容器,它自己就是一台性能强大的web服务器,并且原生支持负载均衡,后面我们会讲到。

    Router类:

    先看官方代码注释:

    A router receives request from an HttpServer and routes it to the first matching Route that it contains. A router can contain many routes.
    

    Router类可以理解为一个路由器,他接收httpserver带来的请求,并将不同的请求分发到不同的路由中,如果简单对比一下spring mvc的话,可以将router理解为spring mvc中的dispatcher。

    route:

    route代表一条路由,同样,对比spring mvc,相当于spring中的@RequestMapping,他指定了restful api的请求接口路径,并将其交给handler来处理该条路由。

    Handler:

    首先来看官方代码注释:

    Specify a request handler for the route. The router routes requests to handlers depending on whether the various criteria such as method, path, etc match. There can be only one request handler for a route. If you set this more than once it will overwrite the previous handler.
    

    handler处理具体的路由请求,字面上讲就是处理某个具体的restful api。他与httpserver,router,route的关系可以用如下流程表示:

    来自httpserver的request请求-->交由路由器做分发处理-->路由器匹配到具体的路由规则-->路由到最终的handler去处理请求
    

    vert.x默认提供了很多处理器,包括但不局限于以下:

    AuthHandler 处理权限校验支持
    BodyHandler 提供所有请求上下文
    CookieHandler 提供cookie支持
    SessionHandler 提供session支持
    

    RoutingContext:

    官方代码注释:

    Represents the context for the handling of a request in Vert.x-Web.
    

    很简单,请求上下文,可以理解为servlet中的httprequest和httpresponse

    Verticle:

    A verticle is a piece of code that can be deployed by Vert.x.
    

    verticle是vert.x中,可被部署运行的最小代码块,可以理解为一个verticle就是一个最小化的业务处理引擎。
    verticle被发布部署后,会调用其内部的start方法,开始业务逻辑处理,完成后会调用stop方法,对该代码块执行销毁动作

    vert.x发布restufl api

    新建类:RestServer,代码如下

    package com.heartlifes.vertx.demo.simple;
    
    import io.vertx.core.AbstractVerticle;
    import io.vertx.core.Vertx;
    import io.vertx.core.json.JsonObject;
    import io.vertx.ext.web.Router;
    import io.vertx.ext.web.RoutingContext;
    import io.vertx.ext.web.handler.BodyHandler;
    
    public class RestServer extends AbstractVerticle {
    
    	public static void main(String[] args) {
    		// 获取vertx基类
    		Vertx vertx = Vertx.vertx();
    		// 部署发布rest服务
    		vertx.deployVerticle(new RestServer());
    	}
    
    	// 重写start方法,加入我们的rest服务处理逻辑
    	@Override
    	public void start() throws Exception {
    		// 实例化一个路由器出来,用来路由不同的rest接口
    		Router router = Router.router(vertx);
    		// 增加一个处理器,将请求的上下文信息,放到RoutingContext中
    		router.route().handler(BodyHandler.create());
    		// 处理一个post方法的rest接口
    		router.post("/post/:param1/:param2").handler(this::handlePost);
    		// 处理一个get方法的rest接口
    		router.get("/get/:param1/:param2").handler(this::handleGet);
    		// 创建一个httpserver,监听8080端口,并交由路由器分发处理用户请求
    		vertx.createHttpServer().requestHandler(router::accept).listen(8080);
    	}
    
    	// 处理post请求的handler
    	private void handlePost(RoutingContext context) {
    		// 从上下文获取请求参数,类似于从httprequest中获取parameter一样
    		String param1 = context.request().getParam("param1");
    		String param2 = context.request().getParam("param2");
    
    		if (isBlank(param1) || isBlank(param2)) {
    			// 如果参数空,交由httpserver提供默认的400错误界面
    			context.response().setStatusCode(400).end();
    		}
    
    		JsonObject obj = new JsonObject();
    		obj.put("method", "post").put("param1", param1).put("param2", param2);
    
    		// 申明response类型为json格式,结束response并且输出json字符串
    		context.response().putHeader("content-type", "application/json")
    				.end(obj.encodePrettily());
    	}
    
    	// 逻辑同post方法
    	private void handleGet(RoutingContext context) {
    		String param1 = context.request().getParam("param1");
    		String param2 = context.request().getParam("param2");
    
    		if (isBlank(param1) || isBlank(param2)) {
    			context.response().setStatusCode(400).end();
    		}
    		JsonObject obj = new JsonObject();
    		obj.put("method", "get").put("param1", param1).put("param2", param2);
    
    		context.response().putHeader("content-type", "application/json")
    				.end(obj.encodePrettily());
    	}
    
    	private boolean isBlank(String str) {
    		if (str == null || "".equals(str))
    			return true;
    		return false;
    	}
    
    }
    
    

    执行代码,打开浏览器,输入以下接口

    http://localhost:8080/get/1/2
    http://localhost:8080/post/1/2
    

    处理session代码示例:

    package com.heartlifes.vertx.demo.simple;
    
    import io.vertx.core.AbstractVerticle;
    import io.vertx.core.Vertx;
    import io.vertx.ext.web.Router;
    import io.vertx.ext.web.Session;
    import io.vertx.ext.web.handler.CookieHandler;
    import io.vertx.ext.web.handler.SessionHandler;
    import io.vertx.ext.web.sstore.LocalSessionStore;
    
    public class SessionServer extends AbstractVerticle {
    
    	public static void main(String[] args) {
    		Vertx vertx = Vertx.vertx();
    		vertx.deployVerticle(new SessionServer());
    	}
    
    	@Override
    	public void start() throws Exception {
    		Router router = Router.router(vertx);
    		// 增加cookies处理器,解码cookies,并将其放到context上下文中
    		router.route().handler(CookieHandler.create());
    		// 增加session处理器,为每次用户请求,维护一个唯一的session,这里使用内存session,后面会讲分布式的session存储
    		router.route().handler(
    				SessionHandler.create(LocalSessionStore.create(vertx)));
    		router.route().handler(routingContext -> {
    			// 从请求上下文获取session
    				Session session = routingContext.session();
    				Integer count = session.get("count");
    				if (count == null)
    					count = 0;
    				count++;
    				session.put("count", count);
    
    				routingContext.response()
    						.putHeader("content-type", "text/html")
    						.end("total visit count:" + session.get("count"));
    			});
    
    		vertx.createHttpServer().requestHandler(router::accept).listen(8080);
    	}
    
    }
    
    

    处理cookies代码示例:

    package com.heartlifes.vertx.demo.simple;
    
    import io.vertx.core.AbstractVerticle;
    import io.vertx.core.Vertx;
    import io.vertx.ext.web.Cookie;
    import io.vertx.ext.web.Router;
    import io.vertx.ext.web.handler.CookieHandler;
    
    public class CookieServer extends AbstractVerticle {
    
    	public static void main(String[] args) {
    		Vertx vertx = Vertx.vertx();
    		vertx.deployVerticle(new CookieServer());
    	}
    
    	@Override
    	public void start() throws Exception {
    		Router router = Router.router(vertx);
    		router.route().handler(CookieHandler.create());
    		router.route().handler(
    				routingContext -> {
    					Cookie cookie = routingContext.getCookie("testCookie");
    					Integer c = 0;
    					if (cookie != null) {
    						String count = cookie.getValue();
    						try {
    							c = Integer.valueOf(count);
    						} catch (Exception e) {
    							c = 0;
    						}
    						c++;
    					}
    
    					routingContext.addCookie(Cookie.cookie("testCookie",
    							String.valueOf(c)));
    					routingContext.response()
    							.putHeader("content-type", "text/html")
    							.end("total visit count:" + c);
    				});
    
    		vertx.createHttpServer().requestHandler(router::accept).listen(8080);
    	}
    
    }
    
    
  • 相关阅读:
    【c++】流状态的查询和控制
    【c++】iostreeam中的类为何不可以直接定义一个无参对象呢
    异步操作超出页面超时时间
    sql转Linq的工具
    用离职换来的领悟:人生没有最佳时机
    Log4Net日志记录两种方式
    C# FileStream复制大文件
    C#常用的集合类型(ArrayList类、Stack类、Queue类、Hashtable类、SortedList类)
    C# 读取 timestamp 时间戳 值为byte[] 类型时转换为时间戳字符串
    IIS7错误:“Web服务器被配置为不列出此目录的内容”的解决办法
  • 原文地址:https://www.cnblogs.com/heartlifes/p/6971029.html
Copyright © 2020-2023  润新知