0

在此期间,我正在研究 Spring MVC 展示示例。

关于请求映射我有点怀疑,我有以下情况:

在我提交表单的视图中,提交此表单启动以下 Jquery 函数:

$("form.readJsonForm").submit(function() {          

    var form = $(this);                 // Variabile che si riferisce all'elemento nel DOM che ha scatenato l'evento submit (il form) 
    var button = form.children(":first");       // Seleziona il bottone submit 

    var data = form.hasClass("invalid") ?       // OPERATORE CONDIZIONALE: il form ha classe "invalid" ? 
            "{ \"foo\": \"bar\" }" :            // SI: foo = bar 
            "{ \"foo\": \"bar\", \"fruit\": \"apple\" }";   // NO: foo= bar ; fruit = apple 


    /* AJAX CALL PARAMETER:
       type: Say to the servlet tath the request is a POST HTTP Request
       url: The address to which to send the call   
       data: the content of my data variable
       contentType: an object having JSON format
       dataType: the type of content returned by the server
    */
    $.ajax({ type: "POST", url: form.attr("action"), data: data, contentType: "application/json", dataType: "text", 
        success: function(text) { MvcUtil.showSuccessResponse(text, button); }, 
        error: function(xhr) { MvcUtil.showErrorResponse(xhr.responseText, button); }});

    return false;
});

所以在我的例子中,生成了以下具有 JSON 格式的 JavaScript 对象:

{ \"foo\": \"bar\", \"fruit\": \"apple\" }

好的,然后我的 Jquery 函数执行 AJAX 调用并将我的 JSON 对象发送到 Spring 控制器类。

这是处理这个 HTTP 请求的方法:

@RequestMapping(value="/mapping/consumes", method=RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody String byConsumes(@RequestBody JavaBean javaBean) {
    System.out.println("foo: " + javaBean.getFoo() + " fruit: " + javaBean.getFruit());
    return "Mapped by path + method + consumable media type (javaBean '" + javaBean + "')";
}

此方法处理对 URL 的 HTTP POST 请求:“/mapping/consumes”并使用 JSON 对象(这由consumes=MediaType.APPLICATION_JSON_VALUE指定)

好的,此方法采用使用 @RequestBody 注释进行注释的输入参数,该注释指示我的方法参数应绑定到 HTTP 请求正文中的值(我的 JSON 对象)

JavaBean 类仅包含 2 个属性:

private String foo;
    private String fruit;

(作为 JSON 对象属性)

为了将 JSON 对象属性与 JavaBean 属性绑定,JavaBean 类由@XmlRootElement注释进行注释:

包 org.springframework.samples.mvc.mapping;

导入 javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class JavaBean {

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

    // Setter and Getter method for properties

现在我知道,当您在 Spring 控制器中的对象上看到 @RequestBody 注释时,@RequestMapping 注释的消耗属性是“application/xml”(或 pre spring 3.1,Content-Type 标头设置为“application/ xml") 这将告诉 Spring 请求消息的有效负载是 XML 并且需要解组到使用 @RequestBody 注释的对象。在这种情况下,使用 @RequestBody 注释的对象通常会使用 JAXb 注释对其自身进行注释,以提供将该对象编组到 XML 或从 XML 解组所需的元数据,而 @XmlRootElement 是提供该元数据的那些注释之一。

好的,这对我来说很清楚......我唯一的疑问与以下事实有关

所以我有以下问题要问你:

1) Content-Type headerconsumes=MediaType.APPLICATION_JSON_VALUE有什么区别

2)据我了解阅读** @XmlRootElement** 文档:http ://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/XmlRootElement.html

此注释提供 XML 内容和内容 JAVA 之间的双向关联。所以我可以在 Java 类属性中映射 XML 字段的内容,反之亦然

问题是在这种情况下我没有 XML“对象”,但我使用的是 JSON 对象,它是 XML 的替代品!!!我错过了什么?

非常感谢你

安德烈亚

4

1 回答 1

1

首先回答你的问题:

Content-Type 标头和 consumes=MediaType.APPLICATION_JSON_VALUE 有什么区别?

它们都定义了内容类型,但它们用于不同的目的。

  • Content-Type 标头是 HTML 规范的一部分;它是作为 HTML 消息头的一部分传输的属性,它告诉接收者正在传输的数据有效负载的格式。
  • Spring 控制器上使用的“consumes”注释提供了一种机制来限制控制器接受的内容类型。通过将你的控制器设置为consumes=MediaType.APPLICATION_JSON_VALUE你告诉你的控制器只接受来自调用者的消息,这些消息指定他们正在向它发送 JSON 格式的有效负载。这意味着您需要确保您的客户端代码指定了“应用程序/json”的内容类型,但根据您的示例代码,它似乎已正确设置。(请注意,使用注释匹配方法的内容类型而不是“限制”它们,但出于您的问题的目的,我正在简化事情。有关更多信息,请参阅链接。

关于第二个问题/问题:

您的代码表明您使用 Spring 3.0+ 将您的 JSON 消息编组到关联的 Java 对象中是正确的,但您可能需要确保您的 Spring 配置设置正确。确保你<mvc:annotation-driven/>的 spring 配置中有这个集合,它将包括 Spring MVC 中 JSON 和/或 XML 编组/解组所需的 Jackson 支持(即它确保 Jackson 在你的类路径上)。有关详细信息,请参阅

此外,我会删除@XmlRootElement标签,因为它用于 XML 编组/解组,并且在使用 JSON 进行通信时不需要。(它应该被忽略,但如果真的不需要它,我会放弃它)。

最后,我不确定您是否在问题或实际代码中使用类名“JavaBean”来进行说明,但如果您在代码中使用它,我建议您更改名称。术语“JavaBean”已在 Java 中的多个地方使用,并且具有相同名称的类可能会令人困惑。

于 2012-12-10T14:25:25.463 回答