
一、表单元素的enctype属性
通常情况下无须设置表单元素的enctype属性,表单的enctype属性指定的是表单数据的编码方式,该属性有如下3个值:
◆ application/x-www-form-urlencoded:这是默认的编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式
◆ multipart/form-data:这种编码方式会以二进制的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里
◆ text/plain:这种编码方式当表单的action属性为mailto:URL的形式时比较方便,这种方式主要适用于直接通过表单发送邮件的方式
下面来看看enctype属性为application/x-www-form-urlencoded和multipart/form-data时的差别
|
<html>
<head>
<title>enctype属性测试</title>
</head>
<body>
<form action="pro.jsp" method="post"
enctype="application/x-www-form-urlencoded">
上传文件:
<input type="file" name="file" /><br />
请求参数:
<input type="text" name="info" /><br />
<input type="submit" value="提交" />
</form>
</body>
</html>
|
注意:application/x-www-form-urlencoded是enctype属性的默认值
提交到的pro.jsp代码如下:
|
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="java.io.*"%>
<%
//获取HTTP请求的输入流
InputStream is=request.getInputStream();
//创建缓冲读入流
BufferedReader br=new BufferedReader(new InputStreamReader(is));
//读取HTTP请求内容
String buffer=br.readLine();
while(buffer!=null){
out.println(buffer);
buffer=br.readLine();
}
%>
|
以上代码通过二进制流来处理HTTP请求——这是一种更底层的处理方式,当通过HttpServletRequest的getParameter方法来获取请求参数时,实际上是Web服务器替我们处理了这种底层的二进制流,并将二进制流转换成对应的请求参数值。
请求数据中的文字转码
|
public class TestURLEncoder {
public static void main(String[] args)throws Exception {
String encodeStr="%D0%EC%D6%DD";
System.out.println(URLDecoder.decode(encodeStr,"GBK"));
String rawStr="北大青鸟";
System.out.println(URLEncoder.encode(rawStr,"GBK"));
}
}
|
一般情况下,程序中直接通过HttpServletRequest的getParameter方法即可获得正确的请求参数,而那些底层的二进制流处理,以及使用URLDecoder处理请求参数,都由Web服务器来替我们完成了。
但是做文件上串操作的话,仅仅只能获得文件选择器中数值,而不能获得文件的内容,为了实现文件上传,必须设置enctype属性值为:multipart/form-data
二、手动上传
下面直接通过底层的二进制流来取得上传文件的内容,并将该文件保存到Web应用程序所在的目录下
|
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="java.io.*"%>
<%
//获取HTTP请求的输入流
InputStream is=request.getInputStream();
//创建缓冲读入流
BufferedReader br=new BufferedReader(new InputStreamReader(is));
//读取HTTP请求内容
String buffer=br.readLine();
while(buffer!=null){
//如果读到以-----------------------------开始,且以--结束,表明已到请求内容尾
if(buffer.endsWith("--") && buffer.startsWith
("-----------------------------")){
//跳出循环
break;
}
//如果读到的内容以-----------------------------开始,表明开始了一个表单域
if(buffer.startsWith("-----------------------------")){
if(br.readLine().indexOf("filename")>1){
//跳过两行,开始处理上传的文件内容
br.readLine();
br.readLine();
File file=new File(request.getSession().getServletContext().getRealPath("/")+System.currentTimeMillis());
PrintStream ps=new PrintStream(new FileOutputStream(file));
String content=null;
//接着开始读取文件内容
while((content=br.readLine())!=null){
//如果读到的内容以-----------------------------开始,表明开始了下一个表单域内容
if(content.startsWith("-----------------------------")){
//跳出循环
break;
}
//将读到的内容输出到文件中
ps.println(content);
}
//关闭输出
ps.flush();
ps.close();
}
}
buffer=br.readLine();
}
br.close();
%>
|