【问题标题】:Dynamic JSON urls with JSP and Spring-mvc使用 JSP 和 Spring-mvc 的动态 JSON url
【发布时间】:2012-02-28 10:26:08
【问题描述】:

我想通过 JSON GET 将变量 wordId 传递给我的 web 应用程序中的 Spring-mvc 控制器。我对使用 json 的静态 url 没有任何问题,但我不知道使用动态/参数 url 的最佳做法是什么。

控制器部分:

@RequestMapping(value="/delete/{wordId}", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteWord(@RequestParam ("wordId") Long wordId, Principal principal) {

     wordService.deleteWord(wordId, principal.getName());
}

JSP 部分:

<c:choose>
    <c:when test="${not empty accountWords}">
        <c:forEach items="${accountWords}" var="word" varStatus="status">
            <li class="word">
                <input type="checkbox" name="word" class="word_checkbox" value="" />
                <span>${word.word}</span>
                <s:url value="/words/delete/${word.wordId}" var="delete_word"></s:url>
                <a href="${delete_word}"><img src="resources/gfx/delete.png" /></a>
            </li>
        </c:forEach>
    </c:when>
</c:choose>

到目前为止的jQuery部分:

$("li.word a").click(function(e) {
    e.preventDefault();
    var deleteUrl = ...
    $.getJSON(deleteUrl, function() {

    });
});

你能告诉我的 jquery 部分应该如何将 wordId 变量传递给控制器​​吗?我可以从标签的 href 属性中获取 url,但我想要相对 url。我被卡住了……

更新:

 $("#testJSON").click(function() {
    $.getJSON("admin/json.html", function(w) {
        $('#span_json').html("w.wordId + "<br>" + w.word);
    });
});

【问题讨论】:

  • 我只尝试了静态网址 [上面更新] 没问题,但我不知道如何用参数很好地做到这一点。

标签: java jquery json jsp spring-mvc


【解决方案1】:

由于 wordId 是 URL 的一部分,您应该使用 @PathVariable 注释而不是 @RequestParam。

另外,由于您询问了最佳实践,我应该指出,将 HTTP GET 方法用于非幂等操作并不是一个好的实践。换句话说,您不应该将 GET 用于更改服务器端数据的操作,例如从数据库中删除记录。

用于执行记录删除的正确 HTTP 方法是HTTP DELETE 方法。一些较旧的浏览器不支持 DELETE,因此您会发现很多代码会执行 POST 以进行删除。不过,我认为这已经不是什么大问题了。详情请参阅http://annevankesteren.nl/2007/10/http-method-support

使用 DELETE 而不是 GET 不仅仅是为了“以正确的方式做事”的好主意......它实际上可以帮助您避免一些令人讨厌的问题。有一些浏览器插件可以通过预取页面上的所有链接并将它们存储在本地缓存中来加速人们的网络体验。如果用户安装了这些插件之一,该插件将“点击”您页面上的每个删除链接!此外,如果您正在构建面向公众的应用程序,搜索引擎爬虫也会跟踪您的删除链接。我在现实世界中看到过这种情况,所以相信我,这是一个真正的问题!

另一个 RESTful 最佳实践是使用遵循 /noun/{id} 模式的 URL,将 HTTP 方法用作动词。因此,与其将 /delete/{wordId} 与 GET 一起使用,不如将 /word/{wordId} 与 DELETE 一起使用。

根据我建议的所有更改,您的代码将如下所示:

控制器

@RequestMapping(value="/word/{wordId}", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteWord(@PathVariable ("wordId") Long wordId, Principal principal) {
     wordService.deleteWord(wordId, principal.getName());
}

不幸的是,当您使用 DELETE 而不是 GET 时,jQuery 和 JSP 变得有点棘手。 GET 真的很诱人,因为您可以像这样构建一个链接:

<a href="${delete_word}"><img src="resources/gfx/delete.png" /></a>

要让浏览器改为使用 DELETE,您需要有一个方法为 DELETE 的表单,或者您需要调用一些执行 Ajax DELETE 的 JavaScript。 (因为您已经在使用 Ajax,这就是我将采用的技术。)我首先将您的链接更改为按钮:

<button class="delete-button" id="delete_${delete_word}"><img src="resources/gfx/delete.png" /></button>

这将创建一个按钮,该按钮将您要删除的单词的 id 存储在按钮本身的 id 中。不知何故,您需要将要删除的单词的 id 与每个按钮相关联,这是一种方法。我见过其他人将 id 放在按钮旁边的隐藏跨度中。 (说实话,我从不喜欢这两种技术,我希望有人能以更好的方式跟进我的回答。)

无论如何,随着 JSP 主体的更改,您还需要添加一些 jQuery 来处理所有删除按钮的单击。 (请注意,我在按钮上放置了一个名为“delete-button”的类,以便在 jQuery 中轻松引用。)

jQuery:

$(".delete-button").on("click", function() {
    var wordId = $(this).attr("id").substring("delete_".length);
    $.ajax({
        type: "DELETE",
        url: "/word/" + wordId,
        success: function() {
            // Maybe put some code here that deletes the <li> ?
        }
    }); 
});

注意我是如何从被点击按钮的 id 属性中提取单词 id 的:

var wordId = $(this).attr("id").substring("delete_".length);

当然你也可以这样做:

var wordId = $(this).attr("id").substring(7);

我更喜欢第一种方式,因为它可以自我记录子字符串在做什么。在第二个例子中,数字 7 是一个神奇的数字,它不能解释发生了什么。

【讨论】:

  • 很棒的答案!非常有启发性,非常感谢您的帮助:)。我只有一个小问题。您更喜欢 PUT 而不是 POST 通过 ajax 添加新单词? [与上述情况相反的情况] 或者只是 POST 就足够了。
  • @Mariusz :应该如何使用 PUT 和 POST 之间存在细微差别,jcalcote.wordpress.com/2008/10/16/… 对此进行了很好的解释。简而言之,PUT 和 POST 之间的区别在于服务器如何处理相同 URL 和相同参数的两个 HTTP 请求。当两次调用会创建两条记录或返回错误时,我们应该使用 POST,而当重复调用无效时,我们应该使用 PUT。或者,您可以做几乎每个人都会做的事情,而忽略 PUT 并为所有 RESTful 创建使用 POST。 :-)
  • 谢谢,所以我将只使用 POST 并进行一些额外的验证,以防止提交相同的单词两次。
  • 嘿,我刚刚实现了你的做法,这很棒,但就我而言,我不得不使用: $(".delete_button").live("click", function() 因为按钮已由 ajax/jquery 渲染 :)。
猜你喜欢
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
相关资源
最近更新 更多