实现 Web 开发中的文件上传功能,两个 *** 作:在 Web 页面添加上传输入项,在 Servlet 中读取上传文件的数据并保存在本地硬盘中。
1、Web 端上传文件。在 Web 页面中添加上传输入项:<input type="file">设置文件上传输入项时应注意:(1) 必须设置 input 输入项的 name 属性,否则浏览器将不会发送上传文件的数据。(2) 必须把 form 的 enctype 属性设为 multipart/form-data,设置该值后,浏览器在上传文件时,将把文件数据附带在 http 请求消息体中,并使用 MIME 协议对上传文件进行描述,以方便接收方对上传数据进行解析和处理。(3) 表单提交的方式要是 post
2、服务器端获取文件。如果提交表单的类型为 multipart/form-data 时,就不能采用传统方式获取数据。因为当表单类型为 multipart/form-data 时,浏览器会将数据以 MIME 协议的形式进行描述。如果想在服务器端获取数据,那么我们必须采用获取请求消息输入流的方式来获取数据。
3、Apache-Commons-fileupload。为了方便用户处理上传数据,Apache 提供了一个用来处理表单文件上传的开源组建。使用 Commons-fileupload 需要 Commons-io 包的支持。
4、fileuplpad 组建工作流程
(1)客户端将数据封装在 request 对象中。
(2)服务器端获取到 request 对象。
(3)创建解析器工厂 DiskFileItemFactory 。
(4)创建解析器,将解析器工厂放入解析器构造函数中。之后解析器会对 request 进行解析。
(5)解析器会将每个表单项封装为各自对应的 FileItem。
(6)判断代表每个表单项的 FileItem 是否为普通表单项 isFormField,返回 true 为普通表单项。
(7)如果是普通表单项,通过 getFieldName 获取表单项名,getString 获得表单项值。
(8)如果 isFormField 返回 false 那么是用户要上传的数据,可以通过 getInputStream 获取上传文件的数据。通过getName 可以获取上传的文件名。
使用 apache fileupload ,spring MVC jquery1.6x , bootstrap 实现一个带进度条的多文件上传,由于fileupload 的局限,暂不能实现每个上传文件都显示进度条,只能实现一个总的进度条,效果如图:
1、jsp 页面
<!DOCTYPE html><%@ page contentType="text/htmlcharset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
<script src="../js/jquery-1.6.4.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="../css/bootstrap.css"/>
</head>
<body>
<form id='fForm' class="form-actions form-horizontal" action="../upload.html"
encType="multipart/form-data" target="uploadf" method="post">
<div class="control-group">
<label class="control-label">上传文件:</label>
<div class="controls">
<input type="file" name="file" style="width:550">
</div>
<div class="controls">
<input type="file" name="file" style="width:550">
</div>
<div class="controls">
<input type="file" name="file" style="width:550">
</div>
<label class="control-label">上传进度:</label>
<div class="controls">
<div class="progress progress-success progress-striped" style="width:50%">
<div id = 'proBar' class="bar" style="width: 0%"></div>
</div>
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="button" id="subbut" class="btn">submit</button>
</div>
</div>
</form>
<iframe name="uploadf" style="display:none"></iframe>
</body>
</html>
<script >
$(document).ready(function(){
$('#subbut').bind('click',
function(){
$('#fForm').submit()
var eventFun = function(){
$.ajax({
type: 'GET',
url: '../process.json',
data: {},
dataType: 'json',
success : function(data){
$('#proBar').css('width',data.rate+''+'%')
$('#proBar').empty()
$('#proBar').append(data.show)
if(data.rate == 100){
window.clearInterval(intId)
}
}})}
var intId = window.setInterval(eventFun,500)
})
})
</script>
2、java 代码
package com.controller
import java.util.List
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpSession
import org.apache.commons.fileupload.FileItemFactory
import org.apache.commons.fileupload.ProgressListener
import org.apache.commons.fileupload.disk.DiskFileItemFactory
import org.apache.commons.fileupload.servlet.ServletFileUpload
import org.apache.log4j.Logger
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.servlet.ModelAndView
@Controller
public class FileUploadController {
Logger log = Logger.getLogger(FileUploadController.class)
/**
* upload 上传文件
* @param request
* @param response
* @return
* @throws Exception
*/
@RequestMapping(value = "/upload.html", method = RequestMethod.POST)
public ModelAndView upload(HttpServletRequest request,
HttpServletResponse response) throws Exception {
final HttpSession hs = request.getSession()
ModelAndView mv = new ModelAndView()
boolean isMultipart = ServletFileUpload.isMultipartContent(request)
if(!isMultipart){
return mv
}
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory()
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory)
upload.setProgressListener(new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int pItems) {
ProcessInfo pri = new ProcessInfo()
pri.itemNum = pItems
pri.readSize = pBytesRead
pri.totalSize = pContentLength
pri.show = pBytesRead+"/"+pContentLength+" byte"
pri.rate = Math.round(new Float(pBytesRead) / new Float(pContentLength)*100)
hs.setAttribute("proInfo", pri)
}
})
List items = upload.parseRequest(request)
// Parse the request
// Process the uploaded items
// Iterator iter = items.iterator()
// while (iter.hasNext()) {
// FileItem item = (FileItem) iter.next()
// if (item.isFormField()) {
// String name = item.getFieldName()
// String value = item.getString()
// System.out.println("this is common feild!"+name+"="+value)
// } else {
// System.out.println("this is file feild!")
// String fieldName = item.getFieldName()
// String fileName = item.getName()
// String contentType = item.getContentType()
// boolean isInMemory = item.isInMemory()
// long sizeInBytes = item.getSize()
// File uploadedFile = new File("c://"+fileName)
// item.write(uploadedFile)
// }
// }
return mv
}
/**
* process 获取进度
* @param request
* @param response
* @return
* @throws Exception
*/
@RequestMapping(value = "/process.json", method = RequestMethod.GET)
@ResponseBody
public Object process(HttpServletRequest request,
HttpServletResponse response) throws Exception {
return ( ProcessInfo)request.getSession().getAttribute("proInfo")
}
class ProcessInfo{
public long totalSize = 1
public long readSize = 0
public String show = ""
public int itemNum = 0
public int rate = 0
}
}
开始页面:start.jsp<%@ page contentType="text/htmlcharset=GBK" %>
<% session.removeAttribute("task")%>
<jsp:useBean id="task" scope="session" class="progress.TaskBean"/>
<% task.setRunning(true)%>
<% new Thread(task).start()%>
<jsp:forward page="status.jsp"/>
状态页面:status.jsp
<%@ page contentType="text/htmlcharset=GBK" %>
<jsp:useBean id="task" scope="session" class="progress.TaskBean"/>
<HTML>
<HEAD>
<TITLE>JSP进度条</TITLE>
<% if (task.isRunning()) { %>
<script type="" LANGUAGE="JavaScript">
setTimeout("location='status.jsp'", 1000)
</script>
<% } %>
</HEAD>
<bODY bgcolor="">
<H1 ALIGN="CENTER">JSP进度条</H1>
<H2 ALIGN="CENTER">
结果: <%= task.getResult() %><BR>
<% int percent = task.getPercent()%>
<%= percent %>%
</H2>
<TABLE WIDTH="60%" ALIGN="CENTER"
CELLPADDING=0 CELLSPACING=2>
<TR>
<% for (int i = 10i <= percenti += 10) { %>
<TD WIDTH="10%" height="10" BGCOLOR="red"></TD>
<% } %>
<% for (int i = 100i >percenti -= 10) { %>
<TD WIDTH="10%"></TD>
<% } %>
</TR>
</TABLE>
<TABLE WIDTH="100%" BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR>
<TD ALIGN="CENTER">
<% if (task.isRunning()) { %>
正在执行
<% } else { %>
<% if (task.isCompleted()) { %>
完成
<% } else if (!task.isStarted()) { %>
尚未开始
<% } else { %>
已停止
<% } %>
<% } %>
</TD>
</TR>
<TR>
<TD ALIGN="CENTER">
<BR>
<% if (task.isRunning()) { %>
<FORM METHOD="GET" ACTION="stop.jsp">
<INPUT TYPE="SUBMIT" ="停止">
</FORM>
<% } else { %>
<FORM METHOD="GET" ACTION="start.jsp">
<INPUT TYPE="SUBMIT" ="开始">
</FORM>
<% } %>
</TD>
</TR>
</TABLE>
</BODY></HTML>
停止页面:stop.jsp
<%@ page contentType="text/htmlcharset=GBK" %>
<jsp:useBean id="task" scope="session" class="progress.TaskBean"/>
<% task.setRunning(false)%>
<jsp:forward page="status.jsp"/>
业务逻辑bean:TaskBean.java
package progress
import java.io.Serializable
public class TaskBean
implements Runnable, Serializable {
private int counter
private int sum
private boolean started
private boolean running
private int sleep
public TaskBean() {
counter = 0
sum = 0
started = false
running = false
sleep = 100
}
protected void work() {
try {
Thread.sleep(sleep)
counter++
sum += counter
}
catch (InterruptedException e) {
setRunning(false)
}
}
public synchronized int getPercent() {
return counter
}
public synchronized boolean isStarted() {
return started
}
public synchronized boolean isCompleted() {
return counter == 100
}
public synchronized boolean isRunning() {
return running
}
public synchronized void setRunning(boolean running) {
this.running = running
if (running) {
started = true
}
}
public synchronized Object getResult() {
if (isCompleted()) {
return new Integer(sum)
}
else {
return null
}
}
public void run() {
try {
setRunning(true)
while (isRunning() &&!isCompleted()) {
work()
}
}
finally {
setRunning(false)
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)