10

I am trying to Map the yml file to a HashMap with String Key and PromotionPolicy value in my Spring boot application and using the default spring boot implementation to parse the values, but the PromotionPolicy object only contains the default values [0, false, false] for all instances when I try to read values from the Map.

My yml is :

promotionPolicies : 
    policies: 
        P001NN:
            PromotionPolicy:
                expiryPeriodInDays: 16
                reusable: true
                resetExpiry: false
        P001YN:
            PromotionPolicy:
                expiryPeriodInDays:1
                reusable:true
                resetExpiry:false
        P001NY:
            PromotionPolicy:
                expiryPeriodInDays:1
                reusable:false
                resetExpiry:true

The Model I have is :

public class PromotionPolicy {

private int expiryPeriodInDays;
private boolean reusable;
private boolean resetExpiry;

public int getExpiryPeriodInDays() {
    return expiryPeriodInDays;
}
public void setExpiryPeriodInDays(int expiryPeriodInDays) {
    this.expiryPeriodInDays = expiryPeriodInDays;
}
public boolean isReusable() {
    return reusable;
}
public void setReusable(boolean reusable) {
    this.reusable = reusable;
}
public boolean isResetExpiry() {
    return resetExpiry;
}
public void setResetExpiry(boolean resetExpiry) {
    this.resetExpiry = resetExpiry;
}

}

The component java class is as below:

@Configuration
@ConfigurationProperties(prefix = "promotionPolicies")
@EnableConfigurationProperties
@Component
public class PromotionPolicyConfig {

private Map<String, PromotionPolicy> policies = new HashMap<String, PromotionPolicy>();

public void setPolicies(Map<String, PromotionPolicy> policies) {
    this.policies = policies;
}

public Map<String, PromotionPolicy> getPolicies() {
    return policies;
}

}

Trying to display values here :

@RestController
@RequestMapping("/test")
public class LoyaltyServiceController {

@Autowired
PromotionPolicyConfig promotionPolicyConfig;

@RequestMapping(value = "/try")
public String tryThis() {
    for (Entry<String, PromotionPolicy> entry : promotionPolicyConfig.getPolicies().entrySet()) {
        System.out.print(entry.getKey() + " : ");
        System.out.print(entry.getValue() + " : ");
        System.out.print(entry.getValue().getExpiryPeriodInDays()  + " : ");
        System.out.print(entry.getValue().isResetExpiry()  + " : ");
        System.out.println(entry.getValue().isReusable()  + " : ");
    }
}

My Output is as below:

P001NN : com.expedia.www.host.loyalty.model.PromotionPolicy@63a1c99b : 0 : false : false : 
P001YN : com.expedia.www.host.loyalty.model.PromotionPolicy@7892b6b6 : 0 : false : false : 
P001NY : com.expedia.www.host.loyalty.model.PromotionPolicy@459928ab : 0 : false : false : 

while I expected the result to contain the values in my yml. I also tried removing the line "PromotionPolicy:" in my yml, but no luck.

Request help understand how can I Map the yml into the Map of custom objects.

Manjunath
  • 117
  • 1
  • 1
  • 5
  • may be this will help http://stackoverflow.com/questions/32593014/mapping-list-in-yaml-to-list-of-objects-in-spring-boot – pvpkiran Apr 19 '17 at 22:21

5 Answers5

12

change your yml to

promotionPolicies : 
  policies: 
    P001NN:
            expiryPeriodInDays: 16
            reusable: true
            resetExpiry: false
    P001YN:
            expiryPeriodInDays: 1
            reusable: true
            resetExpiry: false
    P001NY:
            expiryPeriodInDays: 1
            reusable: false
            resetExpiry: true
Community
  • 1
  • 1
pvpkiran
  • 25,582
  • 8
  • 87
  • 134
8
  • This worked for me

YML:

property-name: '{
  key1: "value1",
  key2: "value2"
}'

Spring Boot:

  @Value("#{${property-name}}")
  private Map<String,String> myMap;

found the answer thanks to : https://relentlesscoding.com/2018/09/09/spring-basics-dynamically-inject-values-with-springs-value/

csf
  • 529
  • 1
  • 4
  • 16
0
        promotionPolicies : 
          policies: 
            P001NN:
                    expiryPeriodInDays: 16
                    reusable: true
                    resetExpiry: false
            P001YN:
                    expiryPeriodInDays: 1
                    reusable: true
                    resetExpiry: false
            P001NY:
                    expiryPeriodInDays: 1
                    reusable: false
                    resetExpiry: true

Java code :

        //Used lambok and spring annotation
        @Data
        @Configuration
        @ConfigurationProperties(prefix = "promotionPolicies")
        @NoArgsConstructor
        @AllArgsConstructor
        public class PromotionPolicies {
            private Map<String, Map<String, String>> policies = new HashMap<>();
        }

            
0

I recently solved a similar problem. In my case a default, i.e. no argument, constructor was required for PromotionPolicy class.

Abra
  • 19,142
  • 7
  • 29
  • 41
-1

The problem was with the spaces, the below yml works fine. The spaces after the text and : was required

promotionPolicies : 
    policies : 
        P001NN :
            PromotionPolicy :
                expiryPeriodInDays: 16
                reusable: true
                resetExpiry: false
        P001YN :
            PromotionPolicy :
                expiryPeriodInDays:1
                reusable:true
                resetExpiry:false
        P001NY :
            PromotionPolicy :
                expiryPeriodInDays:1
                reusable:false
                resetExpiry:true
Manjunath
  • 117
  • 1
  • 1
  • 5