У меня была такая же проблема, и в настоящее время (в Dozer 5.5.x) простого способа нет, но есть и более сложный.
Обратите внимание, что в JVM не включен диспетчер безопасности, илииначе вам нужно будет добавить несколько разрешений в правила безопасности.Это связано с тем, что это решение использует отражение для доступа к закрытым полям классов Dozer.
Вам необходимо расширить 2 класса: DozerBeanMapper
и MappingProcessor
.Вам также понадобится enum для указания и интерфейса, чтобы получить направление из вышеперечисленных классов.
Перечисление:
public enum Direction {
TO,
FROM;
}
Интерфейс:
public interface DirectionAware {
Direction getDirection();
}
Расширяемый класс DozerBeanMapper
:
public class DirectionAwareDozerBeanMapper extends DozerBeanMapper implements DirectionAware {
private Direction direction;
public DirectionAwareDozerBeanMapper(Direction direction) {
super();
this.direction = direction;
}
public DirectionAwareDozerBeanMapper(Direction direction, List<String> mappingFiles) {
super(mappingFiles);
this.direction = direction;
}
@Override
protected Mapper getMappingProcessor() {
try {
Method m = DozerBeanMapper.class.getDeclaredMethod("initMappings");
m.setAccessible(true);
m.invoke(this);
} catch (NoSuchMethodException|SecurityException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e) {
// Handle the exception as you want
}
ClassMappings arg1 = (ClassMappings)getField("customMappings");
Configuration arg2 = (Configuration)getFieldValue("globalConfiguration");
CacheManager arg3 = (CacheManager)getField("cacheManager");
StatisticsManager arg4 = (StatisticsManager)getField("statsMgr");
List<CustomConverter> arg5 = (List<CustomConverter>)getField("customConverters");
DozerEventManager arg6 = (DozerEventManager)getField("eventManager");
Map<String, CustomConverter> arg7 = (Map<String, CustomConverter>)getField("customConvertersWithId");
Mapper mapper = new DirectionAwareMappingProcessor(arg1, arg2, arg3, arg4, arg5,
arg6, getCustomFieldMapper(), arg7, direction);
return mapper;
}
private Object getField(String fieldName) {
try {
Field field = DozerBeanMapper.class.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(this);
} catch (NoSuchFieldException|SecurityException|IllegalArgumentException|IllegalAccessException e) {
// Handle the exception as you want
}
return null;
}
public Direction getDirection() {
return direction;
}
}
Расширяемый класс MappingProcessor
:
public class DirectionAwareMappingProcessor extends MappingProcessor implements DirectionAware {
private Direction direction;
protected DirectionAwareMappingProcessor(ClassMappings arg1, Configuration arg2, CacheManager arg3, StatisticsManager arg4, List<CustomConverter> arg5, DozerEventManager arg6, CustomFieldMapper arg7, Map<String, CustomConverter> arg8, Direction direction) {
super(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
this.direction = direction;
}
public Direction getDirection() {
return direction;
}
}
Теперь используется.
1) Каждый раз, когда вы хотите отобразить один и тот же тип примитива(например, String-String), используйте DozerConverter
с этим типом для обоих аргументов в качестве пользовательского конвертера в файле сопоставлений бульдозера.Реализация такого конвертера должна расширять: DozerConverter<String,String>
и реализовывать MapperAware
интерфейс.Важно, чтобы у вас было MapperAware
в наличии, поскольку, имея маппер, вы сможете привести его к DirectionAware
и затем получить направление.
Например:
public class MyMapper extends DozerConverter<String, String> implements MapperAware {
private DirectionAware dirAware;
public MyMapper(Class<String> cls) {
super(cls, cls);
}
@Override
public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<String> destinationClass, Class<String> sourceClass) {
if (dirAware.getDirection() == Direction.FROM) {
// TODO convert sourceFieldValue for "FROM" direction and return it
} else {
// TODO convert sourceFieldValue for "TO" direction and return it
}
}
@Override
public void setMapper(Mapper mapper) {
dirAware = (DirectionAware)mapper;
}
}
2) Вам нужно создать 2 глобальных объекта Dozer mapper, по одному на каждое направление отображения.Они должны быть настроены с одинаковыми файлами сопоставления, но с другим аргументом направления.Например:
DirectionAwareDozerBeanMapper mapperFrom = DirectionAwareDozerBeanMapper(mappingFiles, Direction.FROM);
DirectionAwareDozerBeanMapper mapperTo = DirectionAwareDozerBeanMapper(mappingFiles, Direction.TO);
Конечно, вам нужно будет использовать правильный маппер (от / до), чтобы предоставить информацию для пользовательских мапперов, в каком направлении вы отображаете.