1

在此期间,我正在研究 Spring MVC 展示示例可下载表单 STS 仪表板。

我对某些类型的 rmaping 有一些疑问(显示在展示的请求映射部分)。

在 home.jsp 视图中,我有这两个链接:

<li>
<a id="byProducesAcceptJson" class="writeJsonLink" 
        href="<c:url value="/mapping/produces" />">
        By produces via Accept=application/json</a>
</li>

 <li>
    <a id="byProducesJsonExt" class="writeJsonLink" 
       href="<c:url value="/mapping/produces.json" />">By produces via ".json"</a>
 </li>

第一个链接向 URL 生成 HTTP 请求:“/mapping/produces” 第二个链接向URL 生成 HTTP 请求:“/mapping/produces.json

与writeJsonLink类相关,我有以下简单的 Jquery 回调函数:

$("a.writeJsonLink").click(function() {

    var link = $(this);                     // Variabile che si riferisce all'elemento del DOM che ha scatenato l'evento click (il link clickato) 

    // Esegue la chiamata ajax 
    $.ajax({ 
        url: this.href,                     // Indirizzo verso cui è indirizzata la richiesta           
        beforeSend: function(req) {         // Prima di inviare l'HTTP Request esegui la funzione passandogli il parametro req 
            if (!this.url.match(/\.json$/)) {                               // Se l'url termina con .json 
                req.setRequestHeader("Accept", "application/json");         // Aggiunge alla HTTP Request l'header Accept: application/json 
            }
        },
        success: function(json) {
            MvcUtil.showSuccessResponse(JSON.stringify(json), link);
        },
        error: function(xhr) {
            MvcUtil.showErrorResponse(xhr.responseText, link);
        }});
    return false;
});

这个函数的作用对我来说很清楚:只需执行一个 AJAX 调用,然后在发送调用之前检查 URL 是否以 .json 结尾

好的,在我的控制器类中,我有以下方法可以处理以前的两个 HTTP 请求:

@RequestMapping(value="/mapping/produces", method=RequestMethod.GET,
 produces=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody JavaBean byProducesJson() {
    System.out.println("Dentro byProducesJson()");
    return new JavaBean();
}

这种方法的行为对我来说很清楚:

此方法处理对 URL“/mapping/produces”的 HTTP GET 请求,并且 * produces元素指定该方法将不接受名为 Accept 与指定 MediaType 不兼容的标头的请求,并且该方法生成一个具有 JSON 格式的新对象放在 HTTP 响应的正文字段中*

新的 JavaBean 对象仅包含两个初始化变量和 getter\setter 方法:

public class JavaBean {

private String foo = "bar";
private String fruit = "apple";

    // Getter & Setter Method

好的...所以使用这个变量值创建了一个新的 JavaBean 对象,并且这个值存储在一个 JSON 对象中,该对象被放置在对浏览器的 HTTP 响应中。

单击两个链接,在浏览器中出现相同的输出,这个:{“foo”:“bar”,“fruit”:“apple”}

现在我对此有些怀疑:

  1. 第一个链接生成一个 HTTP 请求:/mapping/produces

    第二个链接生成一个 HTTP 请求:/mapping/produces.json

    我的方法处理对具有以下形式的 URL 的 HTTP 请求:“/mapping/produces”,为什么此方法还处理以 .json 结尾的第二种类型的 HTTP 请求?

  2. 第一个 HTTP 请求不以 .json 扩展名结尾,因此,执行之前的 Jquery 代码时,我没有在if 正文中输入,因此未设置以下标头:( "Accept", "application/json")对于我的 HTTP 请求。

    好的,我的方法的@RequestMapping 注释包含 produce=MediaType.APPLICATION_JSON_VALUE元素。据我了解阅读文档,此方法只有在其标头中有一个包含“Accept”,“application/json”作为值的 Accept 标头时才必须处理 HTTP 请求。

    这个 HTTP 请求不包含这个头,为什么它是由我的方法处理的?

  3. 与 2 种 HTTP 请求有什么区别?以同样的方式处理?为什么?

非常感谢

安德烈亚

4

1 回答 1

1

我认为您正在看到Spring的内容协商效果。HTTP 本身仅提供一种方法来指示响应所需的内容类型:Accept标头。Spring 通过内容协商 bean 提供了两种附加方式。它可以将 URI 后缀(.json在这种情况下)解释为对特定内容类型的请求。bean 在传递控制器类之前去掉后缀。

于 2013-06-16T22:58:53.493 回答