Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON field mapping for Java model

Tags:

JSON which is sent:

{
  "Banner": "ABC"
}

Java model:

...
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class BannerData implements java.io.Serializable {

    private static final long serialVersionUID = 5664846645733319592L;

    @JsonProperty(value = "Banner")
    private String banner;

    public String getBanner() {
        return banner;
    }

    public void setBanner(String banner) {
        this.banner = banner;
    }
}

Controller:

@RequestMapping(value = {"/GetBanner"}, method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<String> enrollCustomer(@RequestBody BannerData body, HttpServletRequest request) throws Exception {
...
}

request to /GetBanner returns:
The request sent by the client was syntactically incorrect.

Works OK when json changed to (lowercase naming as is Java field name):

{
  "banner": "ABC"
}

However I need uppercase field naming in JSON.
Looks like @JsonProperty(value = "Banner") does not work.

Is it correct mapping?

like image 497
sergionni Avatar asked Jun 19 '15 17:06

sergionni


People also ask

What is JsonProperty annotation Java?

The @JsonProperty annotation is used to map property names with JSON keys during serialization and deserialization. By default, if you try to serialize a POJO, the generated JSON will have keys mapped to the fields of the POJO.

What is the use of @JsonProperty in Java?

@JsonProperty is used to mark non-standard getter/setter method to be used with respect to json property.


4 Answers

Maybe you just try to:

@JsonProperty("Banner")

without 'value ='. I used it in my project and it actually worked as expected.

UPDATE

I just created some test classes to test the bahaviour of your problem. What I have done:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonSerialize;


@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class BannerData implements java.io.Serializable {

 private static final long serialVersionUID = 5664846645733319592L;

 @JsonProperty("Banner")
 private String banner;

 public String getBanner() {
     return banner;
 }

 public void setBanner(String banner) {
     this.banner = banner;
 }
}

Another class to read the json:

import org.codehaus.jackson.map.ObjectMapper;
import java.io.File;
import java.io.IOException;

public class BannerReader {
 private static final String JSON_PATH = "pathToYourJson";

 public BannerData readBanner() throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readValue(new File(JSON_PATH), BannerData.class);
 }
}

And finally the entry point class:

import java.io.IOException;

public class BannerTest {

 public static void main(String[] args) throws IOException {
     BannerReader reader = new BannerReader();
     BannerData bannerData = reader.readBanner();
     System.out.println(bannerData.getBanner());
 }
}

prints:

ABC

Used dependency:

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.9.13</version>
</dependency>

json file:

{
  "Banner": "ABC"
}

UPDATE 2

While the above code does not work for you, try adding

@JsonProperty("Banner")

not only to the private variable, but also to the getter/setter pair, like:

@JsonProperty("Banner")
private String banner;

@JsonProperty("Banner")
public String getBanner() {
  return banner;
}

@JsonProperty("Banner")
public void setBanner(String banner) {
  this.banner = banner;
}
like image 128
Arthur Eirich Avatar answered Oct 13 '22 01:10

Arthur Eirich


I would suggest below; (If you are using ObjectMapper)

once you get your ObjectMapper, you can set PropertyNamingStrategy with PascalCase. this is link for documentation

ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(
    PropertyNamingStrategy.PascalCaseStrategy);

If you are not using ObjectMapper- then Annotate your BannerData class with @JsonNaming like below--

@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class) 
public class BannerData implements java.io.Serializable {

I found out @JsonNaming here in github

like image 32
Ashish Patil Avatar answered Oct 13 '22 00:10

Ashish Patil


Have you tried to update your jackson from 1.9.13 to 2.5.4 (it has another artifact group id - com.fasterxml.jackson )

Is this code works correctly for you?

ObjectMapper mapper = new ObjectMapper();
BannerData bannerData = mapper.readValue("{ \"Banner\": \"ABC\"}", BannerData.class);

Works fine with me (If I replace "Banner" with "banner" - got wrong object with null "banner" field.)

Also this code can be useful:

System.out.println(mapper.getDeserializationConfig().getPropertyNamingStrategy());

Something can be wrong with property naming strategy - if you use custom one.

like image 31
pkozlov Avatar answered Oct 13 '22 00:10

pkozlov


Try it on the getter

@JsonProperty(value = "Banner")
public String getBanner() {

EDIT:

Show us your Spring config file. Are you really using Jackson? See http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-jackson-and-client-program

 <!-- Configure to plugin JSON as request and response in method handler -->
 <beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
     <beans:property name="messageConverters">
         <beans:list>
             <beans:ref bean="jsonMessageConverter"/>
         </beans:list>
     </beans:property>
 </beans:bean>

 <!-- Configure bean to convert JSON to POJO and vice versa -->
 <beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
 </beans:bean> 

EDIT 2

Since you may or may not be using Jackson... try some other annotations @XmlElement(name="Banner")

From GSON perhaps @SerializedName("Banner")

like image 36
Shaun Avatar answered Oct 13 '22 01:10

Shaun