2

I am trying to produce XML and JSON response from the same method in my controller. I googled and found that JSON is the default for spring, as the jackson is on classpath. But for XML, I had to add the JAXB dependency and then annotate my model with JAXB annotation. Also, I had to change the produces attribute of the @RequestMapping annotation.

Now, my default behavior has changed, it returns an XML response. I thought after adding the content-Type header to my request with the value application/json, my response will be JSON, but sadly this is not the case. Below is my code:-

package com.example.controller;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.domain.Person;

@RestController("person")
public class PersonController {

    @RequestMapping(name ="getperson", produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE})
    public Person getPerson() {
        Person p = new Person();
        p.setAge(28);
        p.setEmail("email@gmail.com");
        p.setName("Amar");
        return p;
    }

}

Model class :-

package com.example.domain;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Person {

    //@XmlElement
    private String name;
    //@XmlElement
    private int age;
    private String email;

    public String getName() {
        return name;
    }
    @XmlElement
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    @XmlElement
    public void setAge(int age) {
        this.age = age;
    }
    public String getEmail() {
        return email;
    }
    @XmlElement
    public void setEmail(String email) {
        this.email = email;
    }
}

Build file:-

buildscript {
    ext {
        springBootVersion = '1.3.6.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot' 

jar {
    baseName = 'demo'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-aop')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('javax.xml.bind:jaxb-api:2.2.12')
    testCompile('org.springframework.boot:spring-boot-starter-test') 
}


eclipse {
    classpath {
         containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
         containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
    }
}

What am I doing wrong ??? Any help here is much appreciated.

Thanks,

Amar

Amar Dev
  • 1,360
  • 2
  • 18
  • 38
  • 1
    JAXB is part of the JDK you shouldn't need to add that dependencies. What is returned is determined by what you send as the accept header (and in which order) and also by which URL you are calling (extensions like .json or .xml also have influence in what is getting returned). I you want jackson to understand the JAXB annotation you will need to include the correct JAXB dependency for that. – M. Deinum Jul 11 '16 at 09:21
  • Thanks a lot, Since I can't accept a comment as an answer, I have accepted the below one. – Amar Dev Jul 11 '16 at 09:31

2 Answers2

6

In order to get json response from the server your request must contain Accept header set to application/json.

Oleg Kurbatov
  • 1,376
  • 1
  • 19
  • 32
  • This works, Thanks, I was thinking content-type set as the request header will do the trick, but it was the Accept Header. – Amar Dev Jul 11 '16 at 09:30
3

In order to send response in Json or XML, one solution might be to use Content Negotiation Strategy. You could use urls such as /person.json or /person.xml. These will produces json or xml response. But first, you have to configure your Main Spring boot Class :

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

  @Override

      public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false).
                favorParameter(true).
                parameterName("mediaType").
                ignoreAcceptHeader(true).
                useJaf(false).
                defaultContentType(MediaType.APPLICATION_JSON).
                mediaType("xml", MediaType.APPLICATION_XML).
                mediaType("json", MediaType.APPLICATION_JSON);
      }
    }

No need to add produces = {MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE} in your controller. Here is an example Hope this will help

Pracede
  • 4,226
  • 16
  • 65
  • 110