spring mvc rest response json和xml

时间:2011-06-24 11:29:28

标签: xml json spring rest mongodb

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

@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>

当我将第一个方法的内容类型更改为“application / json”时,它可以工作,但是xml响应不再起作用,因为json转换器想要将xml字符串转换为json-structure I认为

我该怎么做,那个spring识别出一个方法应该返回一个json类型而另一个方法是一个普通的xml作为字符串的区别? 我用accept标志尝试了它:

@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

我希望有人可以帮助我。

7 个答案:

答案 0 :(得分:13)

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

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

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

答案 1 :(得分:8)

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

  1. 在您的应用中包含Jackson JSON JAR
  2. RequestMapping返回类型设置为@ResponseBody(yourObjectType)
  3. Spring会自动将您的对象转换为JSON。真。就像魔法一样。

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

答案 2 :(得分:4)

您可以使用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();
}

答案 3 :(得分:1)

如果有人使用Spring Boot for 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格式生成响应。

答案 4 :(得分:0)

这里我编写了一个方法,它将XML作为请求映射URL的请求参数

这里我将XML发布到我的网址“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 poster测试了它,你可以在内容体中发送任何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中,我可以进一步使用

答案 5 :(得分:0)

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

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

  2. 按如下方式修改代码并在postman上测试端点:

    @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;
    }
    

答案 6 :(得分:0)

经过大量研究,我认为我对此有一个好的解决方案:非常简单,默认情况下,spring使用Jackson与Json一起工作,该库位于 spring-boot-starter-web < / strong> ,但是默认情况下,杰克逊(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);
}

如果人是一个bean(只有@Component标记),则锁定两个代码相等,只有MediaType不同才可以使用!! 也不是必需的,添加“产生” ”和“消耗” 归因于Mapping标记,因为默认情况下,Spring可以同时使用Json和Xml,因此我举了一个发送Json并获取的示例。 xml,然后发送xml来获取Json, ,只需要在执行请求时在邮递员或curl中指定要发送的正确的标头,即可发送application / json或application / xml

注意:这只是一种实现方式,JAXB和XmlRootElement是另一种实现方式。