目录
今天早晨起来想总结一下,然而在编写代码时遇到几个不大不小的问题,浪费了很长时间,在此分享一下,希望大家都能够避免这些错误。
注意点1:form的属性设置
这一个地方我没有犯错,但是会忘记单词的拼写……
<form action="..." method="post" enctype="multipart/form-data">
<!-- 表单内容 -->
</form>
enctype属性的解释是:可设置或返回用于编码表内容的MIME类型。
MIME:(Multipurpose Internet Mail Extensions)多用途互联网右键扩展类型。用以设定以什么类型去”看待“某文件(或资源)。
在enctype属性中,有以下值:
application/x-www-form-urlencoded :默认值,在发送前对所有字符进行编码(将空格转换为 "+" 符号,特殊字符转换为 ASCII HEX 值)。multipart/form-data :不对字符编码。当使用有文件上传控件的表单时,该值是必需的。text/plain :将空格转换为 "+" 符号,但不编码特殊字符。
由于我们需要在表单中写有文件上传控件,所以使用的是enctype=multipart/form-data。
除此之外,也要记住必须使用post当作发送表单的HTTP方法。
注意点2:接收表单数据
注意:不能用getParameter接收此类表单(multipart/form-data)!!!
这一点很关键,因为通过简单的测试就能明白,getParameter接收不到这些参数的值(都是null)。
如果想要接收此类参数,可以使用第三方的jar包(在此使用的是commons-upload)。
常用的三个文件上传组件:
apache commons-upload
Orialiy - COS - 2008()
smart-upload
注意点3:FileUpload的使用
第一步当然是导包,导入两个包:
其中,fileupload包依赖于io包。
下面就是在servlet中写基本的获取提交数据的方法。
- 实例化fileUpload对象
DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload fileUpload = new ServletFileUpload(factory);
- 获取表单中的每一条数据
// req是doPost()方法中的HttpServletRequest对象 List<FileItem> items = fileUpload.parseRequest(req); for(FileItem item : items) { ... }
- 判断每条数据的处理方式(普通元素或文件上传元素)
// 循环内部代码
// 需要判断item是普通表单元素还是文件上传表单元素,
// 从而决定不同的操作
if (item.isFieldName()) {
// 其实这一步不管是什么元素,
// getFieldName()方法的返回值就是表单中name值
String name = item.getFieldName();
// 注意!注意!此处可能存在编码问题!
String value = item.getString();
} else {
String name = item.getFieldName();
String fileName = item.getName();
// 之后对文件内容做处理
...
}
注意点4 编码问题
这个问题算得上是编程界的一大不可避免的问题,只要有数据的传输,就可能有编码问题……
在以前使用getParameter获取值时,没有出现编码问题,但是,在今天早晨测试时,突然发现,如果是带有中文的值,有可能会有乱码现象(很奇怪,昨天和今天的编码情况好像不太一样……)
在fileUpload中获取值有三种方法:
file.getString();
file.getString("");
file.get();
第一个方法是最常规的,不能修改编码;第二个方法是第一个方法的重载,其中的字符串参数就是字符编码。
我使用的是第三种,file.get(),返回的是字节数组。
String info = new String(item.get(),"utf-8");
这样同样能够解决编码问题。
当时调试了半天才找到这个关键点,在之后倘若还出现这类型问题,可以考虑一下这个方面。
注意点5 文件存储
其实这一点很简单,有两种方法,第一种是直接使用fileUpload自带方法,第二种是自己去手工使用文件输出流。
第一种:调用方法
try {
fileItem.write(new File(""));
} catch (Exception e) {
e.printStackTrace();
}
第二种:手工定义输出流
byte[] bytes = fileItem.get();
OutputStream outputStream = new FileOutputStream("");
outputStream.write(bytes);
outputStream.close();
两种方法都能够存储文件,推荐使用第一种比较方便。