गुणों की फ़ाइल से एक सूची पढ़ना और स्प्रिंग एनोटेशन @Value के साथ लोड करें


244

मैं .properties फ़ाइल में मानों की एक सूची रखना चाहता हूं, अर्थात:

my.list.of.strings=ABC,CDE,EFG

और इसे सीधे मेरी कक्षा में लोड करने के लिए, अर्थात:

@Value("${my.list.of.strings}")
private List<String> myList;

जैसा कि मैं समझता हूं, ऐसा करने का एक विकल्प यह है कि इसे स्प्रिंग कॉन्फिग फाइल में रखा जाए, और इसे बीन संदर्भ के रूप में लोड किया जाए (मुझे गलत होने पर सही करें), अर्थात

<bean name="list">
 <list>
  <value>ABC</value>
  <value>CDE</value>
  <value>EFG</value>
 </list>
</bean>

लेकिन क्या ऐसा करने का कोई तरीका है? .properties फ़ाइल का उपयोग कर रहे हैं? ps: यदि संभव हो तो मैं किसी भी कस्टम कोड के साथ ऐसा करना चाहूंगा।

जवाबों:


454

स्प्रिंग ईएल का उपयोग करना:

@Value("#{'${my.list.of.strings}'.split(',')}") 
private List<String> myList;

मान लें कि आपकी गुण फ़ाइल निम्न के साथ सही तरीके से भरी हुई है:

my.list.of.strings=ABC,CDE,EFG

1
मैंने इसे फिर से उसी संस्करण का उपयोग करके जांचा जो आप उपयोग कर रहे हैं। स्प्रिंग ईएल को पोस्ट की तरह ही कॉपी किया और यह काम करता है। हालांकि, अगर मैं अपने ईएल में त्रुटि करता हूं तो मुझे एक org.springframework.expression.spel.SpelEvaluationExceptionअपवाद मिलता है और क्या नहीं, यह अलग है javax.el.ELException। क्या आपकी आपत्ति वसंत द्वारा बनाई गई है?
विल्हेम क्लू

1
वसंत 3.2 के साथ पूरी तरह से काम करता है।
एहसानुल्लाहजान

17
खाली संपत्ति के बारे में कैसे my.list.of.strings=? मुझे उम्मीद है कि ऐसी कार्यक्षमता खाली सूची को हटा देगी जहां यह एक आइटम (खाली स्ट्रिंग) होगा, है न?
Jan Zyka

5
यह भी ध्यान दें कि सुझाए गए समाधान ट्रिमिंग नहीं करते हैं, इसलिए मान जैसे item1, item2, item3आप परिणाम दे सकते हैं आप वास्तव में उम्मीद नहीं करते हैं (संकेत: रिक्त स्थान)।
जान ज़ीका '

4
यदि आपको खाली स्थानों को ट्रिम करने की आवश्यकता है तो विभाजन तर्क के लिए रेगेक्स का उपयोग करें .. कुछ इस तरह@Value("#{'${my.list.of.strings}'.split(',\\s*')}")
Stackee007

88

स्प्रिंग 3.0 के बाद से, आप एक पंक्ति जोड़ सकते हैं

<bean id="conversionService" 
    class="org.springframework.context.support.ConversionServiceFactoryBean" />

आपके applicationContext.xml(या जहाँ आप चीजों को कॉन्फ़िगर करते हैं)। जैसा कि दिमित्री चॉर्नी एक टिप्पणी में बताती है, जावा आधारित विन्यास ऐसा दिखता है:

@Bean public ConversionService conversionService() {
    return new DefaultConversionService();
}

यह नई कॉन्फ़िगरेशन सेवा को सक्रिय करता है जो प्रकारों में परिवर्तित Stringहोने का समर्थन करता है Collection। यदि आप इस कॉन्फ़िगरेशन सेवा को सक्रिय नहीं करते हैं, तो स्प्रिंग इसकी विरासत संपत्ति संपादकों पर कॉन्फ़िगरेशन सेवाओं के रूप में वापस आ जाती है, जो इस तरह के रूपांतरण का समर्थन नहीं करते हैं।

अन्य प्रकार के कार्यों के संग्रह में परिवर्तित, भी:

@Value("${my.list.of.ints}")
private List<Integer> myList

जैसी लाइन के साथ काम करेंगे

 my.list.of.ints= 1, 2, 3, 4

व्हॉट्सएप के साथ कोई समस्या नहीं है, इसका ConversionServiceFactoryBeanख्याल रखता है।

Http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#core-convert-Spring-config देखें

