在 Spark Java 中将路由处理卸载到不同 class 的 intended/better 方法是什么?

What is the intended/better way to offload route handling to a different class in Spark Java?

我正在尝试使用以下路由定义将不同的子路径处理分成不同的 classes:

public static void main(String[] args) {

    port(Integer.valueOf(System.getenv("PORT")));
    staticFileLocation("/public");

    get("/test", (req, res) -> "OK");
    path("/api", () -> {
        path("/x", () -> {
            post("/action1",      (request, response) -> XAPIHandler.action1(request, response));
        });
        path("/y", () -> {
            post("/action1",       (request, response) -> YAPIHandler.action1(request, response));
            post("/action2",       (request, response) -> YAPIHandler.action2(request, response));
            post("/action3",       (request, response) -> YAPIHandler.action3(request, response));
            get("/action4",        (request, response) -> YAPIHandler.action4(request, response));
        });
    });
}

然后我有以下 API 处理程序 class 结构:

public class YAPIHandler {

    public static Object action1(Request request, Response response) {
        try {
            //Some logic goes here
            response.header("Content-Type", "application/json");
            response.status(200);
            response.body(myJsonObject.serialize()); //a bit of pseudocode here, in reality using Gson library
        } catch (Exception e) {
            response.status(500);
            response.body("Some error message");
        }
        return response.body();
    }
    ...
}

这种特殊的方法对我来说似乎没问题并且运行良好,直到在一个特定的场景中(actionZ)它开始 returning 404 而不管通过 [=17= 设置了什么状态].经过一些测试后,我意识到这是因为 actionZ 没有 return 在成功的情况下除了 200 状态之外没有向用户发送任何内容,因此从未明确设置响应主体。调用 response.body("") 解决了 404 问题,但让我意识到我不明白 Spark Java 框架是如何工作的,让我怀疑是否单独的 API 处理程序 classes 是开始的正确方法。

2个问题:

  1. 有没有办法在不显式调用 response.body("") 的情况下使用上述代码结构 return 200 ok 响应空体?
  2. 是否有另一种方法可以将处理程序逻辑拆分为单独的 classes,从而更符合 Spark "ways of doing things"?

P.S. 我看到关于路由的 Spark 文档似乎建议在以下示例中进行某种处理程序分解:

path("/api", () -> {
    before((q, a) -> log.info("Received api call"));
    path("/email", () -> {
        post("/add",       EmailApi.addEmail);
        put("/change",     EmailApi.changeEmail);
        delete("/remove",  EmailApi.deleteEmail);
    });
    path("/username", () -> {
        post("/add",       UserApi.addUsername);
        put("/change",     UserApi.changeUsername);
        delete("/remove",  UserApi.deleteUsername);
    });
});

但我无法复制它。因此,如果有人可以从上面的示例中使用方法签名和 return 值为 EmailApi class 提供示例结构,那可能就是我正在寻找的 Q2 的答案。

将状态设置为 200,之后不使用 body()

Spark.get("/", (req, res) -> {
    res.status(200);
    return "";
});

可以通过 java8 方法引用将工作委托给某些处理程序。 假设您在 class LoginHandler:

中有一个这样的方法
public static String login(Request req, Response res) {
    // do stuff
}

然后在你的主 class 中你可以调用:

Spark.get("/login", LoginHandler::login);

关于序列化为 json 或其他格式我建议你看一下

响应变压器

文档部分:http://sparkjava.com/documentation.html#response-transformer