Servlet导入CSV至Oracle触发java.lang.NullPointerException问题排查
CSV导入Oracle Servlet空指针异常排查与修复
你遇到的java.lang.NullPointerException是因为代码里的csvfile变量可能没有被正确赋值就被调用了,咱们一步步拆解问题,然后修复代码:
错误原因分析
从报错信息看,异常出现在GreetingServlet.java:56,对应代码里的InputStreamReader isr = new InputStreamReader(csvfile);这一行——这说明csvfile是null。
导致这个问题的核心原因:
- 你用
upload.parseParameterMap(request)获取文件项,但如果没有上传文件、或者表单字段不符合要求,循环里的csvfile = uploadItem.getInputStream();根本不会执行,csvfile保持初始的null值 - 代码没有判断
uploadItem是否是文件项(可能是普通表单字段),也没有校验文件类型 - 数据库连接和文件流没有正确关闭,会导致资源泄漏
- 简单用
split(",")处理CSV,若字段本身包含逗号会分割错误
修复后的完整代码
package org.exercise01.web; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * Servlet implementation class GreetingServlet */ @WebServlet("/GreetingServlet") public class GreetingServlet extends HttpServlet { private static final long serialVersionUID = 1L; public GreetingServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().append("Served at: ").append(request.getContextPath()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); // 先校验是否是文件上传请求 if (!ServletFileUpload.isMultipartContent(request)) { out.println("请通过文件上传表单提交CSV!"); return; } try { InputStream csvfile = null; FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); List<FileItem> items = upload.parseRequest(request); // 遍历文件项,找到有效的CSV文件 for (FileItem uploadItem : items) { if (!uploadItem.isFormField()) { String fileName = uploadItem.getName(); if (fileName != null && fileName.toLowerCase().endsWith(".csv")) { csvfile = uploadItem.getInputStream(); break; // 只处理第一个CSV文件 } else { out.println("请上传CSV格式的文件!"); return; } } } // 校验是否获取到有效文件流 if (csvfile == null) { out.println("未找到有效的CSV文件,请重新上传!"); return; } InputStreamReader isr = new InputStreamReader(csvfile); BufferedReader reader = new BufferedReader(isr); reader.readLine(); // 跳过表头行 // 数据库操作:使用PreparedStatement防止SQL注入,统一管理资源 Connection con = null; PreparedStatement pstmt = null; try { Class.forName("oracle.jdbc.driver.OracleDriver"); con = DriverManager.getConnection("jdbc:oracle:thin:@//10.250.173.103:1521/optunai", "TUNAIREPORT", "TUNAIREPORT#2015"); String query = "insert into csvfile(name,mail) values(?, ?)"; pstmt = con.prepareStatement(query); String text; while ((text = reader.readLine()) != null) { String[] columns = text.split(","); // 校验列数是否符合表结构 if (columns.length != 2) { System.out.println("跳过格式错误的行:" + text); continue; } pstmt.setString(1, columns[0].trim()); pstmt.setString(2, columns[1].trim()); pstmt.executeUpdate(); } out.println("CSV数据成功导入数据库!"); } catch (Exception e) { out.println("数据库操作失败:" + e.getMessage()); e.printStackTrace(); } finally { // 关闭数据库资源,避免连接泄漏 try { if (pstmt != null) pstmt.close(); if (con != null) con.close(); } catch (Exception e) { e.printStackTrace(); } // 关闭文件流 reader.close(); isr.close(); csvfile.close(); } } catch (Exception e) { out.println("文件上传处理失败:" + e.getMessage()); e.printStackTrace(); } } }
关键修复点说明
- 空指针预防:添加请求类型校验、文件流非空判断,确保只有获取到有效文件才继续执行
- 文件合法性校验:判断上传文件是否为CSV格式,避免无效文件
- 资源安全:在
finally块中统一关闭数据库连接、文件流,彻底避免资源泄漏 - SQL注入防护:用
PreparedStatement替代字符串拼接SQL,杜绝注入风险 - 容错处理:校验每行数据的列数,跳过格式错误的行,避免批量导入失败
进阶优化建议
- 使用专业CSV解析库(如OpenCSV)处理包含逗号、引号的复杂CSV字段
- 配置数据库连接池(如Apache DBCP),提升连接复用率和系统稳定性
- 添加文件大小限制,防止超大文件占用服务器资源
内容的提问来源于stack exchange,提问作者Ken Kaneki
相关产品推荐
相关产品推荐