एक स्प्रिंग एप्लिकेशन में, आप आमतौर पर एक रूपांतरण सेवा को प्रति स्प्रिंग कंटेनर (या ApplicationContext) से कॉन्फ़िगर करते हैं। उस रूपांतरण सेवा को स्प्रिंग द्वारा उठाया जाएगा और तब उपयोग किया जाएगा जब भी किसी प्रकार के रूपांतरण को फ्रेमवर्क द्वारा निष्पादित करने की आवश्यकता होती है। [...] यदि कोई रूपांतरण सेवा वसंत के साथ पंजीकृत नहीं है, तो मूल संपत्ति-आधारित प्रणाली का उपयोग किया जाता है।


6
जावा कॉन्फ़िगरेशन: @ सार्वजनिक रूपांतरण रूपांतरण सेवा सेवा () {नया DefaultConversionService () लौटें; }
दिमित्री चोर्नी

2
split()हर अभिव्यक्ति के साथ खुद को दोहराने से बचने के लिए , यह ठीक से आपको देने के बजाय एक खाली सूची को भी संभालता है[null]
डिडिएर एल

यदि संपत्ति को
अधिग्रहित किया

47

यदि आप इसे पढ़ रहे हैं और आप स्प्रिंग बूट का उपयोग कर रहे हैं , तो आपके पास इस सुविधा के लिए 1 और विकल्प है

आमतौर पर अल्पविराम से अलग की गई सूची वास्तविक विश्व उपयोग के मामले के लिए बहुत ही भद्दी होती है (और कभी-कभी संभव भी नहीं है, यदि आप अपने कॉन्फिग में कॉमा का उपयोग करना चाहते हैं):

email.sendTo=somebody@example.com,somebody2@example.com,somebody3@example.com,.....

स्प्रिंग बूट के साथ , आप इसे इस तरह लिख सकते हैं (सूचकांक 0 पर शुरू):

email.sendTo[0]=somebody@example.com
email.sendTo[1]=somebody2@example.com
email.sendTo[2]=somebody3@example.com

और इसे इस तरह उपयोग करें:

@Component
@ConfigurationProperties("email")
public class EmailProperties {

    private List<String> sendTo;

    public List<String> getSendTo() {
        return sendTo;
    }

    public void setSendTo(List<String> sendTo) {
        this.sendTo = sendTo;
    }

}


@Component
public class EmailModel {

  @Autowired
  private EmailProperties emailProperties;

  //Use the sendTo List by 
  //emailProperties.getSendTo()

}



@Configuration
public class YourConfiguration {
    @Bean
  public EmailProperties emailProperties(){
        return new EmailProperties();
  }

}


#Put this in src/main/resource/META-INF/spring.factories
  org.springframework.boot.autoconfigure.EnableAutoConfiguration=example.compackage.YourConfiguration

मुझे एक समस्या है कि यहां बताए गए अन्य समाधान बच गए अल्पविरामों के कारण काम नहीं करते हैं जो मान्यता प्राप्त नहीं हैं। क्या स्प्रिंग 4 के साथ इस समाधान को करने का कोई तरीका है?
सैंडरोज़बिंदन

34

my.list.of.strings=ABC,CDE,EFGमें .properties फ़ाइल निर्दिष्ट करके और उपयोग करके

@Value("${my.list.of.strings}") private String[] myString;

आप स्ट्रिंग्स के सरण प्राप्त कर सकते हैं। और उपयोग करके CollectionUtils.addAll(myList, myString), आप तार की सूची प्राप्त कर सकते हैं।


मुझे केवल पहली स्ट्रिंग "एबीसी"
मिलती है

19

क्या आपने @Autowiredकंस्ट्रक्टर या सेटर और String.split()आईएनजी को शरीर में अंतर्ग्रहण माना है?

class MyClass {
    private List<String> myList;

    @Autowired
    public MyClass(@Value("${my.list.of.strings}") final String strs) {
        myList = Arrays.asList(strs.split(","));
    }

    //or

    @Autowired
    public void setMyList(@Value("${my.list.of.strings}") final String strs) {
        myList = Arrays.asList(strs.split(","));
    }
}

मैं अपने कोड की परीक्षण क्षमता को बढ़ाने के लिए इनमें से किसी एक तरीके से अपनी ऑटोवेयर करना पसंद करता हूं।


14

यदि आप स्प्रिंग बूट 2 का उपयोग कर रहे हैं, तो यह बिना किसी अतिरिक्त विन्यास के काम करता है।

my.list.of.strings=ABC,CDE,EFG

@Value("${my.list.of.strings}")
private List<String> myList;

