【问题标题】:@ResponseBody @RequestBody- Object what happens exactly [closed]@ResponseBody @RequestBody-对象到底发生了什么[关闭]
【发布时间】:2014-02-04 05:24:20
【问题描述】:

编辑我清理了我相当长的帖子。我将单独发布问题。

请帮助澄清我的疑问。如果需要,我会发布代码。

我使用 spring rest 模板作为带有消息转换器的客户端测试了 Spring Rest 控制器,没有消息转换器,在 classpath 中有 JSON jars,在 classpath 中没有 JSON jars。

每种情况下的行为都不同,这是我之前想澄清的。

我的要求是我需要从客户端发送和获取 XML 作为字符串。将来我们可能需要支持对象。

我用@RequestBody 方法设计了一个简单的控制器,其中一个JAXBObject 作为方法参数,由消息转换器设置,在服务器端将XML 字符串转换为JAXB 对象。

//控制器

   @RequestMapping(method=RequestMethod.POST, value="/updatePricePlan" , consumes="application/xml" , produces = "application/xml")
   public @ResponseBody  ResponseEntity<Employee> updateEmployee( @RequestBody Employee emp ) {
  // code 
  }

我想知道:

  1. 我的方法将来是否支持对象交换。
  2. 可以单独使用 JAXB 对象作为 @RequestBody 的一部分发送
  3. 如果 json jar 位于调用 rest 服务的客户端代码的类路径中,即使我在标头中明确设置了 application/xml,JSON 是否会成为默认格式。
  4. 对象如何作为@ResponseBody 或@RequestBody 的一部分准确发送。
  5. 如果客户端期望对象而不是 XML 作为字符串,则服务器端的消息转换器不会将上述示例中的 JAXB 对象转换为 XML 作为字符串并按原样返回对象
  6. 如果根据我的理解第 5 点为真,对象是否按原样传递给客户端?发送 JAXB 对象而不是 POJO 对象是一种好习惯吗

【问题讨论】:

  • 请具体一点,这个问题太长了,没有人会费心阅读你的整个问题。
  • 我想知道在使用 spring rest 控制器时对象是如何通过 Http 发送的。我尝试了不同的场景。由于论坛需要代码和我们目前的理解。我给出了我尝试过的场景以及我对每个场景的问题。你能澄清我的疑问吗
  • 这是一本小说。我看到那里有 4-5 个问题。可能最好将其分解为单独的问题。
  • 很难看一眼
  • 我只更新了问题。我为我之前的长篇博文道歉,我认为提供所有信息会让其他人更容易帮助我。

标签: java xml json spring rest


【解决方案1】:
  1. 不知道你说的以后交换对象是什么意思。如果你的意思是你想用其他对象替换 Employee ,那么这会很好,但你会得到不同的 XML。除非EmployeeNewEmployee(无论您用什么替换它)具有相同的XML 输出,否则这将是无缝的。
    1. 同样,我不完全确定您在问什么,如果您问的是 JAXB 是否是唯一允许的 XML 库,但事实并非如此。 JAX-RS 支持添加 MessageBodyReaderMessageBodyWriter 提供程序。您可以使用这些来添加备用 XML 读取器和写入器。如果您询问是否可以使用其他格式(例如 JSON 和 Jackson),那么您可以,但最好编写一种不同的方法。
    2. 作为服务器,您不会设置请求的标头,除非您拦截和替换客户端的标头,这会很奇怪。如果客户端发出带有 JSON 内容类型标头的请求,那么他们将收到 HTTP 415 错误,因为您没有任何“使用” JSON 内容类型的方法。
    3. 以下说明
    4. 我不确定你的意思。客户端将获得一个 XML 字符串。除非他们自己编写了这样的类,否则他们将没有Employee 对象的概念。他们还必须负责将 XML 字符串反序列化为他们的 Employee 对象。
    5. 给客户端的是一个 XML 字符串,而不是一个对象。 JAXB 对象和 POJO 对象有什么区别?

当您收到请求时会发生以下情况。

  1. 请求到达服务器。在这一点上,它是一个 HTTP 请求,它是一个长长的标头字符串和 HTTP 信息加上一个只是字节流的主体。我假设正文是一个 XML 字符串。
  2. 请求被传递到 JAX-RS servlet。
  3. JAX-RS servlet 查看其资源列表 (@Path) 以查找与 URL、内容类型标头和接受标头匹配的所有方法。不同的内容类型可能有多个匹配项。
  4. JAX-RS servlet 查看其MessageBodyReadersMessageBodyWriters 列表,查看是否可以找到MessageBodyReader,该MessageBodyReader 可以将具有给定内容类型的消息转换为@RequestBody 的对象类型(它使用accept 方法检查)和MessageBodyWriter,可以将响应对象类转换为具有适当生产类型的消息。
  5. 如果找到匹配项,则使用MessageBodyReaderMessageBodyWriter 执行该方法以序列化/反序列化对象。

例如,假设您只有上面发布的方法。

  • 如果请求的内容类型为 application/json,则 JAX-RS 将找到具有相同 URL 但与消耗注释不匹配的匹配项。 JAX-RS 将返回 415。
  • 如果请求带有 application/xml 的内容类型和 application/json 的接受标头,则 JAX-RS 将找到具有相同 URL 但与产生注释不匹配的匹配项。 JAX-RS 将返回 415。
  • 如果请求带有 application/xml 的内容类型和 application/xml 的接受标头,则 JAX-RS 将找到该方法作为匹配项。然后它将寻找可以接受("application/xml", Employee.class)MessageBodyReader。默认的 JAXB MessageBodyReader 接受 ("application/xml", &lt;any class with @XmlRootElement&gt;),因此它会匹配这个。然后,JAX-RS 将寻找可以接受 ("application/xml", Employee.class)MessageBodyWriter。默认的 JAXB MessageBodyWriter 接受 ("application/xml", &lt;any class with @XmlRootElement&gt;),所以它会匹配这个。
  • 然后,JAX-RS 会将请求正文作为 InputStream 传递给默认的 JAXB MessageBodyReader,这会将请求反序列化为 Employee 对象。
  • JAX-RS 将使用 Employee 对象调用您的方法并获取响应。
  • JAX-RS 然后将响应传递给默认的 JAXB MessageBodyWriter 以及 OutputStream 以表示响应正文。 MessageBodyWriter 会将 Employee 对象序列化为 XML 字符串。
  • 此 XML 字符串将被封装到 Content-Type 为“application/xml”的 HTTP 响应中并发送回客户端。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多