ssh版本不一致导致sftp连接时出现的java.io.IOException: End of IO Stream Read异常

本文介绍了一种常见情况,即客户端SSH版本为6.6,而服务端SSH版本为7.3时,进行sftp操作时出现的IOException错误。详细解释了错误原因是由于openSSH7.3默认屏蔽了部分旧版加密算法,如diffie-hellman-group1-sha1。并提供了详细的解决方案,包括如何修改服务端ssh7.3的配置文件sshd_conf,添加特定的加密算法配置,以实现版本间的兼容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

情景:

客户端ssh版本是6.6,服务端ssh版本是7.3。
sftp请求时报错ava.io.IOException: End of IO Stream Read。
后来查询得知是版本不一致导致,openSSH7.3默认屏蔽了jdk1.6支持的加密算法,如:diffie-hellman-group1-sha1等.

解决方案:

修改服务端ssh7.3中config配置,添加支持该算法的配置。
在/etc/ssh/sshd_conf或/usr/etc/sshd_conf两个文件中添加
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
记得刷新配置或重启ssh服务

启动springboot项目报错:2025-07-30 10:48:55.654 ERROR 50120 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sysDirController' defined in file [D:\0728\lowcode_api\target\classes\org\sunwoda\lowCode\api\system\SysDirController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'lpDirServiceImpl' defined in file [D:\0728\lowcode_service_impl\target\classes\org\sunwoda\lowCode\service\impl\system\impl\LpDirServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'lpDirMapper' defined in file [D:\0728\lowcode_service_impl\target\classes\org\sunwoda\lowCode\service\impl\system\mapper\LpDirMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [com/baomidou/mybatisplus/autoconfigure/MybatisPlusAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is java.io.IOException: Failed to parse mapping resource: 'file [D:\0728\lowcode_service_impl\target\classes\mapper\system\LpAppAdminDirMapper.xml]'
最新发布
07-31
<think>我们面对的是一个Spring Boot启动的依赖注入错误,错误链如下: 1. `UnsatisfiedDependencyException` 在创建 `sysDirController` ,通过构造器参数0(即`lpDirServiceImpl`)注入失败。 2. 进一步,创建`lpDirServiceImpl`,构造器参数0(即`lpDirMapper`)注入失败。 3. 创建`lpDirMapper`,其属性`sqlSessionFactory`注入失败。 4. 创建`sqlSessionFactory`失败,因为解析映射资源文件`LpAppAdminDirMapper.xml`发生了IO异常。 根据错误信息,问题核心在于MyBatis在解析XML映射文件失败。可能的原因包括: - XML文件格式错误(如标签未闭合、属性错误等) - XML文件中有支持的标签或语法 - XML文件编码问题 - 文件路径错误(但错误提示中文件路径存在,所以可能是文件内容问题) ### 解决步骤: 1. **定位问题文件**: 错误信息指出问题文件:`D:\0728\lowcode_service_impl\target\classes\mapper\system\LpAppAdminDirMapper.xml` 2. **检查XML文件内容**: 打开该文件,检查是否有明显的语法错误,例如: - 标签未正确闭合 - 使用了未定义的标签 - 特殊字符未转义(如`<`、`>`等) - 命名空间(namespace)是否正确 3. **验证XML格式**: 可以使用XML验证工具(如IDE的XML验证)或在线XML验证器检查该文件。 4. **查看具体解析错误**: Spring Boot启动日志通常会打印详细的MyBatis解析错误,但我们可以通过以下方式获取更详细的信息: - 在`application.properties`中增加MyBatis日志级别: ```properties logging.level.org.mybatis=DEBUG logging.level.org.apache.ibatis=DEBUG ``` 重新启动,查看详细错误日志。 5. **常见问题**: - **特殊字符处理**:在XML中,如`<`、`>`等需要转义为`<`、`>`。 - **SQL语句中的注释**:避免在SQL语句中使用`--`注释,可能会被误解析为XML注释结束。建议使用`<!-- -->`进行注释。 - **CDATA区域**:如果SQL语句中包含特殊字符,可以使用`<![CDATA[ ... ]]>`包裹。 ### 示例修复: 假设在`LpAppAdminDirMapper.xml`中存在如下SQL片段: ```xml <select id="selectById" resultType="com.example.Entity"> SELECT * FROM table WHERE id < 100 -- 这里的小于号是问题所在 </select> ``` 修复方法: ```xml <select id="selectById" resultType="com.example.Entity"> SELECT * FROM table WHERE id < 100 </select> ``` 或者使用CDATA: ```xml <select id="selectById" resultType="com.example.Entity"> <![CDATA[ SELECT * FROM table WHERE id < 100 ]]> </select> ``` ### 如果以上步骤无法解决问题: - 检查文件编码:确保XML文件以UTF-8编码保存(无BOM)。 - 检查文件完整性:文件是否被其他程序锁定或损坏。 - 检查MyBatis配置:在`application.properties`中检查MyBatis的配置项,如: ```properties mybatis.mapper-locations=classpath:mapper/**/*.xml ``` 确保路径匹配。 ### 代码示例:捕获MyBatis初始化异常 虽然能直接解决该问题,但我们可以编写一个初始化检查类来提前捕获映射文件错误: ```java import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class MyBatisStartupValidator implements CommandLineRunner { @Autowired private SqlSessionFactory sqlSessionFactory; @Override public void run(String... args) { // 尝试获取配置,如果配置有错误会抛出异常 sqlSessionFactory.getConfiguration().getMappedStatementNames(); System.out.println("MyBatis映射文件检查通过"); } } ``` 这样可以在启动立即发现映射文件问题,但注意这个检查会触发所有映射文件的加载。 ### 总结问题原因: 根本原因是MyBatis在解析指定的XML映射文件遇到语法错误,导致`SqlSessionFactory`创建失败,进而引发一连串的依赖注入失败。 --- §§相关问题§§: 1. Spring Boot中如何配置MyBatis的XML映射文件路径? 2. MyBatis映射文件中常见的XML语法错误有哪些? 3. 如何解决MyBatis中特殊字符(如<, >)在XML中的转义问题? 4. 除了XML文件错误,还有哪些原因会导致`SqlSessionFactory`创建失败?</think>### Spring Boot 启动错误分析与解决方案 #### 错误分析 错误链揭示了核心问题: ```plaintext Caused by: java.io.IOException: Failed to parse mapping resource: 'file [D:\0728\lowcode_service_impl\target\classes\mapper\system\LpAppAdminDirMapper.xml]' ``` 这是典型的 **MyBatis XML 映射文件解析失败** 问题,常见原因包括: 1. **XML 语法错误** - 标签未闭合(如 `<select>` 缺少 `</select>`) - 属性值未加引号(如 `parameterType=com.example.Entity`) - 特殊字符未转义(如 SQL 中的 `<`, `>`) 2. **MyBatis 配置问题** - 无效的 MyBatis 标签(如使用了未声明的标签) - 错误的命名空间(namespace)定义 - 结果映射(resultMap)配置错误 3. **资源路径问题** - XML 文件未正确复制到 target 目录 - Maven 未正确过滤资源文件 #### 解决方案步骤 ##### 1. 检查 XML 文件语法(关键步骤) 打开问题文件:`LpAppAdminDirMapper.xml` **常见错误示例:** ```xml <!-- 错误示例1:标签未闭合 --> <select id="getUser" parameterType="int" SELECT * FROM users WHERE id = #{id} <!-- 缺少 </select> --> <!-- 错误示例2:特殊字符未转义 --> <select id="findByAge"> SELECT * FROM users WHERE age < 25 <!-- 应改为 < --> </select> <!-- 错误示例3:无效标签 --> <insert id="addUser"> <invalidTag/> <!-- 非MyBatis标准标签 --> INSERT INTO users... </insert> ``` ##### 2. 验证 XML 文件位置 确保文件在正确位置: ```bash 项目结构: lowcode_service_impl └── src └── main └── resources └── mapper └── system └── LpAppAdminDirMapper.xml # 源文件位置 # 编译后应出现在: target/classes/mapper/system/LpAppAdminDirMapper.xml ``` ##### 3. 添加 Maven 资源过滤配置 在 `pom.xml` 中确保 XML 文件被包含: ```xml <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>true</filtering> </resource> </resources> </build> ``` ##### 4. 启用 MyBatis 详细日志 在 `application.properties` 中添加: ```properties # 开启MyBatis详细日志 logging.level.org.mybatis=DEBUG logging.level.org.apache.ibatis=TRACE # 显示SQL语句 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl ``` ##### 5. 验证修复的 XML 示例 ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="org.sunwoda.lowCode.service.impl.system.mapper.LpDirMapper"> <!-- 正确的结果映射 --> <resultMap id="BaseResultMap" type="org.sunwoda.lowCode.entity.LpDir"> <id column="id" property="id" jdbcType="BIGINT"/> <result column="dir_name" property="dirName" jdbcType="VARCHAR"/> </resultMap> <!-- 正确的查询语句 --> <select id="selectById" resultMap="BaseResultMap"> SELECT * FROM lp_dir WHERE id = #{id} AND create_time < NOW() <!-- 特殊字符转义 --> </select> </mapper> ``` #### 根本原因说明 该错误发生在 Spring Boot 启动的生命周期阶段: 1. **依赖注入阶段**:尝试创建 `sysDirController` Bean 2. **依赖解析**:需要注入 `lpDirServiceImpl` 3. **Mapper 创建**:`lpDirMapper` 需要 MyBatis 的 `SqlSessionFactory` 4. **XML 解析失败**:`SqlSessionFactory` 初始化解析 XML 映射文件失败 #### 预防措施 1. **IDE 验证**:在 IDE 中打开 XML 文件验证语法(如 IntelliJ 会标记错误) 2. **构建前检查**:添加 Maven XML 验证插件 ```xml <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>xml-maven-plugin</artifactId> <version>1.0.2</version> <executions> <execution> <goals> <goal>validate</goal> </goals> </execution> </executions> </plugin> ``` 3. **单元测试**:添加 MyBatis Mapper 的单元测试 ```java @SpringBootTest class LpDirMapperTest { @Autowired private LpDirMapper lpDirMapper; @Test void testSelectById() { LpDir dir = lpDirMapper.selectById(1L); assertNotNull(dir); } } ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EmineWang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值