SpringMVC + Kindeditor时List items = upload.parseRequest(request);为空

解决Kindeditor与SpringMVC整合中文件上传问题
本文详细介绍了在使用Kindeditor进行文件上传时遇到的问题及解决方法,涉及SpringMVC配置、文件保存目录、文件类型检查、大小限制等关键步骤。通过调整配置文件中的参数,最终成功实现Kindeditor与SpringMVC的无缝整合。

问题描述: 根据Kindeditor给的demo,结合SpringMVC使用时,

List items = upload.parseRequest(request);
item始终为空。

@Controller
@IfNeedLogin(needLogin = false)
@RequestMapping("/kindeditor")
public class KEUploadController extends BaseController {

	private Logger logger = LoggerFactory.getLogger(KEUploadController.class);

	@RequestMapping(value = "/upload", method = { RequestMethod.GET,
			RequestMethod.POST })
	public void upload(HttpServletRequest request, HttpServletResponse response)
			throws FileUploadException, IOException {
		logger.debug("Kindeditor上传文件");
		PrintWriter writer = response.getWriter();
		ServletContext servletContext = request.getSession()
				.getServletContext();

		// 文件保存目录路径
		String savePath = servletContext.getRealPath("/") + "attached/";

		// 文件保存目录URL
		String saveUrl = request.getContextPath() + "/attached/";

		// 定义允许上传的文件扩展名
		HashMap<String, String> extMap = new HashMap<String, String>();
		extMap.put("image", "gif,jpg,jpeg,png,bmp");
		extMap.put("flash", "swf,flv");
		extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
		extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");

		// 最大文件大小
		long maxSize = 1000000;

		response.setContentType("text/html; charset=UTF-8");

		if (!ServletFileUpload.isMultipartContent(request)) {
			writer.println(getError("请选择文件。"));
			return;
		}
		// 检查目录
		File uploadDir = new File(savePath);
		if (!uploadDir.isDirectory()) {
			writer.println(getError("上传目录不存在。"));
			return;
		}
		// 检查目录写权限
		if (!uploadDir.canWrite()) {
			writer.println(getError("上传目录没有写权限。"));
			return;
		}

		String dirName = request.getParameter("dir");
		if (dirName == null) {
			dirName = "image";
		}
		if (!extMap.containsKey(dirName)) {
			writer.println(getError("目录名不正确。"));
			return;
		}
		// 创建文件夹
		savePath += dirName + "/";
		saveUrl += dirName + "/";
		File saveDirFile = new File(savePath);
		if (!saveDirFile.exists()) {
			saveDirFile.mkdirs();
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String ymd = sdf.format(new Date());
		savePath += ymd + "/";
		saveUrl += ymd + "/";
		File dirFile = new File(savePath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}

		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("UTF-8");
		List items = upload.parseRequest(request);
		Iterator itr = items.iterator();
		while (itr.hasNext()) {
			FileItem item = (FileItem) itr.next();
			String fileName = item.getName();
			long fileSize = item.getSize();
			if (!item.isFormField()) {
				// 检查文件大小
				if (item.getSize() > maxSize) {
					writer.println(getError("上传文件大小超过限制。"));
					return;
				}
				// 检查扩展名
				String fileExt = fileName.substring(
						fileName.lastIndexOf(".") + 1).toLowerCase();
				if (!Arrays.<String> asList(extMap.get(dirName).split(","))
						.contains(fileExt)) {
					writer.println(getError("上传文件扩展名是不允许的扩展名。\n只允许"
							+ extMap.get(dirName) + "格式。"));
					return;
				}

				SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
				String newFileName = df.format(new Date()) + "_"
						+ new Random().nextInt(1000) + "." + fileExt;
				try {
					File uploadedFile = new File(savePath, newFileName);
					item.write(uploadedFile);
				} catch (Exception e) {
					writer.println(getError("上传文件失败。"));
					return;
				}

				JSONObject obj = new JSONObject();
				obj.put("error", 0);
				obj.put("url", saveUrl + newFileName);
				writer.println(obj.toJSONString());
			}
		}
	}

	private String getError(String message) {
		JSONObject obj = new JSONObject();
		obj.put("error", 1);
		obj.put("message", message);
		return obj.toJSONString();
	}

}

解决方案1:

去掉配置文件:

