20

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?

Erik Gillespie
  • 3,929
  • 2
  • 31
  • 48
sergionni
  • 13,290
  • 42
  • 132
  • 189
  • 2
    I'm convinced you're not using Jackson. Several comments have asked to see your Spring setup but you haven't posted it. `@JsonProperty` works for 3 answers now -- you must be using another serializer – Shaun Jun 23 '15 at 14:45

4 Answers4

17

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;
}
Arthur Eirich
  • 3,368
  • 9
  • 31
  • 63
5

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

Ashish Patil
  • 4,428
  • 1
  • 15
  • 36
3

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")

Shaun
  • 3,777
  • 4
  • 25
  • 46
  • Are you sure you are using Jackson for serialization? It should work. See http://stackoverflow.com/questions/12583638/when-is-the-jsonproperty-property-used-and-what-is-it-used-for – Shaun Jun 21 '15 at 14:32
  • Can you post your configuration for Jackson? I've used `JsonProperty` a hundred times. Maybe you're using Moxy or something else by mistake – Shaun Jun 22 '15 at 13:30
3

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.

pkozlov
  • 746
  • 5
  • 17
  • I have not tried to update jackson.I will access code tomorrow and notify you about progress.Thanks for hint – sergionni Jun 21 '15 at 19:19
  • I don't use `ObjectMapper` mapper.The model is passed to contoller method as param with `@RequestBody` annotation. – sergionni Jun 22 '15 at 07:31
  • You don't use objectmapper directly, but if you use jackson provider for serialization in spring - you use it implicitly. Are you sure that you are using jackson provider, not something else? Some standard embedded spring json serializer? gson? Could you share your spring context descriptor (beans.xml or whatever) with us? – pkozlov Jun 22 '15 at 12:57
  • my spring config is limited ,nothing special – sergionni Jun 22 '15 at 13:22
  • `http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd` there are no more specific contents in spring config that may concern this issue – sergionni Jun 22 '15 at 13:22