मेरे लिए काम नहीं किया, मुझे ऊपर दिखाए गए अनुसार स्प्रिंग ईएल का उपयोग करना होगा।
बिल्बो बैगिन्स

या यहां तक ​​किprivate List<String> myList;
हलीम अनिस

हाँ यह मेरे लिए भी काम किया: मैं स्प्रिंग बूट 2.2.6 का उपयोग कर रहा हूँ
अंकित

8

उपरोक्त सभी उत्तर सही हैं। लेकिन आप इसे सिर्फ एक लाइन में हासिल कर सकते हैं। कृपया घोषणा के बाद प्रयास करें और आपको स्ट्रिंग सूची में सभी अल्पविराम से अलग किए गए मान मिल जाएंगे।

private @Value("#{T(java.util.Arrays).asList(projectProperties['my.list.of.strings'])}") List<String> myList;

और आपको अपने xml कॉन्फ़िगरेशन में निम्नलिखित पंक्ति को भी परिभाषित करना होगा।

<util:properties id="projectProperties" location="/project.properties"/>

बस अपने गुण फ़ाइल का पथ और फ़ाइल नाम बदलें। और आप जाने के लिए अच्छे हैं। :)

आशा है कि यह आपकी मदद करता है। चीयर्स।


1
यह मेरे लिए काम करता है, लेकिन मुझे एनोटेशन को इस तरह से वाक्यांश करना था:@Value("#{T(java.util.Arrays).asList('${my.list.of.strings}')}")
स्टीवन

6

यदि आप नवीनतम स्प्रिंग फ्रेमवर्क संस्करण (स्प्रिंग 3.1+ मेरा मानना ​​है) का उपयोग कर रहे हैं, तो आपको स्प्रिंगेल में उन स्ट्रिंग विभाजन सामान की आवश्यकता नहीं है,

बस अपने स्प्रिंग के कॉन्फ़िगरेशन वर्ग (कॉन्फ़िगरेशन के साथ एनोटेट वाला एक) में प्रॉपर्टी स्रोतप्लानधारककंफिगर और डिफाल्टरवॉर्ससेवा जोड़ें।

@Configuration
public class AppConfiguration {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean public ConversionService conversionService() {
        return new DefaultConversionService();
    }
}

और अपनी कक्षा में

@Value("${list}")
private List<String> list;

और गुण फ़ाइल में

list=A,B,C,D,E

DefaultConversionService के बिना, आप केवल अपने क्षेत्र में मान इंजेक्ट करने पर String सरणी में String से अलग किया हुआ comma ले सकते हैं, लेकिन DefaultConversionService आपके लिए कुछ सुविधाजनक जादू करता है और उन लोगों को Collection, Array, आदि में जोड़ देगा (यदि आप चाहें तो कार्यान्वयन की जाँच करें) इसके बारे में अधिक जानना पसंद है)

इन दोनों के साथ, यह न्यूलाइन सहित सभी निरर्थक व्हाट्सएप को भी संभालता है, इसलिए आपको इन्हें ट्रिम करने के लिए अतिरिक्त लॉगिक्स जोड़ने की आवश्यकता नहीं है।


इस कॉन्फ़िगरेशन को जोड़ने पर काम हो रहा है लेकिन कुछ अजीब होता है: मैं फ़ाइल प्रकार के लिए @Value का उपयोग नहीं कर सकता, मुझे फ़ाइल को संसाधन के साथ बदलना होगा।
ad3luc

2

आप इसे इस तरह एनोटेशन के साथ कर सकते हैं

 @Value("#{T(java.util.Arrays).asList('${my.list.of.strings:a,b,c}')}") 
    private List<String> mylist;

यहाँ my.list.of.strings गुण फ़ाइल से उठाया जाएगा, अगर वहाँ नहीं है, तो चूक a, b, c का उपयोग किया जाएगा

और आपके गुण फ़ाइल में, आप कुछ इस तरह से हो सकते हैं

my.list.of.strings = डी, ई, एफ


2

मूल्यों में रिक्त स्थान से सावधान रहें। मैं गलत हो सकता हूं, लेकिन मुझे लगता है कि अल्पविराम से अलग की गई सूची में रिक्त स्थान @Value और Spel का उपयोग नहीं किया गया है। सूचि

foobar=a, b, c

तार की एक सूची के रूप में पढ़ा जाएगा

"a", " b", " c"

ज्यादातर मामलों में आप शायद रिक्त स्थान नहीं चाहेंगे!

भाव

@Value("#{'${foobar}'.trim().replaceAll(\"\\s*(?=,)|(?<=,)\\s*\", \"\").split(',')}")
private List<String> foobarList;

