/ / वसंत में दो-तरफ़ा कनवर्टर - जावा, वसंत -3

वसंत में दो-तरफ़ा कनवर्टर - जावा, वसंत -3

स्प्रिंग 3 में टाइप रूपांतरण के रूप में इतनी अच्छी सुविधा है। यह एक कनवर्टर SPI प्रदान करता है (Converter<S, T>) का उपयोग डिफरेंसेट रूपांतरण को लागू करने के लिए किया जाता हैतर्क। कनवर्टर प्रकार का उपवर्ग एक-तरफा रूपांतरण (केवल S से T तक) को परिभाषित करने की अनुमति देता है, इसलिए यदि मैं चाहता हूं कि एक रूपांतरण भी T से S तक किया जाए तो मुझे एक और कनवर्टर वर्ग को परिभाषित करना होगा जो लागू हो Converter<T, S>। अगर मेरे पास कई कक्षाएं हैं जो विषय हैंरूपांतरण, मुझे कई कन्वर्टर्स को परिभाषित करने की आवश्यकता है। क्या एक कनवर्टर में दो-तरफा रूपांतरण तर्क (एस से टी और टी से एस तक) को परिभाषित करने के लिए कोई सकारात्मकता है? और इसका उपयोग कैसे किया जाएगा?

पुनश्च। अब मैं के माध्यम से अपने कन्वर्टर्स का उपयोग कर रहा हूँ ConversionServiceFactoryBean कॉन्फ़िगरेशन फ़ाइल में उन्हें परिभाषित / इंजेक्ट करना

उत्तर:

जवाब के लिए 8 № 1

आप सही हैं, यदि आप का उपयोग करना चाहते हैं org.springframework.core.convert.converter.Converter इंटरफ़ेस सीधे, आपको "दो कन्वर्टर्स को लागू करने की आवश्यकता होगी, प्रत्येक दिशा के लिए एक।

लेकिन वसंत 3 में कुछ अन्य विकल्प हैं:

  1. यदि आपका रूपांतरण ऑब्जेक्ट-टू-ऑब्जेक्ट नहीं है, बल्कि ऑब्जेक्ट-टू-स्ट्रिंग (और बैक) है, तो आप ए लागू कर सकते हैं org.springframework.format.Formatter बजाय। फ़ॉर्मेटर्स जेनरिककोवर्टर्स (देखें) के रूप में पंजीकृत होते हैं http://static.springsource.org/spring-webflow/docs/2.3.x/reference/html/ch05s07.html#converter-upgrade-to-spring-3)

  2. अन्यथा आप अपना खुद का क्रियान्वयन कर सकते थे org.springframework.core.convert.converter.GenericConverter, जो प्रतिबिंब का उपयोग करके TwoWayConverter कार्यान्वयन बनाना आसान बनाता है।

    public abstract class AbstractTwoWayConverter<S, T> implements GenericConverter {
    
    private Class<S> classOfS;
    private Class<T> classOfT;
    
    protected AbstractTwoWayConverter() {
    Type typeA = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    Type typeB = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
    this.classOfS = (Class) typeA;
    this.classOfT = (Class) typeB;
    }
    
    public Set<ConvertiblePair> getConvertibleTypes() {
    Set<ConvertiblePair> convertiblePairs = new HashSet<ConvertiblePair>();
    convertiblePairs.add(new ConvertiblePair(classOfS, classOfT));
    convertiblePairs.add(new ConvertiblePair(classOfT, classOfS));
    return convertiblePairs;
    }
    
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
    if (classOfS.equals(sourceType.getType())) {
    return this.convert((S) source);
    } else {
    return this.convertBack((T) source);
    }
    }
    
    protected abstract T convert(S source);
    
    protected abstract S convertBack(T target);
    
    }
    
    /**
    * converter to convert between a userId and user.
    * this class can be registered like so:
    * conversionService.addConverter(new UserIdConverter (userDao));
    */
    public class UserIdConverter extends AbstractTwoWayConverter<String, User> {
    
    private final UserDao userDao;
    
    @Autowired
    public UserIdConverter(UserDao userDao) {
    this.userDao = userDao;
    }
    
    @Override
    protected User convert(String userId) {
    return userDao.load(userId);
    }
    
    @Override
    protected String convertBack(User target) {
    return target.getUserId();
    }
    }
    

