Spring-boot return json and xml from controllers

前端 未结 8 1489
Happy的楠姐
Happy的楠姐 2020-12-16 12:05

I have a spring-boot 1.1.7 application that uses Thymeleaf for much of the UI, so the response from my controllers hasn\'t really been a concern. However, now I need to pro

相关标签:
8条回答
  • 2020-12-16 12:30

    It is very simple Just add jackson-dataformat-xml dependency in your pom.xml file after that your project is able to handle xml/json request or response . add

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

    dependency and add headers content-type or accept as per your need spring boot will handle request or response in json/xml. For full article visit : How to handle xml/json in spring boot

    0 讨论(0)
  • 2020-12-16 12:32

    In my case I wanted to return a formatted xml string and it was all combined into one line.

    Adding produces = { "application/xml", "text/xml" } to the request mapping was enough to return the string as formatted XML (with indentation).

    example:

    @RequestMapping(method= RequestMethod.GET, value="/generate/{blabla}", produces = { "application/xml", "text/xml" })
    public String getBlaBla(@PathVariable("param") String param) throws IOException {
    

    }

    Goodluck.

    0 讨论(0)
  • 2020-12-16 12:38

    In addition to what Michael told in his answer, I added the following dependencies as well to pom.xml

    <dependency>
        <groupId>org.codehaus.woodstox</groupId>
        <artifactId>woodstox-core-asl</artifactId>
        <version>4.4.1</version>
    </dependency>
    

    For some reason, the jackson-dataformat-xml alone was not helping. I also made sure that ResponseEntity is returned in the get call and removed the produces=MediaType from the RequestMapping annotation.

    With these changes, I was able to get the correct data but I had to give the extension of mime type to the REST URL during get call. ie, specify explicitly like: http://localhost:8080/hello.xml or http://localhost:8080/hello.json in browser

    0 讨论(0)
  • 2020-12-16 12:41

    I had the exact same problem and I found the solution on Spring documentation website : here

    In synthesis, I added the following dependency to the pom.xml of my project :

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

    Then I added the following code block to the class that the service had to return :

     import javax.xml.bind.annotation.XmlRootElement;
    
     @XmlRootElement
     public class Greeting {...}
    

    And it worked.

    0 讨论(0)
  • 2020-12-16 12:44

    SOLUTION: I used a combination of both answers below (thank you very much!). I am posting here in case anyone else needs help.

    My modified controller:

    @Controller
    public class RemoteSearchController {
    
        @Autowired
        private SdnSearchService sdnSearchService;
    
        @RequestMapping(value = "/remote/search", method = RequestMethod.GET, produces = { "application/xml", "text/xml" }, consumes = MediaType.ALL_VALUE )
        @ResponseBody
        public SdnSearchResults search(@ModelAttribute SdnSearch sdnSearch) {
            List<Sdn> foundSdns = sdnSearchService.find( sdnSearch );
            SdnSearchResults results = new SdnSearchResults();
            results.setSdns( foundSdns );
            return results;
        }
    }
    

    And on my client, I set the request headers:

    Content-type: application/text Accept: text/xml I think ultimately the problem was that my client headers were not being set correctly, so I may not have had to make some of these changes. But I liked the idea of a SearchResults class containing a list of results:

    @XmlRootElement
    public class SdnSearchResults {
        private List<Sdn> sdns;
    ...
    }
    
    0 讨论(0)
  • 2020-12-16 12:51

    It may be better to create a new class:

    public class SdnSearchResult {
      private List<Sdn> sdns;
      ...
    }
    

    Then, a slight change will be required to the existing classes as follows:

    public interface SdnSearchService {
      SdnSearchResult find(SdnSearch sdnSearch);
    }
    
    @Controller
    public class UISearchController {
      @Autowired
      private SdnSearchService sdnSearchService;
    
      @RequestMapping("/search")
      public ModelAndView search(@ModelAttribute SdnSearch sdnSearch) {
        return new ModelAndView("pages/search/results", "sdns", sdnSearchService.find(sdnSearch).getSdns());
      }
    }
    

    Once this is done, the other controller must be coded as:

    @Controller
    public class RemoteSearchController {
      @Autowired
      private SdnSearchService sdnSearchService;
    
      @RequestMapping("/remote/search")
      @ResponseBody
      public SdnSearchResult search(@RequestBody SdnSearch sdnSearch) {
        return sdnSearchService.find(sdnSearch);
      }
    }
    

    A quick explanation of the changes from your code:

    1. @RequestBody will automatically deserialize the entire HTTP request body to an SdnSearch instance. External applications will typically submit the request data as HTTP body, so @RequestBody will ensure that the deserialization to Java object happens automatically.
    2. @ResponseBody will automatically serialize the return value according to the external client's capabilities and the libraries available on the classpath. If Jackson is available on the classpath and the client has indicated that they can accept JSON, the return value will be automatically sent as JSON. If the JRE is 1.7 or higher (which means that JAXB is included with the JRE) and the client has indicated that they can accept XML, the return value will be automatically sent as XML.
    3. List<Sdn> needs to be changed to SdnSearchResult to ensure that the application can exchange JSON, XML, RSS and ATOM formats with a single controller method, since XML (and XML based formats) require a root-tag on the output, which a List<Sdn> cannot be translated to.

    Once these changes are done, fire up a REST client such as the Postman extension for Chrome and submit a request to /remote/search with the following information:

    1. Request header Accepts set to application/json.
    2. Request header Content-Type set to application/json.
    3. Request body set to the JSON string { "sdnName" : "Victoria", "address" : "123 Maple Ave" }.

    This will give you a JSON response.

    0 讨论(0)
提交回复
热议问题