Spring 3 has such a nice feature as type conversion. It provides a converter SPI(Converter<S, T>
) to be used to implement differenet conversion logic.
The subclass of Converter type allow to define one-way conversion(only from S to T), so if I want a conversion also to be performed from T to S I need to define another converter class that implement Converter<T, S>
. If I have many classes which are subject to conversion, i need to define many converters.
Is there any posibility to define two-way conversion logic(from S to T and from T to S) in one converter? and how it will be used?
PS. now I'm using my converters via ConversionServiceFactoryBean
defining/injecting them in configuration file
Spring provides out-of-the-box various converters for built-in types; this means converting to/from basic types like String, Integer, Boolean and a number of other types. Apart from this, Spring also provides a solid type conversion SPI for developing our custom converters.
Class MappingJackson2HttpMessageConverter. Implementation of HttpMessageConverter that can read and write JSON using Jackson 2. x's ObjectMapper . This converter can be used to bind to typed beans, or untyped HashMap instances.
HttpMessageConverter is a strategy interface that specifies a converter that can convert from and to HTTP requests and responses in Spring REST Restful web services. Internally Spring MVC uses it to convert the Http request to an object representation and back.
Method SummaryReturn true if objects of sourceType can be converted to the targetType . Return true if objects of sourceType can be converted to the targetType . Convert the given source to the specified targetType . Convert the given source to the specified targetType .
You are correct, if you want to use the org.springframework.core.convert.converter.Converter
interface directly, you'll need to implement two converters, one for each direction.
But spring 3 has a couple of other options:
If your conversion is not object-to-object but rather object-to-string (and back), then you can implement a org.springframework.format.Formatter
instead. Formatters get registered as GenericConverters (see http://static.springsource.org/spring-webflow/docs/2.3.x/reference/html/ch05s07.html#converter-upgrade-to-spring-3)
Otherwise you could implement your own org.springframework.core.convert.converter.GenericConverter
, which makes it easy to create TwoWayConverter implementations using reflection.
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With