2

The Situation

I have an enum class called Errors and it is in a common project. The errors enum contains an int code and a String text. The Errors enum is used in two different projects. One project is a Spring based project and the other project is in a non-Spring J2EE application.

In the Spring based project, Jackson is the library used for converting the Errors enum to Json. So if there is a request we can return an Errors enum object and it will be automatically converted to the json representation, which is {code: int, text: error} The Errors enum has the annotation:

@JsonSerialize(using=ErrorsSerializer.class)

The ErrorsSerializer class is located in the Spring based application.

In the common project, where the Errors enum is located, Gson is the library used for converting objects to its Json representation and we want to remove any references to the Jackson library.

The problem

If i remove the annotation from the Errors enum the Spring project will not return the correct representation of the Errors enum, it will only return the constant variable in quotes.

The Question

How do i remove the annotation of the Errors enum (which will remove any Jackson dependencies in the common project) and yet still have the Spring project return the correct Json representation?

Best Option So Far

The best option i have come up with so far is to create an Errors container object in the Spring application that contains the Errors enum and also has the json serialize annotation.

Thanks!

j will
  • 3,747
  • 11
  • 41
  • 64
  • Your best option so far is the best option. Since it's an enum, you can't extend it, so a wrapper object is about your only option. – Taylor Nov 20 '13 at 19:16

1 Answers1

2

You can also specify serializer in Spring based project using Module functionality. Module allow users to customize ObjectMapper object without annotations. See below example:

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class JacksonProgram {

    public static void main(String[] args) throws Exception {
        SimpleModule module = new SimpleModule();
        module.addSerializer(Error.class, new ErrorJsonSerializer());

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(module);

        System.out.println(mapper.writeValueAsString(Error.NOT_FOUND));
    }
}

Above example prints:

{"code":1,"text":"Not found"}

See below links to find solution how to configure ObjectMapper in Spring app:

Community
  • 1
  • 1
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • I would have to call mapper.writeValueAsString whenever i wanted a json representation sent back, right? Is there anyway to have this be automated like it would be with @JsonSerialize? And have the controller method send back an Errors enum rather than a String? – j will Nov 21 '13 at 15:53
  • Spring automatically creates `ObjectMapper` instance and uses it to serialize objects to JSON. You have to create your own `ObjectMapper` class and tell Spring to use your custom OM instead of default one. Above source code is just example, which shows that above solution works properly for `Enum`s. – Michał Ziober Nov 21 '13 at 16:54
  • So what line in your example above tells spring to use the custom OM? – j will Nov 21 '13 at 16:55
  • Above example is just a simple Java console app. It shows how to configure OM to achieve correct result. Could you tell me which version of Spring and Jackson are you using? – Michał Ziober Nov 21 '13 at 16:58
  • spring-framework-version: 3.2.2.RELEASE and version 1.9.12 for Jackson – j will Nov 21 '13 at 17:04
  • One thing that i didn't realize, but helped me a lot, was that I can only have one custom objectMapper and that i can add multiple mappings to the custom objectMapper. Also, i didn't have a need for the SimpleModule object. I wasn't instantly printing out objects as a string. I let the spring autmation handle it. – j will Nov 21 '13 at 21:18