负责上传文件的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
分享到:
相关推荐
在这个"Servlet 文件上传下载例子"中,我们将探讨如何使用Servlet实现文件的上传和下载功能,这对于构建一个简单的图片文件服务器至关重要。 1. **文件上传** - **MultipartRequest**: 在Servlet中,处理文件上传...
本教程将详细讲解如何使用Servlet实现文件的上传和下载功能,其中涉及到的主要技术点包括Servlet API、Multipart解析以及文件流操作。 首先,我们需要了解Servlet在文件上传中的作用。Servlet在接收到客户端(通常...
本文实例为大家分享了JSP+Servlet实现文件上传到服务器功能的具体代码,供大家参考,具体内容如下 项目目录结构大致如下: 正如我在上图红线画的三个东西:Dao、service、servlet 这三层是主要的结构,类似 MVC ...
用户通过`<input type="file">`选择文件后,将文件添加到`FormData`对象,然后通过XMLHttpRequest发送请求。 ### 2. 创建HTML表单 首先,我们需要一个包含文件选择控件的HTML表单: ```html ()">上传 ``` #...
假如一个场景,用户上传文件,某些用户网速较慢,同时存在100个这样的用户,如果BIO且最大线程设为100会导致线程用完。NIO怎么来解决这个问题? 本实例采用tomcat8作为容器,开启异步servlet读写事件,解决高并发IO...
本示例基于Servlet和Apache Commons FileUpload库实现了一个简单的文件上传系统。下面将详细介绍这个过程及其涉及到的关键知识点。 首先,`servlet`是Java EE(企业版)的一部分,它是一种用于扩展Web服务器功能的...
在本案例"JAVA_servlet的文件上传"中,我们将深入探讨如何使用Servlet实现文件上传功能,这对于构建交互性强的Web应用程序是至关重要的。文件上传功能允许用户在Web表单中选择本地文件并将其发送到服务器进行存储或...
在处理文件上传需求时,JSP通常作为前端界面,而Servlet则负责后端逻辑处理。本篇文章将深入探讨如何使用JSP与Servlet进行文件上传,并特别关注如何解决中文文件名乱码的问题。 首先,我们需要理解文件上传的基本...
5. 处理完文件后,向客户端发送确认消息。 文件下载的实现相对简单,主要涉及到HTTP响应头的设置。以下是一般的流程: 1. 用户点击下载链接,发送GET请求到服务器。 2. 在Servlet的`doGet`方法中,找到待下载的...
总的来说,利用COS Servlet上传文件涉及到客户端的表单提交和服务器端的Servlet处理,需要对HTTP协议、文件上传、MultipartRequest以及可能的业务逻辑有深入理解。同时,确保在实现过程中充分考虑安全性,以提供健壮...
- 使用JavaScript监听CKEditor的“文件选择”事件,当用户选择文件后,自动提交表单。 4. **安全性和优化**: - 为了安全,应验证上传的文件类型和大小,防止恶意文件上传。 - 可以考虑使用多线程处理大文件上传...
jsp、servlet 文件上传下载技术详解 文件上传下载是 Web 应用中的一种常见需求,使用 jsp 页面和 servlet 实现文件上传下载是其中的一种解决方案。下面将详细介绍 jsp、servlet 文件上传下载技术。 文件上传下载...
本文将深入探讨如何在Servlet中实现文件的上传和下载功能,以及在页面上利用JSP和Javabean来实例化对象。 首先,文件上传是通过HTTP多部分请求(Multipart Request)来实现的。Servlet 3.0及以上版本提供了对这种...
"Servlet上传文件并显示进度条"这个主题涵盖了如何在用户上传大文件时提供实时进度反馈,以增强用户体验。在这个过程中,我们需要处理以下几个核心知识点: 1. **Multipart解析器**:Servlet 3.0及以上版本引入了...
接收到文件后,我们需要将其转换为字节数组,以便存储在数据库中。可以使用`InputStream`和`ByteArrayOutputStream`来实现这个转换: ```java InputStream fileContent = filePart.getInputStream(); ...
在本篇讨论中,我们将深入探讨如何利用Servlet实现文件上传功能,以及在这个过程中涉及的关键知识点。 首先,我们需要了解HTTP协议。HTTP协议是无状态的,这意味着每次请求都是独立的。因此,在客户端(通常是...
获取到文件后,开发者可以将其保存到服务器的指定目录,或者存储到数据库、云存储等服务。 在处理文件上传的过程中,有几个关键点需要注意: 1. **安全**:确保只接受特定类型的文件,避免恶意文件上传,可以检查...
上载文件.轻松搞定.java Servlet上传文件.
- 上传完成后,Servlet需要返回一个响应,告知客户端文件是否成功上传,或者提供上传失败的原因。 综上所述,Servlet实现的文件上传涉及了HTTP协议、Servlet API、文件存储策略、安全控制等多个方面。理解并熟练...
下面将详细介绍如何使用Servlet实现文件上传和下载的功能。 ### 文件上传 文件上传通常涉及到HTTP协议中的`multipart/form-data`编码类型,这是处理表单数据中包含文件的关键。Servlet 3.0及以上版本提供了更方便...