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接口 查看结果