Home > Blockchain >  How to have different @JsonProperty based on environment in spring boot
How to have different @JsonProperty based on environment in spring boot

Time:12-08

I have a class which is used as a request to hit another service.

It has few fields like below.

public class RequestClass {

  @JsonProperty("123")
  private String name;

  @JsonProperty("124")
  private String email;

  @JsonProperty("129")
  private String mobile;

}

The upstream service requires the request with field id like 123, 124, 129,etc.

These field id will be different for test and production environment.

Is there any better way to do it other than having different RequestClass?

CodePudding user response:

You could create a config class where you keep track of the actual id according to your environment and map them using jackson's @JsonAnyGetter.

So for example if you have the following application.properties (I'm using multi-document props here, but you could also have application.properties per profile):

spring.profiles.active=dev
#---
spring.config.activate.on-profile=dev
application.requestClass.nameId=123
#---
spring.config.activate.on-profile=test
application.requestClass.nameId=456

Then, you'd create your config class (I'm using Lombok's @Data for getter/setters):

@Configuration
@Data
public class RequestClassConfig {

    @Value("${application.requestClass.nameId}")
    private String nameId;

    @PostConstruct
    public void postConstruct() {
        RequestClass.config = this;
    }
}

and finally your DTO with @JsonAnyGetter:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RequestClass {

    public static RequestClassConfig config;

    @JsonIgnore
    private String name;

    @JsonAnyGetter
    public Map<String, Object> any() {
        final var map = new HashMap<String, Object>();

        map.put(config.getNameId(), this.name);
        return map;
    }

}

Note that you can do the same for the remaining props, I've just omitted those for brevity.

Now for a quick test run:

@SpringBootApplication
public class App {

    public static void main(String[] args) throws JsonProcessingException {
        SpringApplication.run(App.class, args);
        final var mapper = new ObjectMapper();
        final var req = new RequestClass();
        req.setName("test");

        System.out.println(mapper.writeValueAsString(req));
    }

}

This will print {"123":"test"} to the console if the dev profile is active and {"456":"test"} if the test profile is active.

  • Related