Laucien
Laucien

Reputation: 521

Overriding a property name when transforming the object to json

I'm coding some backend tests for a feature at work and apparently got stuck on something that seems easy to solve on paper but can't figure out how to make it work >.>.

Here's an example of what I'm doing.

This is how I need the JSON to end up looking like:

{
    "application.properties.service": {
        "properties": {
            "test": "property"
        }
    }
}

These are the 2 Groovy classes I wrote to model that request:

class Configuration {

    private ApplicationPropertiesService applicationPropertiesService

    Configuration() {

    }

    @JsonProperty("application.properties.service")
    ApplicationPropertiesService getApplicationPropertiesService() {
        return applicationPropertiesService
    }

    void setApplicationPropertiesService(ApplicationPropertiesService applicationPropertiesService) {
        this.applicationPropertiesService = applicationPropertiesService
    }
}

--

class ApplicationPropertiesService {

    private Map properties

    ApplicationPropertiesService() {
        this.properties = new HashMap()
    }

    ApplicationPropertiesService(Map properties) {
        this.properties = properties
    }

    Map getProperties() {
        return properties
    }

    void setProperties(Map properties) {
        this.properties = properties
    }

    void addProperty(String key, String value) {
        this.properties.put(key, value)
    }
}

Here's the test I'm doing to try it out:

@Test
void "test"() {
    ApplicationPropertiesService  appPropServ = new ApplicationPropertiesService()
    appPropServ.addProperty("test", "property")
    Configuration testConfig = new Configuration()
    testConfig.setApplicationPropertiesService(appPropServ)

    println new JsonBuilder(testConfig).toPrettyString()
}

But of course what I get in the end is this:

{
    "applicationPropertiesService": {
        "properties": {
            "test": "property"
        }
    }
}

So what I can't figure out is how to override the name so that when parsing it into a JSON it would be separated by . instead of camel case as it is right now. From what I've been reading the annotation @JsonProperty("application.properties.service") from the jackson.annotation package should do exactly what I want but I tried putting it before the getter for the property and then putting it above the property declaration at the start of the class but in both cases it just seems to ignore it.

Am I missing anything?.

Upvotes: 0

Views: 1594

Answers (2)

aristotll
aristotll

Reputation: 9175

It is not a JsonProperty problem, but because of the code

Configuration(ApplicationPropertiesService applicationPropertiesService) {
    this.applicationPropertiesService = applicationPropertiesService
}

So there is no default constructor in your Configuration which makes jackson cannot create the Configuration object. (It uses reflection, and do not know the specific constructor to use. So it uses default constructor).

Try to add

Configuration() {

}

to Configuration class.


Update: You should not mix Jackson ObjectMapper with Groovy built in JsonBuilder.

    ApplicationPropertiesService appPropServ = new ApplicationPropertiesService()
    appPropServ.addProperty("test", "property")
    Configuration testConfig = new Configuration()
    testConfig.setApplicationPropertiesService(appPropServ)
     println new ObjectMapper().writeValueAsString(testConfig)

Output:

{"application.properties.service":{"properties":{"test":"property"}}}

Upvotes: 1

Rao
Rao

Reputation: 21379

If you are looking a groovy based solution, isn't it simple? code is data, data is code.

import groovy.json.JsonBuilder
import groovy.json.JsonOutput

def json = new JsonBuilder()
json.'application.properties.service' {
  properties {
    test 'property'
  }
}

println JsonOutput.prettyPrint(json.toString())

assert '{"application.properties.service":{"properties":{"test":"property"}}}'  == json.toString()

You can quickly try it online demo

Upvotes: 1

Related Questions