Java Spark请求的路由[/ users /]尚未在Spark中映射为接受:[* / *]

时间:2019-03-13 13:41:01

标签: java put

我可以通过以下方法在Postgres数据库中修改用户:

public void modifyUser(User usr){
    try (Connection conn = sql2o.beginTransaction()){
        conn.createQuery("update public.\"user\" set name=:name, lastname=:lastname, email=:email where id=:id")
                .addParameter("id", usr.getId())
                .addParameter("name", usr.getName())
                .addParameter("lastname", usr.getLastname())
                .addParameter("email", usr.getEmail())
                .executeUpdate();
        conn.commit();
    }
}
通过该方法调用的

//update
    put("/users", (request, response) -> {
        response.type("application/json");
        User user = new Gson().fromJson(request.body(), User.class);
        model.modifyUser(user);
        return new Gson().toJson(response);
    });

我用邮递员指定尸体,方法是:

{   "id": 3, 
"name": "Mary",
"lastname": "Changed",
"email": "email"
}

但是,即使post方法工作正常,此“ put”操作也会引发以下错误:

spark.http.matching.MatcherFilter - The requested route [/users/] has not been mapped in Spark for Accept: [*/*]

我不明白错误是什么。我找不到解决方法。

2 个答案:

答案 0 :(得分:1)

我知道这是一个老话题,但是我希望提供有关该主题的更多信息。

路径的“ / users”和“ / users /”是2条不同的路径,因此可以选择允许2条不同的火花路线(我认为火花实际上制作得非常好)。

下面是一个示例,当我不希望为它们使用2条不同的路由时,通常会在我的Spark服务器中解决此问题(不加急)。

path("/user", () ->
{
    get("", GenericRoutes.redirectToSlashIndex);
    get("/index.html", GenericRoutes.pathGet_index);
    get("/*", GenericRoutes.redirectToIndex);
});

这里的想法是第一个(“”)发送到第二个(“ /index.html”),而第三个(“ / *”)发送到第二个(“ /index.html)的所有不存在的路径”)。

然后在Generic Routes类中,您将得到类似的内容:

public static final Route redirectToIndex = new Route()
        {
            @Override
            public Object handle(Request request, Response response) throws Exception
            {
                String path = request.pathInfo();
                path = path.substring(0, path.lastIndexOf('/')+1)+"index.html";
                response.redirect(path, 301);
                return "<html>Redirecting...</html>";
            }
        };

public static final Route redirectToSlashIndex = new Route()
        {
            @Override
            public Object handle(Request request, Response response) throws Exception
            {
                response.redirect(request.pathInfo() + "/index.html", 301);
                return "<html>Redirecting...</html>";
            }
        };

我已经简化了我通常在这里所做的一些工作(您可能希望在这些路由中进行更多的错误处理,并通过这些路由之外的“之前”进行身份验证检查)。但是,这里有一个小例子:

  • Nav:“ / users”->调用get(“”,...)->重定向到:“ /users/index.html”
  • 导航:“ / users /”->调用get(“ / *”,...)->重定向至:“ /users/index.html”
  • 导航:“ /users/index.html”->调用get(“ / index.html”,...)->没有重定向。

因此,您可以看到使用类似的方法如何将流量发送到期望的位置。但是,有些事情要记住:

  1. 如果您有网址参数/令牌,使用它可能会出现问题(如果不小心,可能会丢失它们)
  2. 顺序很重要,因为如果“ / *”在“ /index.html”之前,则“ /users/index.html”将始终触发“ / *”(并无限重定向),而不是触发“ /”的路由index.html“
  3. 在我的示例中,我使用的是get,因此这种方法通常是预期的方法(保存#1),但是与其他方法(例如put / post)一起更改路径可能会导致意外结果,因此使用这种方法时要小心,不要将流量重定向到意外的端点。
  4. 如果SEO对您来说很重要,则可以考虑使用上文所述的301方法来向正在抓取您的网站的用户提示您的输出URL是永久重定向。最好为所有端点设置相同的路由(这也是有效的替代方法,请参见下文)。

故意使我的矿井比您的矿井复杂一些,这是您处理矿井的方法:

path("/user", () ->
{
    /*Looks like you mentioned you had a post with the 'first version', so I think like this?*/
    post("", UserRoutes.postUsers); //post: /users
    put("", UserRoutes.putUsers); //put: /users
    put("/*", UserRoutes.putUsers); //put: /users/
});

请注意,在上面的最后一个放置示例中,您可以执行“ / *”或仅执行“ /”。使用*,您将捕获从“ / users /”开始的任何路径,而如果没有*,则仅允许通过“ / users /”。因此,使用*可以执行“ / users / e13a319e-16d9-3ff5-a83c-96564007998e”,它将触发端点,但是如果没有*,则相同的路径将失败,这与上面的#1直接相关。

因此,您采用哪种方法实际上取决于您网站的意图以及您做什么或不希望那些碰到端点的人去做和看。编码愉快!

答案 1 :(得分:0)

不知道确切的原因,但是问题出在

put("/users", (request, response) -> {

在这种情况下,Spark希望将其写为

put("/users/", (request, response) -> {

与接受第一个版本的“ post”方法不同。