5

I have below json:

    "[{\"movieName\":\"A\",\"Leadactor\":\"\",\"leadActress\":\"\",\"movieTitle\":\"\",\"hero\":\"\",\"heroine\":\"\",\"source\":\"IMDB\"}," +
    "{\"movieName\":\"\",\"Leadactor\":\"\",\"leadActress\":\"\",\"movieTitle\":\"B\",\"hero\":\"B1\",\"heroine\":\"B2\",\"source\":\"Netflix\"}," +
    "{\"movieName\":\"C\",\"Leadactor\":\"C1\",\"leadActress\":\"C2\",\"movieTitle\":\"\",\"hero\":\"\",\"heroine\":\"\",\"source\":\"IMDB\"}," +
    "{\"movieName\":\"D\",\"Leadactor\":\"D1\",\"leadActress\":\"D2\",\"movieTitle\":\"\",\"hero\":\"\",\"heroine\":\"\",\"source\":\"IMDB\"}," +
    "{\"movieName\":\"\",\"Leadactor\":\"\",\"leadActress\":\"\",\"movieTitle\":\"E\",\"hero\":\"E1\",\"heroine\":\"E2\",\"source\":\"Netflix\"}]";

I am using jackson parser to map it to a class:

I want movieName and movieTitle to map into Name property in the java class. So i wrote the below class:

public static class MovieData {
    @JsonProperty("Name")
    private String name;

    @JsonSetter({"movieName"})
    private void setMovieName(final String name) {
            if((name != null) && (! name.equals(""))) {
                    setNameInternal(name);
            }
    }

    @JsonSetter("movieTitle")
    private void setMovieTitle(final String name) {
            if((name != null) && (! name.equals(""))) {
                    setNameInternal(name);
            }
    }

    private void setNameInternal(final String name) {
            this.name = name;
    }

}

In my real json there are so many fields like movieName, movieTitle which i want to normalize into a common name.

Is there any simple syntax like the below which can reduce code duplication:

public static class MovieData {
    @JsonProperty("Name")
    private String name;

 @JsonSetter(value = { "movieName", "movieTitle" })
 private void setName(final String name) {
        if((name != null) && (! name.equals(""))) {
                this.name=name;
        }
}
  }

The above code gave me error on jsonSetter:

 Type mismatch: cannot convert from String[] to String.

EDIT

If Jackson doesn't support it, can GSON Support this operation.

Thanks

3
  • 1
    Your question is not very clear... do you want a list of objects Movie with an attribute name, which contains the value of either "movieName" or "movieTitle"? And if, let's say, "movieName" has a value, "movieTitle" will be always emtpty? Commented Jun 4, 2013 at 23:50
  • 1
    Have you tried adding multiple annotations to setName, one for movieName and one for movieTitle? Otherwise the solution below with @JsonAnySetter will work. Commented Jun 5, 2013 at 17:03
  • @MikO yes i want a list of objects Movie with an attribute name, which contains the value of either movie name or movie title. Yes if movie name has a vlaue then movie title is empty. Commented Jun 5, 2013 at 18:14

3 Answers 3

5

You can use @JsonAnySetter, what it is mean you can find on Jackson Core (Data-Binding) Annotations page.

I have created simple bean which is related to your example:

class MovieData {

    private static List<String> NAME_PROPERTIES = Arrays.asList("movieName", "movieTitle");

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @JsonAnySetter
    private void parseUnknownProperties(String propertyName, String propertyValue) {
        if (NAME_PROPERTIES.contains(propertyName) && !propertyValue.isEmpty()) {
            this.name = propertyValue;
        }
    }

    @Override
    public String toString() {
        return name;
    }
}

Now when I deserialize your JSON in this way:

ObjectMapper objectMapper = new ObjectMapper();
System.out.println(Arrays.toString(objectMapper.readValue(json, MovieData[].class)));

As result I can see:

[A, B, C, D, E]
Sign up to request clarification or add additional context in comments.

Comments

3

Dont do this much. it is very simple with Gson

create class for your single set record like

class Movie{
    private String movieName;
    private String Leadactor;
    private String leadActress;

    //put getter and setter for your fields
}

in main file
Type type = new TypeToken<List<Movie>>(){}.getType();
List<Movie> data = new Gson().fromJson(json_string,type);

2 Comments

I know about gson. the problem is about normalization. I want movieTitle also to map into movieName;
Please refrain from asking people to vote/accept your answers. See this meta post for more information. Thanks!
0

You declare the field like @JsonProperty String[] data

and use

 new ObjectMapper()
      .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
      .readValue(json, YOUT_TYPE.class)

So this option make Jackson part both "foo":"bar" and "foo": ["a", "b", "c"].

All you need to do is to merge string array back into the string with right line separators. I do it via Guava data == null ? null : Jointer.on("\n").join(data)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.