You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:22:05