How to pass parameter to JsonSerializer?

dropwizard, jackson, java, jax-rs, jsonserializer

Solution

I know that this is not a new question but here is what I came up with facing the similar problem:

created custom annotation:

@Target({ ElementType.FIELD, ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonLocalizable {

  public String localizationKey();
} 

Jackson serializer:

 public class LocalizingSerializer extends StdSerializer<String> implements ContextualSerializer {

      private String localizationKey;

      public LocalizingSerializer() {
        super(String.class);
      }

      public LocalizingSerializer(String key) {
        super(String.class);

        this.localizationKey = key;
      }

      @Override
      public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {

        String localizedValue = //.... get the value using localizationKey

        jgen.writeString(localizedValue);
      }

      @Override
      public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {

        String key = null;
        JsonLocalizable ann = null;

        if (property != null) {
          ann = property.getAnnotation(JsonLocalizable.class);
        }

        if (ann != null) {
          key = ann.localizationKey();
        }

        //if key== null??

        return new LocalizingSerializer(key);
      }
    }

Annotate the field you want to localize:

public class TestClass {

    @JsonSerialize(using = LocalizingSerializer.class)
    @JsonLocalizable(localizationKey = "my.key")
    private String field;

    public String getField() {
      return this.field;
    }

    public void setField(String field) {
      this.field = field;
    }
}

Problem

I have a simple data service : ``` @GET public Data getData(@QueryParam("id") Long id) { Data data = dataService.getData(id); return data; } ``` And a matching `DataSerializer` that implements `JsonSerializer<Data>` : The `DataSerializer` is registered to Jackson via : ``` simpleModule.addSerializer(Data.class , dataSerializer); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(simpleModule); ``` It works well. But today , I want to add another `Locale` parameter , and hope the `DataSerializer` to output correspondent content : ``` @GET public Data getData(@QueryParam("id") Long id , @QueryParam("locale") Locale locale) ``` The '`Data`' itself contains various locale variations , and I hope to get the assigned locale output. But when I get the `locale` from the parameter , I don't know how to pass the `locale` value to the `DataSerializer` … Is there anyway to achieve this ? Except this solution : ``` Data data = dataService.getData(id.get() , locale); ``` which is not what I want. It seems `ThreadLocal` is the only way to achieve this , but I feel that is ugly. Any other feasible solutions ? Thanks. Environments : dropwizard-0.7.0-rc2 , jackson-core:jar:2.3.1 ===================== updated ========== reply to @andrei-i : Because my data itself already contains various locale versions. for example : ``` Data helloData = dataService.get("hello"); helloData.getName(Locale.English) == "Hello"; helloData.getName(Locale.France) == "Bonjour"; helloData.getName(Locale.Germany) == "Hallo"; ``` I want to directly pass the locale from URL to JsonSerializer , to get one version of the data presentation. And there 'may' be other version (not just locale) , so , inheriting Data mixing Locale is not considered.

Original source