使用Dozer映射二维字节数组时遇数组元素类型不匹配异常求助
解决Dozer映射二维byte数组时的
array element type mismatch异常 我之前也踩过Dozer处理多维数组的坑,这个异常的根源是Dozer默认的数组映射逻辑无法正确识别二维数组的嵌套类型——它会把二维byte[][]当成一维数组来处理,尝试逐个转换元素,但实际上二维数组的元素本身是byte[]数组,Dozer的默认转换逻辑在这里出现了类型匹配错误,所以抛出了java.lang.IllegalArgumentException: array element type mismatch。
下面给你两个可行的解决办法:
办法一:自定义Dozer转换器(推荐)
编写一个专门处理byte[][]的自定义转换器,明确告诉Dozer如何正确复制二维字节数组:
1. 实现Dozer的Converter接口
import org.dozer.DozerConverter; public class Byte2DArrayConverter extends DozerConverter<byte[][], byte[][]> { public Byte2DArrayConverter() { super(byte[][].class, byte[][].class); } @Override public byte[][] convertTo(byte[][] source, byte[][] destination) { if (source == null) { return null; } // 深拷贝二维byte数组,避免原数组修改影响DTO byte[][] result = new byte[source.length][]; for (int i = 0; i < source.length; i++) { if (source[i] != null) { result[i] = source[i].clone(); } } return result; } @Override public byte[][] convertFrom(byte[][] source, byte[][] destination) { // 双向映射逻辑一致,直接复用convertTo的代码 return convertTo(source, destination); } }
2. 在Dozer映射文件中配置该转换器
修改你的映射文件,给columns字段指定自定义转换器:
<mapping map-id="i" wildcard="false"> <class-a>com.csinfra.jdbmon.web.client.dto.Config.HostGroups.HostGroup.CheckGroup.Check.Type.MultiResult</class-a> <class-b>com.csinfra.jdbmon.web.client.dto.MultiResultDTO</class-b> <field> <a>id</a> <b>id</b> </field> <field custom-converter="com.yourpackage.Byte2DArrayConverter"> <a>columns</a> <b>columns</b> </field> </mapping>
记得把com.yourpackage替换成你实际存放转换器的包路径。
办法二:手动跳过该字段的自动映射
如果不想编写自定义转换器,可以让Dozer跳过columns字段的自动映射,手动处理数组复制:
1. 修改映射文件,排除columns字段
<mapping map-id="i" wildcard="false"> <class-a>com.csinfra.jdbmon.web.client.dto.Config.HostGroups.HostGroup.CheckGroup.Check.Type.MultiResult</class-a> <class-b>com.csinfra.jdbmon.web.client.dto.MultiResultDTO</class-b> <field> <a>id</a> <b>id</b> </field> <!-- 不再配置columns字段,让Dozer自动跳过它 --> </mapping>
2. 手动复制二维数组
在代码完成基础字段映射后,单独处理columns字段:
// 先用Dozer映射其他字段 MultiResultDTO dto = dozerMapper.map(entity, MultiResultDTO.class, "i"); // 手动深拷贝二维byte数组 byte[][] sourceColumns = entity.getColumns(); if (sourceColumns != null) { byte[][] destColumns = new byte[sourceColumns.length][]; for (int i = 0; i < sourceColumns.length; i++) { if (sourceColumns[i] != null) { destColumns[i] = sourceColumns[i].clone(); } } dto.setColumns(destColumns); }
异常原因补充
从堆栈信息可以看到,异常发生在org.dozer.MappingProcessor.addToPrimitiveArray方法中,Dozer错误地将二维数组的元素(byte[])当成了原始byte类型来处理,调用java.lang.reflect.Array.set时出现类型不匹配。这是Dozer对多维数组支持的局限性,需要我们通过自定义逻辑来规避。
内容的提问来源于stack exchange,提问作者user2683906
相关产品推荐
相关产品推荐

