Весна MVC отдых ответ JSON и XML - PullRequest
13 голосов
/ 24 июня 2011

У меня есть требование возвращать результат из базы данных либо в виде строки в 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);
}

для первого метода мне нужно лучшее решение, которое я уже спрашивал здесь: пружина 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 I думаю.

что я могу сделать, чтобы пружина определяла разницу в том, что один метод должен возвращать тип 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

Я надеюсь, что кто-нибудь может мне помочь.

Ответы [ 6 ]

13 голосов
/ 07 марта 2012

Если вы используете Spring 3.1, вы можете воспользоваться новым элементом produces в аннотации @RequestMapping, чтобы обеспечить создание XML или JSON, как вы хотите, даже в пределах одного и того же приложения.

Я написал пост об этом здесь:

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

8 голосов
/ 23 июля 2011

Ого ... когда вы работаете с Spring, предположите, что кто-то еще сталкивался с той же проблемой.Вы можете сбросить все данные JSON на стороне сервера, потому что все, что вам нужно сделать, это:

  1. Включение JAR-файлов Jackson JSON в ваше приложение
  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

4 голосов
/ 11 июня 2012

Вы можете использовать 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();
}
1 голос
/ 13 сентября 2016

Если кто-то использует 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.

0 голосов
/ 09 марта 2015

Самый простой способ получить ответ JSON: Используя Spring 3.1, вы можете сделать следующее:

  1. В вашем файле pom.xml (надеясь, что вы используете проект maven), добавьте зависимость maven для jackson-mapper (http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl/1.9.13)

  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;
    }
    
0 голосов
/ 17 июля 2013

Здесь я написал метод, который принимает XML в качестве параметра запроса из URL-адреса сопоставления вашего запроса

Здесь я публикую 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 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, который я могу использовать в дальнейшем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...