आप तार की एक सूची देना होगा:

"a", "b", "c".

नियमित अभिव्यक्ति कॉमा से पहले और बाद में सभी रिक्त स्थान को हटा देती है। मानों के अंदर रिक्त स्थान नहीं निकाले जाते हैं। इसलिए

foobar = AA, B B, CCC

मूल्यों में परिणत होना चाहिए

"AA", "B B", "CCC".

विभाजन () विधि आंतरिक रूप से सीमांकक के रूप में सीमांकक का उपयोग करती है, इसलिए आपका उदाहरण सरल किया जा सकता है: <br/>@Value("#{'${foobar}'.trim().split( *, *)}")
Karlik_B

2

मुझे लगता है कि यह सरणी को हथियाने और रिक्त स्थान को हटाने के लिए सरल है:

@Value("#{'${my.array}'.replace(' ', '').split(',')}")
private List<String> array;


1

कॉमन्स कॉन्फ़िगरेशन का उपयोग करने पर विचार करें। यह सरणी / सूची में गुण फ़ाइल में एक प्रविष्टि को तोड़ने के लिए सुविधा में बनाया गया है। स्पेल और @Value के साथ आकर आपको जो चाहिए वो देना चाहिए


जैसा कि अनुरोध किया गया है, यहां आपकी आवश्यकता है (वास्तव में कोड की कोशिश नहीं की गई है, कुछ टाइपो मिल सकता है, कृपया मेरे साथ सहन करें):

Apache Commons कॉन्फ़िगरेशन में PropertiesConfiguration है। यह सरणी / सूची में सीमांकित स्ट्रिंग को परिवर्तित करने की सुविधा का समर्थन करता है।

उदाहरण के लिए, यदि आपके पास एक गुण फ़ाइल है

#Foo.properties
foo=bar1, bar2, bar3

नीचे दिए गए कोड के साथ:

PropertiesConfiguration config = new PropertiesConfiguration("Foo.properties");
String[] values = config.getStringArray("foo");

आपको एक स्ट्रिंग सरणी देगा ["bar1", "bar2", "bar3"]

स्प्रिंग के साथ उपयोग करने के लिए, इसे अपने ऐप संदर्भ xml में रखें:

<bean id="fooConfig" class="org.apache.commons.configuration.PropertiesConfiguration">
    <constructor-arg type="java.lang.String" value="classpath:/Foo.properties"/>
</bean>

और अपने वसंत सेम में यह है:

public class SomeBean {

    @Value("fooConfig.getStringArray('foo')")
    private String[] fooArray;
}

मेरा मानना ​​है कि यह काम करना चाहिए: पी


क्या आप उपयोग करने की विधि और वर्ग के बारे में अधिक विशिष्ट हो सकते हैं, और वास्तविक नमूना कोड स्निपलेट महान होगा।
जैकडेव

1

मेरा पसंदीदा तरीका (स्ट्रिंग्स के लिए, विशेष रूप से), निम्नलिखित एक है:

admin.user={'Doe, John','Headroom, Max','Mouse, Micky'}

और उपयोग करें

@Value("#{${admin.user}}")
private List<String> userList;

इस तरह, आप अपने पैरामीटर में अल्पविराम भी शामिल कर सकते हैं। यह सेट्स के लिए भी काम करता है।


0

यदि संपत्ति प्लेसहोल्डर्स का उपयोग कर रहे हैं तो ser1702544 उदाहरण बन जाएगा

@Value("#{myConfigProperties['myproperty'].trim().replaceAll(\"\\s*(?=,)|(?<=,)\\s*\", \"\").split(',')}") 

प्लेसहोल्डर xml के साथ:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   
    <property name="properties" ref="myConfigProperties" />
    <property name="placeholderPrefix"><value>$myConfigProperties{</value></property>
</bean>    

<bean id="myConfigProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
     <property name="locations">
         <list>
                <value>classpath:myprops.properties</value>
         </list>
     </property>
</bean> 

0

मैं स्प्रिंग बूट 2.2.6 का उपयोग कर रहा हूं

मेरी संपत्ति फ़ाइल:

usa.big.banks= JP Morgan, Wells Fargo, Citigroup, Morgan Stanley, Goldman Sachs

मेरा कोड:

@Value("${usa.big.banks}")
    private List<String> bigBanks;

@RequestMapping("/bigbanks")
    public String getBanks() {
        System.out.println("bigBanks = " + bigBanks);
        return bigBanks.toString();
    }

यह बढ़िया काम करता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.