복붙노트

[SPRING] Spring 부트에서 Yaml의 목록을 객체 목록으로 매핑

SPRING

Spring 부트에서 Yaml의 목록을 객체 목록으로 매핑

내 스프링 부팅 응용 프로그램에서 다음 내용이 포함 된 application.yaml 구성 파일이 있습니다. 채널 구성 목록이있는 Configuration 객체로 주입하려고합니다.

available-payment-channels-list:
  xyz: "123"
  channelConfigurations:
    -
      name: "Company X"
      companyBankAccount: "1000200030004000"
    -
      name: "Company Y"
      companyBankAccount: "1000200030004000"

그리고 @Configuration 객체 PaymentConfiguration 객체의 목록으로 채워 넣고 싶습니다.

    @ConfigurationProperties(prefix = "available-payment-channels-list")
    @Configuration
    @RefreshScope
    public class AvailableChannelsConfiguration {

        private String xyz;

        private List<ChannelConfiguration> channelConfigurations;

        public AvailableChannelsConfiguration(String xyz, List<ChannelConfiguration> channelConfigurations) {
            this.xyz = xyz;
            this.channelConfigurations = channelConfigurations;
        }

        public AvailableChannelsConfiguration() {

        }

        // getters, setters


        @ConfigurationProperties(prefix = "available-payment-channels-list.channelConfigurations")
        @Configuration
        public static class ChannelConfiguration {
            private String name;
            private String companyBankAccount;

            public ChannelConfiguration(String name, String companyBankAccount) {
                this.name = name;
                this.companyBankAccount = companyBankAccount;
            }

            public ChannelConfiguration() {
            }

            // getters, setters
        }

    }

@Autowired 생성자가있는 일반 빈으로 주입하고 있습니다. xyz의 값은 정확하게 채워지지만, Spring이 yaml을 구문 분석하려고 시도 할 때

   nested exception is java.lang.IllegalStateException: 
    Cannot convert value of type [java.lang.String] to required type    
    [io.example.AvailableChannelsConfiguration$ChannelConfiguration] 
    for property 'channelConfigurations[0]': no matching editors or 
    conversion strategy found]

여기에 어떤 단서가 있니?

