最近在面试IBM时,面试官突然问到:如果让你自己实现一个文件上传,你的代码要如何写,不借助其他开源的文件上传jar包?
这一问,我楞了。现在开源MVC框架满天飞,大部分的框架像Struts2都会自动的把你上传的文件封装成Action的属性。几乎没有人自己去分析请求流数据,然后获取文件数据的。
总结下文件上传的几种实现:
一、像Struts2这样的框架自动将你上传的文件封装到Action的属性中,在配置文件里面你只需要指定文件上传的临时目录即可。
二、借助Apache的common-fileupload组件,实现文件上传。让开源组件帮你自动分析请求流数据,核心代码如下,详细的请参考
http://morfil.iteye.com/blog/66945:
public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException
{
try {
DiskFileUpload fu = new DiskFileUpload();
// 设置最大文件尺寸,这里是4MB
fu.setSizeMax(4194304);
// 设置缓冲区大小,这里是4kb
fu.setSizeThreshold(4096);
// 设置临时目录:
fu.setRepositoryPath(tempPath);
// 得到所有的文件:
List fileItems = fu.parseRequest(request);
Iterator i = fileItems.iterator();
// 依次处理每一个文件:
while(i.hasNext()) {
FileItem fi = (FileItem)i.next();
// 获得文件名,这个文件名包括路径:
String fileName = fi.getName();
// 在这里可以记录用户和文件信息
// ...
// 写入文件,暂定文件名为a.txt,可以从fileName中提取文件名:
fi.write(new File(uploadPath + "a.txt"));
}
}
catch(Exception e) {
// 可以跳转出错页面
}
}
三、Servlet 3.0通过@MultipartConfig(location = "/home/yongboy/tmp/", maxFileSize = 1024 * 1024 * 10)和@WebServlet("/upload")注解也可以实现文件上传,核心代码如下,详情请见
http://www.blogjava.net/yongboy/archive/2011/01/15/346202.html:
/**
* 上传文件测试 location为临时文件保存路径
*
* @author yongboy
* @date 2011-1-13
* @version 1.0
*/
@MultipartConfig(location = "/home/yongboy/tmp/", maxFileSize = 1024 * 1024 * 10)
@WebServlet("/upload")
public class UploadFileAction extends HttpServlet {
private static final long serialVersionUID = 92166165626L;
private static final Log log = LogFactory.getLog(UploadFileAction.class);
// 得到注解信息
private static final MultipartConfig config;
static {
config = UploadFileAction.class.getAnnotation(MultipartConfig.class);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/upload.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 为避免获取文件名称时出现乱码
request.setCharacterEncoding("UTF-8");
Part part = null;
try {
// <input name="file" size="50" type="file" />
part = request.getPart("file");
} catch (IllegalStateException ise) {
// 上传文件超过注解所标注的maxRequestSize或maxFileSize值
if (config.maxRequestSize() == -1L) {
log.info("the Part in the request is larger than maxFileSize");
} else if (config.maxFileSize() == -1L) {
log.info("the request body is larger than maxRequestSize");
} else {
log.info("the request body is larger than maxRequestSize, or any Part in the request is larger than maxFileSize");
}
forwardErrorPage(request, response, "上传文件过大,请检查输入是否有误!");
return;
} catch (IOException ieo) {
// 在接收数据时出现问题
log.error("I/O error occurred during the retrieval of the requested Part");
} catch (Exception e) {
log.error(e.toString());
e.printStackTrace();
}
if (part == null) {
forwardErrorPage(request, response, "上传文件出现异常,请检查输入是否有误!");
return;
}
// 得到文件的原始名称,eg :测试文档.pdf
String fileName = UploadUtils.getFileName(part);
log.info("contentType : " + part.getContentType());
log.info("fileName : " + fileName);
log.info("fileSize : " + part.getSize());
log.info("header names : ");
for (String headerName : part.getHeaderNames()) {
log.info(headerName + " : " + part.getHeader(headerName));
}
String saveName = System.currentTimeMillis() + "."
+ FilenameUtils.getExtension(fileName);
log.info("save the file with new name : " + saveName);
// 因在注解中指定了路径,这里可以指定要写入的文件名
// 在未执行write方法之前,将会在注解指定location路径下生成一临时文件
part.write(saveName);
request.setAttribute("fileName", fileName);
request.getRequestDispatcher("/uploadResult.jsp").forward(request,
response);
}
private void forwardErrorPage(HttpServletRequest request,
HttpServletResponse response, String errMsg)
throws ServletException, IOException {
request.setAttribute("errMsg", errMsg);
request.getRequestDispatcher("/upload.jsp").forward(request, response);
}
}
获取上传文件名:
/**
* 如何得到上传的文件名, API没有提供直接的方法,只能从content-disposition属性中获取
*
* @param part
* @return
*/
protected static String getFileName(Part part) {
if (part == null)
return null;
String fileName = part.getHeader("content-disposition");
if (StringUtils.isBlank(fileName)) {
return null;
}
return StringUtils.substringBetween(fileName, "filename=\"", "\"");
}
四、就是自己去解析请求流数据,当然现在没有人会傻到还去自己做这种事情。这里我们只是了解下Apache的那帮牛人是怎么做到文件上传的。
首先我们先分析文件上传HTTP请求头:
一、文件上传Http请求Request截图:
贴个文字版的,里面的数据我使用谷歌浏览器截获的,方便大家拷贝
Request URL:http://127.0.0.1/dbm2-web/flowmgmt/FlowMgmtAction/uploadFile.go
Request Method:POST
Status Code:200 OK
Request Headers view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:GBK,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:54738
Content-Type:multipart/form-data; boundary=---- WebKitFormBoundaryhQslmBE7nbTLTJzD
Cookie:JSESSIONID=1ge6jxgy4s166bzms8og4j7us
Host:127.0.0.1
Origin:http://127.0.0.1
Referer:http://127.0.0.1/dbm2-web/page/modules/flowmgmt/main.jsp
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1163.0 Safari/537.1
Request Payload
------WebKitFormBoundaryhQslmBE7nbTLTJzD
Content-Disposition: form-data; name="field1"; filename="exportFlow-4113.fd"
Content-Type: application/octet-stream
------WebKitFormBoundaryhQslmBE7nbTLTJzD--
Response Headers view source
Expires:Thu, 01-Jan-1970 00:00:00 GMT
Server:Jetty(7.3.1.v20110307)
Set-Cookie:JSESSIONID=oyklz60lg9aq1dn127p62ki0t;Path=/dbm2-web
Transfer-Encoding:chunked
从上述结构上我们可以知道,文件上传的Content-Type为multipart/form-data; boundary=----WebKitFormBoundaryhQslmBE7nbTLTJzD,而普通的form表单的Content-Type为application/x-www-form-urlencoded。因此,我们可以利用HttpServletRequest的request.getHeaderNames()方法和request.getHeaders(headName)方法得到请求头Headers中的Content-Type数据,然后根据Content-Type数据中是否包含multipart/form-data来区分请求是否为文件上传请求。其中boundary为文件数据的分隔符,用于区分上传多个文件。详细介绍请见http://yefeng.iteye.com/blog/315847
了解请求头的结构后,我们看看如何用程序去得到普通请求和文件上传请求的数据
http://blog.csdn.net/liuyar/article/details/6202331
二、文件上传Http请求Response截图:
三、文件上传Http请求Cookies截图:
- 大小: 31.7 KB
- 大小: 5.1 KB
- 大小: 6.3 KB
分享到:
相关推荐
"FileUpLoad文件上载jar包"就是专为实现这一功能而设计的库,它通常包含了一系列用于处理文件上传的Java类和方法。下面我们将详细探讨文件上传的基本原理、File控件的作用以及如何利用jar包来实现文件上载。 1. **...
总的来说,"commons-fileupload-1.2.1.jar"和"commons-io-1.3.2.jar"这两个jar包为Java Web开发中的文件上传功能提供了强大的支持,使得开发者能够高效、安全地处理用户的文件上传请求。它们是Java Web开发者的得力...
在Java开发中,上传文件是一项常见的任务,Apache Commons FileUpload库正是为此而设计的。这个"最全的common-FileUpload.jar包"包含了处理HTTP请求中的多部分数据,特别是文件上传的功能。它使得开发者能够方便地从...
Java网页上传文件是Web开发中的常见需求,而`commons-fileupload.jar`是Apache Commons项目提供的一款强大且便捷的工具,专门用于处理Java Servlet环境下的文件上传功能。这个库简化了从HTTP请求中提取多部分...
这个"Java Web 文件上传与下载 jar包"提供了一组关键的库文件,可以帮助开发者轻松实现这些功能。以下是这四个jar文件的主要内容及其在文件处理中的作用: 1. **standard.jar**:这是Java Servlet API的一部分,...
这个场景中提到的"java实现文件上传jar包"是指使用Java库来处理文件上传功能。主要涉及到两个关键的开源库:Apache Commons IO和Apache Commons FileUpload。下面将详细阐述这两个库以及如何使用它们来实现文件上传...
在Java Web开发中,文件上传是一项常见的功能,用于允许用户将本地文件传输到服务器。Apache Commons FileUpload库是一个强大的工具,专门设计用于处理这种需求。本篇将详细讲解使用FileUpload组件实现JSP文件上传所...
在Java开发中,文件上传是一项常见的任务,尤其是在构建Web应用程序时。`commons-fileupload.jar` 和 `commons-io-2.6.jar` 是Apache Commons项目中的两个关键库,它们为处理文件上传提供了强大的支持。 `commons-...
在Java开发中,文件上传是一项常见的任务,尤其是在构建Web应用时。为了实现这一功能,开发者通常会依赖第三方库,如Apache Commons FileUpload和Commons IO。这两个库在Java文件上传处理中扮演着至关重要的角色。 ...
标题提到的"java上传文件jar"实际上指的是两个关键的Java库,它们是Apache Commons IO和Apache Commons FileUpload。这两个库提供了强大的文件操作和文件上传功能,是Java开发者处理文件上传问题的得力助手。 首先...
"fileupload jar包"是Java Web开发中常用的一个组件,主要用于处理HTTP请求中的文件上传功能。这个jar包通常包含了处理文件上传所需的类和接口,使得开发者可以方便地在Web应用程序中实现用户上传文件的功能。 在...
标题中的"fileupload所需jar包"表明我们正在讨论与文件上传功能相关的Java库。在Web应用开发中,处理用户上传的文件是一项常见的需求,而Apache Commons FileUpload和Apache Commons IO是两个关键的Java库,它们提供...
在这个场景下,"文件上传下载需要的jar包"指的是用于处理文件上传和下载操作的Java类库。下面将详细介绍相关的知识点。 1. **Apache Commons FileUpload**: 这是一个非常流行的Java库,用于处理HTTP请求中的多部分...
在使用浏览器的文件上传的功能时,需要在servlet导入几个必备的jar包。 commons-io-1.4-bin.zip commons-beanutils-1.8.0-bin.zip commons-fileupload-1.2.1-bin.zip
在Java开发中,文件上传是一项常见的功能,尤其是在Web应用程序中,用户可能需要上传图片、文档等各类文件。Apache Commons FileUpload和Commons IO是两个非常重要的库,它们为Java开发者提供了方便、高效的文件上传...
在这个场景下,"文件上传的io和fileupload的jar包"主要指的是如何利用Java语言,通过Apache Commons IO库和Commons FileUpload库来实现文件上传的功能。下面我们将详细探讨这两个关键知识点。 首先,Java中的IO是...
在Java Web开发中,文件的上传与下载是常见的功能需求,尤其在构建动态网站或Web应用程序时。本教程将深入讲解如何使用Java Servlet、Apache Commons IO库(版本2.4)以及Apache Commons FileUpload库(版本1.3)来...
Java文件上传JAR包是一个常见的任务,特别是在Java Web开发中,它涉及到服务器端接收客户端上传的文件,如图片、文档或应用程序(如JAR文件)。这个压缩包可能包含了一个完整的Java Web项目,用于演示或实现文件上传...
总的来说,这些jar包构成了处理Java文件上传的基础设施,它们一起帮助开发者轻松地在Web应用中实现安全、高效的文件上传功能。在实际开发中,还需要结合Servlet容器(如Tomcat)和Web框架(如Spring或JSF)来构建...
总之,`Fileupload`和`IO`的jar包是Java Web开发中处理文件上传和进行复杂IO操作的必备工具。通过合理利用这两个库,开发者可以更高效、更安全地管理用户的文件上传,并且可以方便地处理上传文件的存储和进一步的...