0

我正在研究可从 STS 仪表板下载的 Spring MVC showwcase。

现在我正在研究 Spring MVC 如何映射资源,但我在理解以下内容时遇到了一些问题:

所以,我有以下链接,它会生成一个指向“/mapping/produces”文件夹的 HTTP 请求:

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

如您所见,此链接具有名为“writeJsonLink”的类,并且对于该类,定义了单击链接时触发的以下 JQuery 函数:

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

    var link = $(this); // Variable that referer the clicked link in the DOM

    // Execute AJAX call
    $.ajax({ 
        url: this.href,     // Address to which the request is addressed        
        beforeSend: function(req) {     // Before send the Http Request call a function passing it the referer to the HTTP Request
            if (!this.url.match(/\.json$/)) {                               // If the url of the clicked link end with .json
                req.setRequestHeader("Accept", "application/json");         // Add to the HTTP Request theheader Accept: application/json 
            }
        },
        success: function(json) {
            MvcUtil.showSuccessResponse(JSON.stringify(json), link);
        },
        error: function(xhr) {
            MvcUtil.showErrorResponse(xhr.responseText, link);
        }});
    return false;
});

好的,我已经评论了代码以尝试理解它的行为(我是 Javascript 和 JQuery 的初学者),并且似乎我认为这个脚本的行为如下:当我点击链接时,启动发送之前的函数对 Web 应用程序的 ajax 调用检查单击链接的 url 是否是以 .json 扩展名结尾的地址。

在这种情况下,我的 URL 不以 .json 结尾(因为我的 url 指向文件夹:/mapping/produces 而不是指向 .json 文件),因此该函数不添加标题“Accept”,“ application/json" 到 HTTP 请求正文字段。

好的,现在我的问题是了解这段代码的作用:

        success: function(json) {
            MvcUtil.showSuccessResponse(JSON.stringify(json), link);
        },

在成功的情况下,调用具有名为 json 的参数的函数,该函数只需调用名为 showSuccessResponse 的方法,将 json obkect 转换为 String 和链接。

现在,我知道 showSuccessResponse 做了什么(我用它来创建一个 span 标签,在我的页面中单击的链接旁边显示一条消息)。

问题是:我在成功案例中传递给函数的json参数是谁。我正在将此参数转换为字符串,但是:我何时何地创建了 id?

如果我在单击链接时执行我的示例(在链接旁边)出现以下消息:{“foo”:“bar”,“fruit”:“apple”}

似乎它被创建了一个具有以下键\值内容的 JSON 对象:

富:酒吧

水果:苹果

但是它是在哪里创建的?!?!嘘

当我单击链接并执行该方法时,我的堆栈跟踪中有以下消息:

01:27:38 [tomcat-http--28] DispatcherServlet - DispatcherServlet with name 'appServlet' processing GET request for [/spring-mvc-showcase/mapping/produces]
01:27:38 [tomcat-http--28] RequestMappingHandlerMapping - Looking up handler method for path /mapping/produces
01:27:38 [tomcat-http--28] RequestMappingHandlerMapping - Returning handler method [public org.springframework.samples.mvc.mapping.JavaBean org.springframework.samples.mvc.mapping.MappingController.byProducesJson()]
01:27:38 [tomcat-http--28] DispatcherServlet - Last-Modified value for [/spring-mvc-showcase/mapping/produces] is: -1
01:27:38 [tomcat-http--28] RequestResponseBodyMethodProcessor - Written [JavaBean {foo=[bar], fruit=[apple]}] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@360eb2b8]
01:27:38 [tomcat-http--28] DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'appServlet': assuming HandlerAdapter completed request handling
01:27:38 [tomcat-http--28] DispatcherServlet - Successfully completed request

你能帮我理解发生了什么吗?

4

1 回答 1

1

也看一下服务器端代码。您会注意到/mapping/produces URL 映射到 MappingController 中的处理程序方法:

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

这里有两件重要的事情:

  • 通过在返回类型上放置@ResponseBody注解,Spring 会将返回的 JavaBean 实例直接序列化为 HTTP 响应
  • produce=MediaType.APPLICATION_JSON_VALUE会告诉 Spring 在序列化返回的对象时应该使用 JSON 格式

如您所见,此控制器方法仅返回JavaBean 类的新实例,该实例具有以下默认属性:

public class JavaBean {
...
    private String foo = "bar";
    private String fruit = "apple";
...
}

结果,您将在响应中获得提到的{"foo":"bar","fruit":"apple"} JSON。

您还可以从日志中找出调用 URL 时哪个控制器方法正在处理您的请求:

01:27:38 [tomcat-http--28] RequestMappingHandlerMapping - Looking up handler method for path /mapping/produces
01:27:38 [tomcat-http--28] RequestMappingHandlerMapping - Returning handler method [public org.springframework.samples.mvc.mapping.JavaBean org.springframework.samples.mvc.mapping.MappingController.byProducesJson()]
于 2012-11-28T11:11:27.767 回答