해결법

  1. ==============================

    1.이유는 다른 곳에 있어야합니다. 구성없이 Spring Boot 1.2.2 만 사용하면 작동합니다. 이 레포를 보시고 - 휴식을 취할 수 있습니까?

    이유는 다른 곳에 있어야합니다. 구성없이 Spring Boot 1.2.2 만 사용하면 작동합니다. 이 레포를 보시고 - 휴식을 취할 수 있습니까?

    https://github.com/konrad-garus/so-yaml

    YAML 파일이 붙여 넣기 된 방식과 정확히 일치합니까? 여분의 공백, 문자, 특수 문자, 잘못 들여 쓰기 또는 그런 종류의 것이 없습니까? 검색 경로에서 예상 한 파일 대신 사용되는 다른 파일을 가질 수 있습니까?

  2. ==============================

    2.다음과 같이 클래스를 변경하십시오.

    다음과 같이 클래스를 변경하십시오.

    @ConfigurationProperties(prefix = "available-payment-channels-list")
    @Configuration
    public class AvailableChannelsConfiguration {
    
    private String xyz;
    private List<ChannelConfiguration> channelConfigurations;
    
    // getters, setters
    
    public static class ChannelConfiguration {
        private String name;
        private String companyBankAccount;
    
        // getters, setters
    }
    
    }
    
  3. ==============================

    3.나는이 기사와 많은 다른 자료를 참조했으며 도움을 줄 명확하고 간결한 응답을 찾지 못했습니다. 나는 나의 발견을 제안하고 있는데,이 글의 참고 문헌은 다음과 같다.

    나는이 기사와 많은 다른 자료를 참조했으며 도움을 줄 명확하고 간결한 응답을 찾지 못했습니다. 나는 나의 발견을 제안하고 있는데,이 글의 참고 문헌은 다음과 같다.

    봄 부팅 버전 : 1.3.5. 릴리스

    스프링 코어 버전 : 4.2.6.RELEASE

    종속성 관리 : Brixton.SR1

    다음은 해당 yaml 발췌 부분입니다 :

    tools:
      toolList:
        - 
          name: jira
          matchUrl: http://someJiraUrl
        - 
          name: bamboo
          matchUrl: http://someBambooUrl
    

    Tools.class를 만들었습니다.

    @Component
    @ConfigurationProperties(prefix = "tools")
    public class Tools{
        private List<Tool> toolList = new ArrayList<>();
        public Tools(){
          //empty ctor
        }
    
        public List<Tool> getToolList(){
            return toolList;
        }
    
        public void setToolList(List<Tool> tools){
           this.toolList = tools;
        }
    }
    

    Tool.class를 만들었습니다.

    @Component
    public class Tool{
        private String name;
        private String matchUrl;
    
        public Tool(){
          //empty ctor
        }
    
        public String getName(){
            return name;
        }
    
        public void setName(String name){
           this.name= name;
        }
        public String getMatchUrl(){
            return matchUrl;
        }
    
        public void setMatchUrl(String matchUrl){
           this.matchUrl= matchUrl;
        }
    
        @Override
        public String toString(){
            StringBuffer sb = new StringBuffer();
            String ls = System.lineSeparator();
            sb.append(ls);
            sb.append("name:  " + name);
            sb.append(ls);
            sb.append("matchUrl:  " + matchUrl);
            sb.append(ls);
        }
    }
    

    @Autowired를 통해 다른 클래스에서이 조합을 사용했습니다.

    @Component
    public class SomeOtherClass{
    
       private Logger logger = LoggerFactory.getLogger(SomeOtherClass.class);
    
       @Autowired
       private Tools tools;
    
       /* excluded non-related code */
    
       @PostConstruct
       private void init(){
           List<Tool>  toolList = tools.getToolList();
           if(toolList.size() > 0){
               for(Tool t: toolList){
                   logger.info(t.toString());
               }
           }else{
               logger.info("*****-----     tool size is zero     -----*****");
           }  
       }
    
       /* excluded non-related code */
    
    }
    

    그리고 내 로그에 이름과 일치하는 URL이 기록되었습니다. 이것은 다른 기계에서 개발 되었기 때문에 위의 모든 내용을 다시 입력해야했기 때문에 실수로 잘못 입력 한 경우 미리 용서해주십시오.

    이 통합 주석이 많은 사람들에게 도움이되기를 바란다. 나는이 글의 이전 기여자들에게 감사한다.

  4. ==============================

    4.나도이 문제에 많은 문제가 있었다. 드디어 마지막 거래가 무엇인지 알게되었습니다.

    나도이 문제에 많은 문제가 있었다. 드디어 마지막 거래가 무엇인지 알게되었습니다.

    @Gokhan Oner Answer를 참고하면, 일단 당신의 Service 클래스와 POJO가 객체를 표현하면, YAML 설정 파일은 멋지고 의지 할 수있다. @ConfigurationProperties 주석을 사용한다면 명시 적으로 사용할 수있는 객체를 가져와야한다. 그것. 처럼 :

    @ConfigurationProperties(prefix = "available-payment-channels-list")
    //@Configuration  <-  you don't specificly need this, instead you're doing something else
    public class AvailableChannelsConfiguration {
    
        private String xyz;
        //initialize arraylist
        private List<ChannelConfiguration> channelConfigurations = new ArrayList<>();
    
        public AvailableChannelsConfiguration() {
            for(ChannelConfiguration current : this.getChannelConfigurations()) {
                System.out.println(current.getName()); //TADAAA
            }
        }
    
        public List<ChannelConfiguration> getChannelConfigurations() {
            return this.channelConfigurations;
        }
    
        public static class ChannelConfiguration {
            private String name;
            private String companyBankAccount;
        }
    
    }
    

    그리고 여기에 당신이 간다. 그것은 지옥처럼 간단하지만 우리는 객체 getter를 호출해야한다는 것을 알아야합니다. 객체 초기화를 기다리는 중입니다. 희망이 도움이 :)

  5. from https://stackoverflow.com/questions/32593014/mapping-list-in-yaml-to-list-of-objects-in-spring-boot by cc-by-sa and MIT license