【问题标题】:spring mvc rest response json and xmlspring mvc 休息响应 json 和 xml
【发布时间】:2011-09-21 23:11:55
【问题描述】:

我需要将数据库中的结果作为 xml 结构中的字符串或 json 结构返回。 我有一个解决方案,但我不知道这是否是解决此问题的最佳方法。 我这里有两种方法:

@RequestMapping(value = "/content/json/{ids}", method = RequestMethod.GET)
public ResponseEntity<String> getContentByIdsAsJSON(@PathVariable("ids") String ids)
{
  String content = null;
  StringBuilder builder = new StringBuilder();
  HttpHeaders responseHeaders = new HttpHeaders();
  responseHeaders.add("Content-Type", "text/html; charset=utf-8");
  // responseHeaders.add("Content-Type", "application/json; charset=utf-8");

  List<String> list = this.contentService.findContentByListingIdAsJSON(ids);
  if (list.isEmpty())
  {
     content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><error>no data  found</error>";
     return new ResponseEntity<String>(content, responseHeaders, HttpStatus.CREATED);
  }
  for (String json : list)
  {
     builder.append(json + "\n");
  }
  content = builder.toString();
  return new ResponseEntity<String>(content, responseHeaders, HttpStatus.CREATED);
}

@RequestMapping(value = "/content/{ids}", method = RequestMethod.GET)
public ResponseEntity<String> getContentByIdsAsXML(@PathVariable("ids") String ids)
{
  HttpHeaders responseHeaders = new HttpHeaders();
  responseHeaders.add("Content-Type", "application/xml; charset=utf-8");

  String content = this.contentService.findContentByListingIdAsXML(ids);
  if (content == null)
  {
     content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><error>no data found</error>";
     return new ResponseEntity<String>(content, responseHeaders, HttpStatus.CREATED);
  }
  return new ResponseEntity<String>(content, responseHeaders, HttpStatus.CREATED);
}

对于第一种方法,我需要一个更好的解决方案,我已经在这里问过: spring mvc rest mongo dbobject response

接下来,我在配置中插入了一个 json 转换器:

<bean id="jsonHttpMessageConverter"
    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
   <property name="supportedMediaTypes" value="application/json"/>
</bean>

当我将第一种方法的内容类型更改为“应用程序/json”时,它可以工作,但是 xml 响应不再工作,因为 json 转换器想要将 xml 字符串转换为 json 结构我想想。

我能做什么,spring 识别出一种方法应该返回 json 类型而另一种方法应该返回普通 xml 作为字符串的区别? 我用接受标志试了一下:

@RequestMapping(value = "/content/json/{ids}", method = RequestMethod.GET, headers = "Accept=application/json")

但这不起作用。我收到以下错误:

org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.StackOverflowError

希望有人能帮帮我。

