SpringBoot Vert.x 五(Body as Json)

在应用场景中 ,经常有提交Body 为 json的场景

当然 vertx 也对这方面有对应的处理

新增注解

/**
 * request body as json
 *
 * @author pencilso
 * @date 2020/1/23 10:27 下午
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestBody {

}

再次改造VerticleMain 里的 registerControllerMethod 方法

增加判断是否有 @RequestBody 的判断

private void registerControllerMethod(@NotNull Router router, @NotNull RequestMapping classRequestMapping, @NotNull Class<?> controllerClass, @NotNull Object controller) {
    //获取控制器里的方法
    Method[] controllerClassMethods = controllerClass.getMethods();
    Arrays.asList(controllerClassMethods).stream()
            .filter(method -> method.getAnnotation(RequestMapping.class) != null)
            .forEach(method -> {
                try {
                    RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class);
                    String superPath = classRequestMapping.value()[0];
                    String methodPath = methodRequestMapping.value()[0];
                    //if api path empty skip
                    if (StringUtils.isEmpty(superPath) || StringUtils.isEmpty(methodPath)) return;
                    String url = VerticleUtils.buildApiPath(superPath, methodPath);
                    //build route
                    Route route = VerticleUtils.buildRouterUrl(url, router, methodRequestMapping.method());
                    //run controller method get Handler object
                    Handler<RoutingContext> methodHandler = (Handler<RoutingContext>) method.invoke(controller);
                    //register bodyAsJson handler
                    Optional.ofNullable(method.getAnnotation(RequestBody.class)).ifPresent(requestBody -> {
                        route.handler(BodyHandler.create());
                    });
                    //register controller mthod Handler object
                    RequestBlockingHandler requestBlockingHandler = Optional.ofNullable(method.getAnnotation(RequestBlockingHandler.class)).orElseGet(() -> controllerClass.getAnnotation(RequestBlockingHandler.class));
                    if (requestBlockingHandler != null) {
                        //register blocking handler
                        route.blockingHandler(methodHandler);
                    } else {
                        route.handler(methodHandler);
                    }
                    log.info("register controller -> [{}]  method -> [{}]  url -> [{}] ", controllerClass.getName(), method.getName(), url);
                } catch (Exception e) {
                    log.error("registerControllerMethod fail controller: [{}]  method: [{}]", controllerClass, method.getName());
                }
            });
}

新增参数Moel

@Data
public class LoginModel {
    private String username;
    private String password;
}

写一个POST 请求示例

@RequestBody
@RequestMapping(value = "userLogin", method = RequestMethod.POST)
public ControllerHandler userLogin() {
    return vertxRequest -> {
        LoginModel loginModel = vertxRequest.getBodyJsonToBean(LoginModel.class);
        vertxRequest.buildVertxRespone().responeSuccess(loginModel);
    };
}

使用Postman 测试调用 不出意外的话 是成功的

QQ20200131-232022@2x

另外 顺便记一下我之前遇到的一个问题

这种写法 vertxRequest.getParam("xxxx") 在POST 情况下 是无法接收到参数的

需要添加@RequestBody 后才可以接收到参数

@RequestMapping(value = "userLogin", method = RequestMethod.POST)
public ControllerHandler userLogin() {
    return vertxRequest -> {
        String username = vertxRequest.getParam("username").orElse("not found");
        String password = vertxRequest.getParam("password").orElse("not found");
        Map<String, String> map = new HashMap<>();
        map.put("username", username);
        map.put("password", password);
        vertxRequest.buildVertxRespone().responeSuccess(map);
    };
}

Github 源码