Подтвердить что ты не робот

Spring ответ mvc rest json и xml

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

Следующее, что я вставлял в конфигурацию json converter:

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

когда я изменяю тип содержимого в первом методе на "application/json", он работает, но тогда ответ xml больше не работает, потому что json-конвертер хочет преобразовать строку xml в json-структуру я думаю.

что я могу сделать, что 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

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

4b9b3361

Ответ 1

Если вы используете 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/

Ответ 2

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

  • Включите JSON Jackson JSON в ваше приложение.
  • Установите возвращаемый тип RequestMapping в @ResponseBody(yourObjectType)

Spring автоматически преобразует ваш объект в JSON. В самом деле. Работает как магия.

Doc для @ResponseBody: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-responsebody

Ответ 3

Вы можете использовать ContentNegotiationViewResolver, как показано ниже:

<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();
}

Ответ 4

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

Ответ 5

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


    }
}

Я протестировал его, используя хром-плакат, где вы можете отправить любой xml в теле контента, например:

"<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <userEntity><id>3</id><firstName>saurabh</firstName><lastName>shri</lastName><password>pass</password><userName>[email protected]</userName></userEntity>"

Этот XML будет захвачен моим методом createUser и сохранен в String requestBody, который я могу использовать далее

Ответ 6

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

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

  • Измените свой код следующим образом и проверьте конечную точку на почтальоне:

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