繁体   English   中英

使用JSP和Spring-mvc的动态JSON网址

[英]Dynamic JSON urls with JSP and Spring-mvc

我想通过JSON GET将变量wordId传递给我的webapp中的Spring-mvc Controller。 我对使用json的静态网址没有问题,但是我不知道对动态/参数化网址执行此操作的最佳做​​法。

控制器部分:

@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);
    });
});

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

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

执行记录删除的正确 HTTP方法是HTTP DELETE方法。 一些较旧的浏览器不支持DELETE,因此您会发现很多代码可以执行POST删除操作。 我认为这不再是一个大问题。 有关更多详细信息,请参见http://annevankesteren.nl/2007/10/http-method-support

为了“以正确的方式做事”,使用DELETE而不是GET并不是一个好主意……它实际上可以帮助您避免一些麻烦的问题。 有一些浏览器插件可以通过预取页面上的所有链接并将它们存储在本地缓存中来提高人们在Web上的体验。 如果用户安装了以下插件之一,则该插件将“点击”页面上的每个删除链接! 另外,如果您要构建面向公众的应用程序,则搜索引擎爬网程序还将跟踪您的删除链接。 我已经看到这种情况在现实世界中发生,所以请相信我,这是一个真正的问题!

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

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

控制者

@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是一个不可解释的魔术数字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM