SpringBoot Vert.x 二(接收参数 响应JSON)

上一篇已经可以做到响应字符串,但是其实在日常工作中,还是以JSON格式字符串为主的

接下来我们将工程进行改造

我们看VerticleMain 类的这一段代码

//编写一个get方法
router.get("/api/get").handler(handler -> {
    handler.response().end("success");
});

我们进入.handler()方法中查看

@Fluent
Route handler(Handler<RoutingContext> requestHandler);

可以看到的是 该方法里接收了一个参数 requestHandler 这个Handler 是一个接口

/**
 *  A generic event handler.
 *  <p>
 *  This interface is used heavily throughout Vert.x as a handler for all types of asynchronous occurrences.
 *  <p>
 *
 *  @author <a href="http://tfox.org">Tim Fox</a>
 */
@FunctionalInterface
public interface Handler<E> {

  /**
   * Something has happened, so handle it.
   *
   * @param event  the event to handle
   */
  void handle(E event);
}

这里有必要说明一下,就是Vertx的调用概念跟SpringBoot Web的调用是不一样的。

以下是SpringBoot Web的常见写法 我们可以推测 在访问/test/testApi 的时候 会调用Test 类里的testApi() 方法。

但是 Vertx则不同,它在注册api路由的时候,需要传递一个接口给它,然后在访问api路径的时候,会调用传递的接口。

@RestController
@RequestMapping("/test")
public class Test {

    @RequestMapping("testApi")
    public String testApi() {
        return "SUCCESS";
    }
}

知道这些后,我们可以开始我们的改造了。在注册api路由的时候,vertx要的就是一个Handler 实现类。

那么我们可以重写一个Handler 的子类 用作 “BaseController”

统一返回格式数据Model

@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class ResponeWrapper<V> {

    private int code;
    private V data;
    private String message;

    public static final ResponeWrapper<String> RESPONE_SUCCESS = new ResponeWrapper<>(0, null, "操作成功");
    public static final ResponeWrapper<String> RESPONE_FAIL = new ResponeWrapper<>(ResponeWrapperConst.OPERATE_FAIL, null, "操作失败");
}

ControllerHandler "BaseController"

public interface ControllerHandler extends Handler<RoutingContext> {
	
    //重写handle 方法 
    @Override
    default void handle(RoutingContext event) {
        handle(VertxRequest.build(event));
    }

    void handle(VertxRequest vertxRequest);
}

VertxRequest 封装了部分常用的一些方法

@Slf4j
public class VertxRequest {
    private final RoutingContext routingContext;

    private VertxRequest(RoutingContext routingContext) {
        this.routingContext = routingContext;
    }

    public static VertxRequest build(RoutingContext routingContext) {
        return new VertxRequest(routingContext);
    }



    /**
     * 构建 VertxRespone
     *
     * @return VertxRespone
     */
    public VertxRespone buildVertxRespone() {
        return VertxRespone.build(routingContext);
    }

    /**
     * 获取AccessToken 令牌
     *
     * @return
     */
    public Optional<String> getAccessToken() {
        HttpServerRequest request = routingContext.request();
        String accesstoken = null;
        if ((accesstoken = request.getHeader("accesstoken")) != null) {
        } else if ((accesstoken = request.getParam("accesstoken")) != null) {
        } else {
            Cookie cookie = request.getCookie("accesstoken");
            if (cookie != null) accesstoken = cookie.getValue();
        }
        return Optional.ofNullable(accesstoken);
    }



    /**
     * 获取参数 -String
     *
     * @param key
     * @return
     */
    public Optional<String> getParam(String key) {
        HttpServerRequest request = routingContext.request();
        return Optional.ofNullable(request.getParam(key));
    }

    /**
     * 获取参数 -Integer
     *
     * @param key
     * @return
     */
    public Optional<Integer> getParamToInt(String key) {
        Integer value = null;
        Optional<String> param = getParam(key);
        if (param.isPresent()) {
            value = Integer.valueOf(param.get());
        }
        return Optional.ofNullable(value);
    }

    /**
     * 获取参数 -Byte
     *
     * @param key
     * @return
     */
    public Optional<Byte> getParamToByte(String key) {
        Byte value = null;
        Optional<String> param = getParam(key);
        if (param.isPresent()) {
            value = Byte.valueOf(param.get());
        }
        return Optional.ofNullable(value);
    }

    /**
     * 获取参数 -Boolean
     *
     * @param key
     * @return
     */
    public Optional<Boolean> getParamToBoolean(String key) {
        Boolean value = null;
        Optional<String> param = getParam(key);
        if (param.isPresent()) {
            value = Boolean.valueOf(param.get());
        }
        return Optional.ofNullable(value);
    }

    /**
     * 获取参数 - JavaBean
     *
     * @param <T>
     * @param paramClass
     * @return
     */
    public <T> T getBodyJsonToBean(Class<?> paramClass) {
        String bodyAsString = routingContext.getBodyAsString();
        T param = null;
        try {
            param = (T) JsonUtils.jsonToObject(bodyAsString, paramClass);
        } catch (IOException e) {
            log.warn("getParamBean json to object fial body as string: [{}]", bodyAsString, e);
            throw new ValidationException("json to object param fail");
        }
        return param;
    }
}

VertxRespone 封装响应数据

@Slf4j
public class VertxRespone {

    private final RoutingContext routingContext;

    private VertxRespone(RoutingContext routingContext) {
    this.routingContext = routingContext;
}

    public static VertxRespone build(RoutingContext routingContext) {
        return new VertxRespone(routingContext);
    }


    public void respone(ResponeWrapper responeWrapper) {
        HttpServerResponse httpServerResponse = routingContext.response();
        httpServerResponse.putHeader("Content-Type", "text/json;charset=utf-8");
        try {
            // 转换为JSON 字符串
            httpServerResponse.end(JsonUtils.objectToJson(responeWrapper));
        } catch (JsonProcessingException e) {
            log.error("serialize object to json fail wrapper: [{}]", responeWrapper);
            e.printStackTrace();
        }
    }

    public void responeSuccess(Object data) {
        respone(new ResponeWrapper(0, data, "操作成功"));
    }

    public void responeState(boolean state) {
        if (state) {
            respone(ResponeWrapper.RESPONE_SUCCESS);
        } else {
            respone(ResponeWrapper.RESPONE_FAIL);
        }
    }
}

以上 有了这些, 我们接下来重新写api接口 回到VerticleMain 类

@Slf4j
public class VerticleMain extends AbstractVerticle {


    @Override
    public void start() throws Exception {
        super.start();
        //路由
        Router router = Router.router(vertx);
        //编写一个get方法
        router.get("/api/get").handler((ControllerHandler) vertxRequest -> {
            VertxRespone vertxRespone = vertxRequest.buildVertxRespone();
            Map<String, String> stringMap = new HashMap<>();
            stringMap.put("name", "大白");
            vertxRespone.responeSuccess(stringMap);
        });
        //start listen port
        HttpServer server = vertx.createHttpServer();
        server.requestHandler(router).listen(8888, handler -> {
            log.info("vertx run prot : [{}] run state : [{}]", 8888, handler.succeeded());
        });
    }
}

最后我们方法api接口 查看结果

QQ20200131-214229@2x

Github 源码