Servlet下载文件时 中文名 引发的一系列问题

1.报错3986
解决办法:下图蓝框中内容,找到Tomcat安装路径下/conf/catalina.propertils文件中最后一行,去掉最后一行开头的 #,并且在最后一行加上一对大括号{}

Servlet下载文件时 中文名 引发的一系列问题_第1张图片
2.解决完上面之后出现找不到文件路径问题(文件名乱码),下载时会找不到网页,解决代码如下:

		//接收文件名
		String name = request.getParameter("filename");
		System.out.println(name);
		//获取参数,默认会对参数进行编码,方式为ISO8859-1
		//把乱码转回二进制位
		byte[] bytes = name.getBytes("ISO8859-1");
		//在使用UTF-8进行编码
		name = new String(bytes,"UTF-8");

问题2改进:当为post方法提交时可用下面一行代码完成(注:get方法提交不能用)

	request.setCharacterEncoding("UTF-8");

3.解决完上面下载时文件名缺失问题(只有后缀名),解决代码如下:

		//获取客户端信息
		String agent =request.getHeader("User-Agent");
		//定义一个变量记录编码之后的名字
		String filenameEncoder = "";
		if (agent.contains("MSIE")) {
			//IE编码
			filenameEncoder = URLEncoder.encode(name,"utf-8");
			filenameEncoder = filenameEncoder.replace("+", "");
		}else if (agent.contains("Firefox")) {
			//火狐编码
			BASE64Encoder base64Encoder = new BASE64Encoder();
			filenameEncoder = "=?utf-8?B?"+base64Encoder.encode(name.getBytes("utf-8"))+"?=";
		}else {
			//浏览器编码
			filenameEncoder = URLEncoder.encode(name,"utf-8");
		}
		
		response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);

4.文件类型不能识别问题(不属于中文文件名问题),解决代码如下:

		//根据文件名来获取mime类型
		String mimeType = this.getServletContext().getMimeType(name);
		response.setContentType(mimeType);

最后附完整代码:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//接收文件名
		String name = request.getParameter("filename");
		System.out.println(name);
		//获取参数,默认会对参数进行编码,方式为ISO8859-1
		//把乱码转回二进制位
		byte[] bytes = name.getBytes("ISO8859-1");
		//在使用UTF-8进行编码
		name = new String(bytes,"UTF-8");
		//根据文件名来获取mime类型
		String mimeType = this.getServletContext().getMimeType(name);
		response.setContentType(mimeType);
		//告诉浏览器以附件的形式打开,不解析	
		//获取客户端信息
		String agent =request.getHeader("User-Agent");
		//定义一个变量记录编码之后的名字
		String filenameEncoder = "";
		if (agent.contains("MSIE")) {
			//IE编码
			filenameEncoder = URLEncoder.encode(name,"utf-8");
			filenameEncoder = filenameEncoder.replace("+", "");
		}else if (agent.contains("Firefox")) {
			//火狐编码
			BASE64Encoder base64Encoder = new BASE64Encoder();
			filenameEncoder = "=?utf-8?B?"+base64Encoder.encode(name.getBytes("utf-8"))+"?=";
		}else {
			//浏览器编码
			filenameEncoder = URLEncoder.encode(name,"utf-8");
		}
		
		response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);
		//拼接文件绝对路径
		String path = this.getServletContext().getRealPath("download/"+name);
		//根据path加载文件
		FileInputStream in = new FileInputStream(path);
		//获取响应的输出流
		ServletOutputStream out = response.getOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len=in.read(buffer)) != -1) {
			//写到响应当中
			out.write(buffer,0,len);
		}
		
		in.close();
	}

HTML:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>文件下载</h1>
<a href="/LoginTest/DownServlet?filename=aaa.jpg">jpg</a><br/>
<a href="/LoginTest/DownServlet?filename=ggg.zip">.zip</a><br/>
<a href="/LoginTest/DownServlet?filename=中文.jpg">中文.jpg</a><br/>
</body>
</html>

你可能感兴趣的:(JAVAWeb)