使用ZipEntry解压zip文件报错: java.lang.IllegalArgumentException: MALFORMED

文章目录

场景

使用ZipEntry解压zip文件报错:  java.lang.IllegalArgumentException: MALFORMED  

分析

压缩文件中含有中文, 在ZipCoder调用toString函数报错。此处识别成了utf8,
所以 在解压时设置成gbk字符集就行了
String toString(byte[] ba, int length) {
        CharsetDecoder cd = decoder().reset();
        int len = (int)(length * cd.maxCharsPerByte());
        char[] ca = new char[len];
        if (len == 0)
            return new String(ca);
        // UTF-8 only for now. Other ArrayDeocder only handles
        // CodingErrorAction.REPLACE mode. ZipCoder uses
        // REPORT mode.
        // 这里是报错位置
        if (isUTF8 && cd instanceof ArrayDecoder) {
            int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca);
            if (clen == -1)    // malformed
                throw new IllegalArgumentException("MALFORMED");
            return new String(ca, 0, clen);
        }
        ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
        CharBuffer cb = CharBuffer.wrap(ca);
        CoderResult cr = cd.decode(bb, cb, true);
        if (!cr.isUnderflow())
            throw new IllegalArgumentException(cr.toString());
        cr = cd.flush(cb);
        if (!cr.isUnderflow())
            throw new IllegalArgumentException(cr.toString());
        return new String(ca, 0, cb.position());
    }

解决

ZipFile zf = new ZipFile(file, Charset.forName(“gbk”));

    /**
     * 解压文件
     * */
    @Override
    public void unZip(String srcPath, String dest) throws IOException {

        File file = new File(srcPath);
        if (!file.exists()) {
            throw new RuntimeException(srcPath + "所指文件不存在");
        }
        ZipFile zf = new ZipFile(file, Charset.forName("gbk"));
        Enumeration entries = zf.entries();
        ZipEntry entry = null;
        while (entries.hasMoreElements()) {
            entry = (ZipEntry) entries.nextElement();
            System.out.println("解压" + entry.getName());
            if (entry.isDirectory()) {
                String dirPath = dest + File.separator + entry.getName();
                Path path = Paths.get(dirPath);
                Files.createDirectories(path);

            } else {
                // 表示文件
                File f = new File(dest + File.separator + entry.getName());
                if (!f.exists()) {
                    String dirs = f.getParent();
                    Path path = Paths.get(dirs);
                    Files.createDirectories(path);
                }
                f.createNewFile();
                // 将压缩文件内容写入到这个文件中
                InputStream is = zf.getInputStream(entry);
                FileOutputStream fos = new FileOutputStream(f);
                int count;
                byte[] buf = new byte[8192];
                while ((count = is.read(buf)) != -1) {
                    fos.write(buf, 0, count);
                }
                is.close();
                fos.close();
            }
        }
    }
Spring Boot 3.x中配置多数据源后启动应用时,如果遇到 `java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String` 异常,通常是由于 MyBatis Plus 与 Spring Boot 3.x 的兼容性问题导致的。 具体来说,该异常的核心原因是 `factoryBeanObjectType` 属性的值类型不正确。在 Spring Boot 3.2 版本中,`FactoryBeanRegistrySupport#getTypeForFactoryBeanFromAttributes` 方法进行了变更,要求 `factoryBeanObjectType` 必须是 `ResolvableType` 或 `Class` 类型。然而,某些版本的 `mybatis-plus-boot-starter` 或 `mybatis-spring` 将 `factoryBeanObjectType` 设置为 `String` 类型,从而导致不兼容问题[^2]。 以下是可能的原因及解决方案: ### 原因分析 1. **依赖版本不匹配**: - 如果使用了 `mybatis-plus-boot-starter` 的版本较低(如 3.5.3.1 或 3.5.5),它默认依赖的 `mybatis-spring` 版本为 2.0.2 或 2.1.1,这些版本与 Spring Boot 3.x 不兼容。 - Spring Boot 3.x 要求 `mybatis-spring` 版本至少为 3.0.0 以上,以支持新的 `FactoryBeanRegistrySupport` 行为。 2. **错误的 Starter 依赖**: - 在 Spring Boot 3.x 项目中错误地引入了面向 Spring Boot 2.x 的 `mybatis-plus-boot-starter`,而没有使用专为 Spring Boot 3.x 设计的 `mybatis-plus-spring-boot3-starter`。 ### 解决方案 #### 方案 1:使用专为 Spring Boot 3.x 设计的 Starter 推荐使用 `mybatis-plus-spring-boot3-starter`,该依赖专为 Spring Boot 3.x 设计,避免了与 `factoryBeanObjectType` 相关的兼容性问题。 ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-spring-boot3-starter</artifactId> <version>3.5.7</version> </dependency> ``` #### 方案 2:排除旧版 mybatis-spring 并手动指定新版 如果必须使用 `mybatis-plus-boot-starter`(如 3.5.5 或更高版本),可以通过排除其自带的 `mybatis-spring` 依赖,并手动引入兼容 Spring Boot 3.x 的 `mybatis-spring` 3.0.3 或以上版本。 ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.5</version> <exclusions> <exclusion> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </exclusion> </exclusions> </dependency> <!-- 手动引入兼容 Spring Boot 3.x 的 mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.3</version> </dependency> ``` #### 方案 3:检查多数据源配置是否正确 在配置多数据源时,确保每个数据源的 `SqlSessionFactory` 和 `MapperScannerConfigurer` 都被正确配置,并且没有重复或冲突的 Bean 定义。例如,确保每个数据源都有独立的 `@MapperScan` 注解,并指向不同的 Mapper 包。 ```java @Configuration @MapperScan(basePackages = "com.example.mapper.datasource1", sqlSessionFactoryRef = "dataSource1SqlSessionFactory") public class DataSource1Config { // 配置数据源1的 SqlSessionFactory } ``` ### 总结 `factoryBeanObjectType` 报错的根本原因是 `mybatis-spring` 版本与 Spring Boot 3.x 不兼容,或者错误地使用了面向 Spring Boot 2.x 的依赖。通过升级到 `mybatis-plus-spring-boot3-starter` 或手动排除并引入兼容的 `mybatis-spring` 版本,可以有效解决该问题[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值