【问题讨论】:

    标签: xml json spring rest mongodb


    【解决方案1】:

    经过大量研究,我认为我有一个很好的解决方案:非常简单,默认为 spring,使用 Jackson 来处理 Json,该库位于 spring-boot-starter-web,但 Jackson 的 Xml 扩展默认情况下不会出现,您需要做的就是在 build.gradle 或 pom.xml 中导入 jackson-dataformat- xml 依赖,现在您可以在 json 或 xml 之间切换,例如使用如下代码:

    @PostMapping(value = "/personjson")
    public ResponseEntity<?> getJsonPerson (@RequestBody Person person) {
        return ResponseEntity.accepted().contentType(MediaType.APPLICATION_JSON)
        .body(person);
    }
    
    @PostMapping(value = "/personxml")
    public ResponseEntity<?> getXmlPerson (@RequestBody Person person) {
        return ResponseEntity.accepted().contentType(MediaType.APPLICATION_XML)
        .body(person);
    }
    

    如果 person 是一个 bean(只有 @Component 标签),锁定两个代码是相等的,只有 MediaType 不同并且它有效!!,也不需要添加“produces " 和 "consumes" 归因于 Mapping 标签,因为默认情况下 Spring 可以同时使用 Json 和 Xml,我做了一个发送 Json 并获取的示例。 xml,并发送 xml 获取 Json,只有您在执行请求时需要在邮递员或 curl 中指定,您要发送 application/json 或 application/xml 的正文的正确标头.

    注意:这只是一种方式,JAXB 和 XmlRootElement 是其他方式。

    【讨论】:

      【解决方案2】:

      如果有人使用 Spring Boot 进行 XML 响应,则添加以下依赖项,

      <dependency>
          <groupId>com.fasterxml.jackson.dataformat</groupId>
          <artifactId>jackson-dataformat-xml</artifactId>
      </dependency>
      

      在您返回的模型类中添加@XmlRootElement

      @Entity
      @Table(name = "customer")
      @XmlRootElement
      public class Customer {
            //... fields and getters, setters
      }
      

      并在您的控制器中添加produces="application/xml"。这将产生 xml 格式的响应。

      【讨论】:

        【解决方案3】:

        获取 JSON 响应的最简单方法是: 使用 Spring 3.1,您可以执行以下操作

        1. 在您的 pom.xml 文件中(希望您使用的是 maven 项目),为 jackson-mapper (http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl/1.9.13) 添加 maven 依赖项

        2. 如下修改你的代码并在邮递员上测试端点:

          @RequestMapping(value = "/content/json/{ids}", method = RequestMethod.GET)
          public @ResponseBody String getContentByIdsAsJSON(@PathVariable("ids") String ids){
              String content = "";
              StringBuilder builder = new StringBuilder();
          
              List<String> list = this.contentService.findContentByListingIdAsJSON(ids);
              if (list.isEmpty()){
                  content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><error>no data found</error>";
                  return content;
              }
              for (String json : list){
                  builder.append(json + "\n");
              }
          
              content = builder.toString();
              return content;
          }
          

        【讨论】:

          【解决方案4】:

          这里我写了从你的请求映射 URL 中将 XML 作为请求参数的方法

          在这里,我将 XML 发布到我的 URL“baseurl/user/createuser/”

              public class UserController {
              @RequestMapping(value = "createuser/" ,
              method=RequestMethod.POST,  consumes= "application/xml")
              @ResponseBody
              ResponseEntity<String> createUser(@RequestBody String requestBody ) {
          
                  String r = "<ID>10</ID>"; // Put whatever response u want to return to requester
          
              return new ResponseEntity<String>(
                        "Handled application/xml request. Request body was: " 
                        + r, 
                        new HttpHeaders(), 
                        HttpStatus.OK);       
          
          
              }
          }
          

          我使用 chrome 海报对其进行了测试,您可以在其中发送任何内容正文中的 xml,例如:

          "<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <userEntity><id>3</id><firstName>saurabh</firstName><lastName>shri</lastName><password>pass</password><userName>test@test.com</userName></userEntity>"
          

          此 XML 将通过我的 createUser 方法捕获并存储在我可以进一步使用的 String requestBody 中

          【讨论】:

          • 当我有 xmlns 时,有没有办法删除 standalone="yes"
          【解决方案5】:

          您可以使用 ContentNegotiatingViewResolver 如下:

          <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
              <property name="defaultContentType" value="application/json" />
              <property name="ignoreAcceptHeader" value="true" />
              <property name="favorPathExtension" value="true" />
              <property name="order" value="1" />
              <property name="mediaTypes">
                  <map>
                      <entry key="xml" value="application/xml" />
                      <entry key="json" value="application/json" />
                  </map>
              </property>
              <property name="defaultViews">
                  <list>
                      <ref bean="xmlView"/>
                      <ref bean="jsonView"/>
                  </list>
              </property>
          </bean>
          
          <bean id="jsonView"
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
              <property name="contentType" value="application/json;charset=UTF-8"/>
              <property name="disableCaching" value="false"/>
          </bean>
          
          <bean id="xmlView"
                class="org.springframework.web.servlet.view.xml.MarshallingView">
              <property name="contentType" value="application/xml;charset=UTF-8"/>
              <constructor-arg>
                  <ref bean="xstreamMarshaller"/>
              </constructor-arg>
          </bean>
          
          
          <bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
              <property name="autodetectAnnotations" value="true" />
              <property name="annotatedClass" value="demo.domain.xml.XMLResponse"/>
              <property name="supportedClasses" value="demo.domain.xml.XMLResponse"/>
          </bean>
          

          在你的控制器中:

          @RequestMapping(value = "/get/response.json", method = RequestMethod.GET)
          public JSONResponse getJsonResponse(){
              return responseService.getJsonResponse();
          }
          @RequestMapping(value = "/get/response.xml", method = RequestMethod.GET)
          public  XMLResponse getXmlResponse(){
              return responseService.getXmlResponse();
          }
          

          【讨论】:

            【解决方案6】:

            如果您使用的是 Spring 3.1,则可以利用 @RequestMapping 注释上的新 produces 元素来确保即使在同一个应用程序中也可以根据需要生成 XML 或 JSON。

            我在这里写了一篇关于这个的帖子:

            http://springinpractice.com/2012/02/22/supporting-xml-and-json-web-service-endpoints-in-spring-3-1-using-responsebody/

            【讨论】:

            • 这是一个很好的答案,它考虑到有效地提供 xml 和 json。它不像 Jersey 的 Jaxson 实现那么简单,但我会接受它。
            【解决方案7】:

            哇...当您使用 Spring 时,假设其他人遇到了同样的问题。您可以转储所有的服务器端 JSON 生成,因为您需要做的就是:

            1. 在您的应用中包含 Jackson JSON JAR
            2. RequestMapping返回类型设置为@ResponseBody(yourObjectType)

            Spring 会自动将您的对象转换为 JSON。真的。像魔术一样工作。

            @ResponseBody 的文档:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-responsebody

            【讨论】:

            • 如果您将方法的返回类型设置为@ResponseBody MyObject 并且在您的类路径中有Jackson JAR,Spring 会进行转换。您使用的是 Spring 3 吗?
            • 感谢有关 ResponseBody 的信息...不过,我必须添加一些内容:@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET,produces="application/ json") @ResponseBody public Pet getPet(@PathVariable String petId, Model model) { // 省略实现 }
            猜你喜欢
            • 2016-11-13
            • 1970-01-01
            • 2016-05-18
            • 2011-05-11
            • 1970-01-01
            • 1970-01-01
            • 2017-05-03
            • 1970-01-01
            • 2019-05-18
            相关资源
            最近更新 更多