जवाब के लिए 2 № 2

स्प्रिंग का इस उद्देश्य के लिए सिर्फ एक इंटरफ़ेस है: TwoWayConverter। निम्नलिखित देखें: http://static.springsource.org/spring-webflow/docs/2.0.x/javadoc-api/org/springframework/binding/convert/converters/TwoWayConverter.html


जवाब के लिए 0 № 3

आप उपयोग कर सकते हैं स्प्रिंग फॉर्मेटर स्ट्रिंग और इसके विपरीत टाइप टी का प्रारूप वस्तु।

package org.springframework.format;

public interface Formatter<T> extends Printer<T>, Parser<T> {
}

इस इंटरफ़ेस का उपयोग करके आप इसे प्राप्त कर सकते हैंबैरी पिटमैन कहते हैं, लेकिन कम कोड के साथ और यह स्प्रिंग डॉक्यूमेंटेशन का बेहतर तरीका है यदि आप स्ट्रिंग और इसके विपरीत फॉर्मेट करते हैं। तो बैरी का UserIdConverter वर्ग इस तरह दिखने वाला है:

public class UserIdConverter implements Formatter<User> {

private final UserDao userDao;

@Autowired
public UserIdConverter(UserDao userDao) {
this.userDao = userDao;
}

@Override
public User parse(String userId, Locale locale) {
return userDao.load(userId);
}

@Override
public String print(User target, Locale locale) {
return target.getUserId();
}
}

इस प्रारूप को पंजीकृत करने के लिए आपको इसे अपने XML कॉन्फ़िगरेशन में शामिल करना चाहिए:

...
<mvc:annotation-driven conversion-service="conversionService"/>

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" >
<property name="formatters">
<set>
<bean class="com.x.UserIdConverter"/>
</set>
</property>
</bean>
...

! ध्यान दें कि इस वर्ग के लिए ही इस्तेमाल किया जा सकता हैकुछ प्रकार टी से स्ट्रिंग और इसके विपरीत स्वरूपण। आप उदाहरण के लिए T से कुछ अन्य प्रकार T1 से प्रारूपित नहीं कर सकते। यदि आपके पास यह मामला है तो आपको स्प्रिंग जेनेरिक कनेक्टर के साथ जाना चाहिए और बैरी पिटमैन जवाब का उपयोग करना चाहिए:

public abstract class AbstractTwoWayConverter<S, T> implements GenericConverter {

private Class<S> classOfS;
private Class<T> classOfT;

protected AbstractTwoWayConverter() {
Type typeA = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Type typeB = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
this.classOfS = (Class) typeA;
this.classOfT = (Class) typeB;
}

public Set<ConvertiblePair> getConvertibleTypes() {
Set<ConvertiblePair> convertiblePairs = new HashSet<ConvertiblePair>();
convertiblePairs.add(new ConvertiblePair(classOfS, classOfT));
convertiblePairs.add(new ConvertiblePair(classOfT, classOfS));
return convertiblePairs;
}

public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (classOfS.equals(sourceType.getType())) {
return this.convert((S) source);
} else {
return this.convertBack((T) source);
}
}

protected abstract T convert(S source);

protected abstract S convertBack(T target);

}

/**
* converter to convert between a userId and user.
* this class can be registered like so:
* conversionService.addConverter(new UserIdConverter (userDao));
*/
public class UserIdConverter extends AbstractTwoWayConverter<String, User> {

private final UserDao userDao;

@Autowired
public UserIdConverter(UserDao userDao) {
this.userDao = userDao;
}

@Override
protected User convert(String userId) {
return userDao.load(userId);
}

@Override
protected String convertBack(User target) {
return target.getUserId();
}
}

और अपने XML कॉन्फ़िगरेशन में जोड़ें:

...
<mvc:annotation-driven conversion-service="conversionService"/>

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" >
<property name="converters">
<set>
<bean class="com.x.y.UserIdConverter"/>
</set>
</property>
</bean>
...