负责上传文件的servlet
package upload;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.Hashtable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UploadFileServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
final int NONE = 0; //状态码,标识没有特殊操作
final int DATAHEADER = 1; //标识下一行要读到的抱头信息
final int FILEDATA = 2; //表示下面要读到表单域的文本值
final int FIELDDATA = 3; //表示下面要读的是二进制文件和二进制数据
int totalbytes = request.getContentLength(); //请求消息实体的总长度(请求消息中除了消息头之外的数据长度)
byte[] b = new byte[totalbytes]; //保存请求消息实体的 数组
String contentType = request.getContentType(); //请求消息类型
String fieldname = ""; //表单域的名称
String fieldvalue = "";//表单域的值
String filename = ""; //上传的文件的名字
String boundary = ""; //分界符字符串
String lastBoundary = ""; //结束分界符字符串
int fileSize = 0; //文件长度
Hashtable<String,String> formfields = new Hashtable<String,String>(); //保存表单域的名称/值的哈希表
int pos = contentType.indexOf("boundary="); //在消息头中找到分界符的定义
String fileID; // 上传文件的id
if (pos != -1) {
pos += "boundary=".length();
boundary = "--" + contentType.substring(pos); //解析出分界符
lastBoundary = boundary + "--"; //得到结束分界符
}
int state = NONE; //起始状态是none
DataInputStream in = new DataInputStream(request.getInputStream()); //请求消息的数据输入流
in.readFully(b); //根据长度,将消息实体的内容读入字节数组b中
in.close();
String reqcontent = new String(b);
BufferedReader reqbuf = new BufferedReader(new StringReader(reqcontent));//从字符串中得到输出缓冲流
boolean flag = true; //循环标识
int i = 0;
while (flag == true) {
String s = reqbuf.readLine();
if (s == null || s == lastBoundary)
break;
switch (state) {
case NONE:
if (s.startsWith(boundary)) {
state = DATAHEADER;
i += 1;
}
break;
case DATAHEADER:
pos = s.indexOf("filename="); //先判断出这是一个文本表单域的头信息,还是一个上传文件的头信息
if (pos == -1) {
pos = s.indexOf("name="); //如果是文本表单域的头信息,解析出表单域的名称
pos += "name=".length() + 1;
s = s.substring(pos);
int l = s.length();
s = s.substring(0, l - 1);
fieldname = s; //表单域的名称放入filename
state = FIELDDATA; //设置状态吗,准备读取表单域的值
} else {//如果是文件数据的头,先存储这一行,用于在字节数组中定位
String temp = s;
// 先解析出文件名
pos = s.indexOf("filename=");
pos += "filename=".length() + 1;
s = s.substring(pos);
int l = s.length();
s = s.substring(0, l - 1);
pos = s.lastIndexOf("\\");
s = s.substring(pos + 1);
filename = s;
pos = byteIndexOf(b, temp, 0); //定位行
b = subBytes(b, pos + temp.getBytes().length + 2, b.length); //定位下一行,2标识一个回车和一个换行站2字节
s = reqbuf.readLine();
File f = new File(filename); //准备文件输入流,准备写文件
DataOutputStream fileout = new DataOutputStream(
new FileOutputStream(f));
b = this.subBytes(b, s.getBytes().length + 4, b.length);
pos = this.byteIndexOf(b, boundary, 0); //定位文件数据的结尾
b = this.subBytes(b, 0, pos - 1); //取得文件数据
fileout.write(b, 0, b.length -1); //将文件数据存盘
fileSize = b.length - 1; //文件长度
state = FILEDATA;
}
break;
case FIELDDATA: //读取表单域的值
s = reqbuf.readLine();
fieldvalue = s;
formfields.put(fieldname, fieldvalue);
state = NONE;
break;
case FILEDATA:
while ((!s.startsWith(boundary))
&& (!s.startsWith(lastBoundary))) {
s = reqbuf.readLine();
if (s.startsWith(boundary)) {
state = DATAHEADER;
} else
break;
}
break;
} // switch
} // while
response.setContentType("text/html;charset=gb2312");//指定内容类型,并且可显示中文
PrintWriter out = response.getWriter();
out
.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>文件上传结果</TITLE></HEAD>");
out.println(" <BODY>");
out.println("<h1>文件上传结果</h1>");
out.println("ID 为" + formfields.get("FileID") + "的文件" + filename
+ "已经上传!" + "文件长度为:" + fileSize + "字节");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
private static byte[] subBytes(byte[] b, int from, int end) {
byte[] result = new byte[end - from];
System.arraycopy(b, from, result, 0, end - from);
return result;
}
private static int byteIndexOf(byte[] b, String s, int start) {
return byteIndexOf(b, s.getBytes(), start);
}
private static int byteIndexOf(byte[] b, byte[] s, int start) {
int i;
if (s.length == 0) {
return 0;
}
int max = b.length - s.length;
if (max < 0)
return -1;
if (start > max)
return -1;
if (start < 0)
start = 0;
search: for (i = start; i <= max; i++) {
if (b[i] == s[0]) {
int k = 1;
while (k < s.length) {
if (b[k + i] != s[k]) {
continue search;
}
k++;
}
return i;
}
}
return -1;
}
private static String subBytesString(byte[] b,int from,int end){
return new String(subBytes(b,from,end));
}
}
<%@ page language="java" contentType = "text/html;charset=gb2312" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form method ="POST" action ="UploadFileServlet" enctype ="multipart/form-data">
<p>
I D:
<input type="text" name="FileID" size="20">
</p>
<p>
文件:
<input type="file" name="FileData" size="20">
</p>
<p>
<input type="submit" value="上传" name="uploadfile">
</p>
</form>
</body>
</html>
配置文件web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>UploadFileServlet</servlet-name>
<servlet-class>upload.UploadFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadFileServlet</servlet-name>
<url-pattern>/UploadFileServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
执行结果:
源码见附件
- 大小: 12.7 KB
- 大小: 19.7 KB
分享到:
相关推荐
本文实例为大家分享了JSP+Servlet实现文件上传到服务器功能的具体代码,供大家参考,具体内容如下 项目目录结构大致如下: 正如我在上图红线画的三个东西:Dao、service、servlet 这三层是主要的结构,类似 MVC ...
假如一个场景,用户上传文件,某些用户网速较慢,同时存在100个这样的用户,如果BIO且最大线程设为100会导致线程用完。NIO怎么来解决这个问题? 本实例采用tomcat8作为容器,开启异步servlet读写事件,解决高并发IO...
servlet 上传文件流保存到数据库
Servlet实现文件上传与下载 Servlet 文件上传与下载
ajax异步文件上传,servlet处理
jsp与servlet文件上传代码,可以上传中文文件名,不乱码 jsp与javaBean文件上传代码,但上传中文文件名乱码 刚写完的。
Servlet上传文件并显示进度条
上载文件.轻松搞定.java Servlet上传文件.
JAVA_servlet的文件上传案例
使用commons-fileupload 做的一个简单的基于servlet的文件上传的例子
servlet上传文件详细解析 大家好好看
java 写的文件上传下载的例子,可以做简单图片文件服务器
Servlet中文件上传和下载,页面使用jsp里面实例化对象使用Javabean
本工程用于借助Servlet3.0实现文件上传 本工程编码方式:UTF-8 注意: 1、在上传文件前请在计算机C盘新建一个名为“upload”的文件夹,否则会出现如下异常:java.io.IOException: The temporary upload location [C...
该资源利用开源upload文件包,成功实现文件上传与下载
利用cos.jar 通过Servlet实现文件上传至服务器
vue,servlet3.0、文件上传
自己用servlet写的文件上传及下载功能带进度条 主要用到两个jar:commons-fileupload-1.2.2.jar和commons-io-2.0.1.jar 内容介绍: com.fm.FileManagerService:一个servlet用来实现主要的文件上传下载逻辑的 ...
使用Servlet实现文件的上传与下载Demo
servlet实现多文件上传,上传只为分享...