简体   繁体   English

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

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

I would like to pass a variable wordId through JSON GET to Spring-mvc Controller in my webapp. 我想通过JSON GET将变量wordId传递给我的webapp中的Spring-mvc Controller。 I have no problem with static url to work with json but I do not know what is best practice to do it with dynamic/parametric urls. 我对使用json的静态网址没有问题,但是我不知道对动态/参数化网址执行此操作的最佳做​​法。

Controller part: 控制器部分:

@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 part: 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 part so far: 到目前为止,jQuery部分:

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

    });
});

Could you tell how should my jquery part look like to pass wordId variable to controller? 您能否告诉我,我的jquery部分应如何将wordId变量传递给控制器​​? I can get url from href attribute of a tag but i would like to have relative url. 我可以从标签的href属性获取url,但我想拥有相对的url。 I'm stucked... 我被困住了...

UPDATE: 更新:

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

Since the wordId is part of the URL, you should be using the @PathVariable annotation instead of @RequestParam. 由于wordId是URL的一部分,因此您应该使用@PathVariable批注而不是@RequestParam。

Also, since you asked about best practices, I should point out that it's not a good practice to use the HTTP GET method for actions that aren't idempotent. 另外,由于您询问了最佳实践,因此我应该指出,对不等幂的操作使用HTTP GET方法不是一个好习惯。 In other words, you shouldn't use GET for actions that make a change to data on the server-side, such as deleting records from the database. 换句话说,您不应将GET用于对服务器端数据进行更改的操作,例如从数据库中删除记录。

The proper HTTP method for performing a record deletion is the HTTP DELETE method. 执行记录删除的正确 HTTP方法是HTTP DELETE方法。 Some older browsers don't support DELETE, so you'll find a lot of code out there that does a POST for deletion instead. 一些较旧的浏览器不支持DELETE,因此您会发现很多代码可以执行POST删除操作。 I don't think that's much of a problem anymore though. 我认为这不再是一个大问题。 See http://annevankesteren.nl/2007/10/http-method-support for more detail. 有关更多详细信息,请参见http://annevankesteren.nl/2007/10/http-method-support

Using DELETE instead of GET isn't just a good idea for the sake of "doing things the right way"... it can actually help you avoid some nasty problems. 为了“以正确的方式做事”,使用DELETE而不是GET并不是一个好主意……它实际上可以帮助您避免一些麻烦的问题。 There are browser plugins that will speed-up people's experience on the web by pre-fetching all links on a page and storing them in their local cache. 有一些浏览器插件可以通过预取页面上的所有链接并将它们存储在本地缓存中来提高人们在Web上的体验。 If a user has one of these plugins installed the plugin will "click" on every delete link on your page! 如果用户安装了以下插件之一,则该插件将“点击”页面上的每个删除链接! Also, if you're building a public-facing application, search engine crawlers will also follow your delete links. 另外,如果您要构建面向公众的应用程序,则搜索引擎爬网程序还将跟踪您的删除链接。 I've seen this happen in the real world, so trust me it's a real concern! 我已经看到这种情况在现实世界中发生,所以请相信我,这是一个真正的问题!

Another RESTful best practice is to use URLs that follow the pattern of /noun/{id}, with the HTTP method serving as the verb. 另一个RESTful最佳实践是使用遵循/ noun / {id}模式的URL,以HTTP方法作为动词。 So, instead of /delete/{wordId} with a GET, it would be better to go with /word/{wordId} with a DELETE. 因此,最好将/ word / {wordId}与DELETE一起使用,而不是使用GET的/ delete / {wordId}。

With all of my suggested changes your code would look like this: 经过我建议的所有更改,您的代码将如下所示:

Controller 控制者

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

Unfortunately, the jQuery and JSP become a little trickier when you use DELETE instead of GET. 不幸的是,当您使用DELETE而不是GET时,jQuery和JSP变得有些棘手。 GET is really tempting because you can just build a link, as you did like this: GET确实很诱人,因为您可以像这样完成一个链接:

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

To get the browser to use DELETE instead, you either need to have a form whose method is DELETE, or you need to invoke some JavaScript that does an Ajax DELETE. 要使浏览器改为使用DELETE,您要么需要拥有一个其方法为DELETE的表单,要么需要调用一些执行Ajax DELETE的JavaScript。 (Since you're already using Ajax, that's the technique I'll go with.) I'd start by changing your link to a button: (由于您已经在使用Ajax,这就是我要使用的技术。)首先,将您的链接更改为按钮:

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

This creates a button that stores the id of the word you want to delete in the id of the button itself. 这将创建一个按钮,该按钮将要删除的单词的ID存储在按钮本身的ID中。 Somehow you need to associate the id of a word to delete with every button, and this is one way to do it. 您需要以某种方式将要删除的单词的ID与每个按钮相关联,这是一种实现方法。 I've seen other people put the id in a hidden span next to the button. 我看到其他人将id放在按钮旁边的隐藏范围内。 (To be honest, I've never loved either of these techniques, and I'm hoping somebody follows up my answer with a better way to do it.) (说实话,我从未爱过这两种技术,我希望有人能用一种更好的方法来跟踪我的答案。)

Anyway, with that change in the body of your JSP you'll also want to add some jQuery that handles the click of all delete buttons. 无论如何,随着JSP主体中的更改,您还需要添加一些jQuery,以处理所有删除按钮的单击。 (Notice I put a class on the button called "delete-button" so that it would be easy to reference in jQuery.) (请注意,我在按钮上放置了一个名为“ delete-button”的类,以便在jQuery中易于引用。)

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

Notice how I extracted the word id from the id attribute of the button that was clicked: 请注意,我是如何从单击按钮的id属性中提取单词id的:

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

Of course you could also do it this way: 当然,您也可以这样进行:

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

I prefer the first way of doing it because it self-documents what the substring is doing. 我更喜欢第一种方法,因为它可以自动记录子字符串的工作。 In the second example the number 7 is a magic number that doesn't explain what's happening. 在第二个示例中,数字7是一个不可解释的魔术数字。

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

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