	 <!-- 上传文件时需要做的配置 -->  
<!--     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <property name="maxUploadSize" value="5000000"></property>
        <property name="maxInMemorySize" value="4096" />  
    	<property name="defaultEncoding" value="UTF-8" />  
    </bean> -->

<think>好的,我现在要解决用户关于ServletFileUpload.parseRequest(request)报错的问题。用户之前已经提过这个问题,现在又补充了一些站内引用,我需要结合这些引用和之前的回答来给出更准确的解决方案。 首先,用户这次的引用提到几个关键点:本地环境正常但Linux服务器报错,解析请求后再次解析为,以及在Spring Boot中使用的问题。这可能涉及环境差异、多次解析请求、配置问题等。 回顾之前的回答,我提到了参数类型不匹配和错误使用底层类的问题,并建议使用ServletFileUpload来替代FileUploadBase。现在需要整合新的引用内容,特别是引用2提到的多次解析导致数据的问题,以及引用3中在Spring Boot中的处理方式。 用户现在想知道错误的具体原因和解决方案。需要分析可能的错误原因,比如多次解析、配置不一致、环境差异、依赖版本问题等。结合引用2,多次解析会导致请求流被消费,无法再次读取,这点很重要。引用3提到在Spring Boot中可能需要使用ServletRequestContext,这可能是因为框架处理请求的方式不同。 接下来要组织回答结构,分点说明原因和对应的解决方案。需要确保涵盖所有引用中提到的问题,比如环境配置、多次解析、依赖冲突、Spring Boot的特殊处理等。同,要提供具体的代码示例和配置建议,比如检查依赖版本、配置参数、避免多次解析等。 还要注意用户可能是在不同环境下遇到问题,比如本地和服务器环境差异,需要检查依赖版本是否一致,配置文件是否正确。此外,在Spring MVC或Spring Boot中,可能有框架自身的处理机制,导致需要调整解析方式,比如使用CommonsMultipartResolver或避免多次解析。 最后,生成相关问题要覆盖用户可能遇到的其他问题,比如配置参数、大小限制、依赖冲突排查等。确保回答清晰,结构合理,帮助用户全面理解问题并解决。</think>#### 深度解析:`ServletFileUpload.parseRequest(request)`错误原因及解决方案 --- ### 一、核心错误原因分析 结合引用内容和实际开发场景,`parseRequest`报错主要涉及以下4类根本原因: 1. **请求流重复消费 (关键原因)** - **引用[2]明确说明**:HttpServletRequest的输入流只能被读取一次,若框架层(如SpringMVC)或开发者代码已调用过`parseRequest`,二次解析必然失败[^2] - **典型场景**:同使用原生ServletFileUpload和Spring的`@RequestParam`接收文件 2. **环境配置差异** - **引用[1]中的现象**:本地正常但服务器异常,常见于: - 服务器缺少`commons-fileupload`依赖或版本不一致 - 服务器未正确配置临目录写入权限 $$ \text{Linux权限问题示例}:chmod -R 777 /tmp/upload\_cache $$ 3. **请求未正确封装** - **引用[3]的解决方案**:在Spring Boot等现代框架中,需使用`ServletRequestContext`封装请求对象 ```java // Spring Boot特殊处理 List<FileItem> items = upload.parseRequest(new ServletRequestContext(request)); ``` 4. **配置参数缺失** ```java // 必须设置内存缓冲区与临目录 DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(1024*1024); // 1MB内存缓冲 factory.setRepository(new File("/tmp/uploads")); ``` --- ### 二、分步解决方案 #### 步骤1:确认请求仅解析一次 | 错误模式 | 修正方案 | |---------|----------| | ```java // Controller中混合使用 List<FileItem> items = upload.parseRequest(request); @RequestParam("file") MultipartFile file // 冲突! ``` | **方案一**:完全使用ServletFileUpload解析 **方案二**:完全使用Spring的MultipartFile接收 | #### 步骤2:环境一致性检查 ```bash # Linux服务器验证步骤 ls -l $TOMCAT_HOME/lib/commons-fileupload-*.jar # 检查jar存在性 df -h /tmp # 检查磁盘间 ulimit -a | grep openfiles # 检查文件句柄限制 ``` #### 步骤3:完整配置示例(Spring Boot) ```java @Bean public MultipartConfigElement multipartConfigElement() { DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(1024*1024); factory.setRepository(Paths.get("/tmp").toFile()); ServletFileUpload upload = new ServletFileUpload(factory); upload.setFileSizeMax(1024*1024*50); // 50MB单文件限制 upload.setSizeMax(1024*1024*100); // 100MB总请求限制 return new MultipartConfigElement(""); } ``` --- ### 三、高级调试技巧 1. **请求头验证** 使用抓包工具检查`Content-Type`是否包含`multipart/form-data` ```http POST /upload HTTP/1.1 Content-Type: multipipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW ``` 2. **依赖树分析** Maven执行`mvn dependency:tree`检查是否存在多个版本的fileupload库 ```xml <!-- 正确依赖声明 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.5</version> </dependency> ``` 3. **异常类型对照表** | 异常信息 | 解决方案 | |---------|----------| | `FileUploadException: Stream closed` | 禁止重复读取request | | `FileSizeLimitExceededException` | 调整setFileSizeMax() | | `IOExceptions` | 检查服务器磁盘间 | --- ### 四、框架整合建议 对于**SpringMVC/SpringBoot**用户,推荐优先使用`CommonsMultipartResolver`: ```java @Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setDefaultEncoding("UTF-8"); resolver.setMaxUploadSize(52428800); // 50MB return resolver; } ``` 通过`@RequestParam MultipartFile file`接收文件,避免手动解析request[^3] ---
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值