1.需要提前准备好的配置文件
1>配置文件web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>testmavenspringmvc</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 全局初始化数据,spring的监听器读取此配置文件
多个配置文件用分号分隔 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring.xml</param-value>
</context-param>
<!-- spring容器初始化的监听器,会读取全局初始化的数据(xml文件) -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- spring处理中文乱码问题 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- restful和非restful虽然能并存,但实际开发中,二者选其一 -->
<!-- spring mvc的入口 加载spring mvc 前端控制器 非restful-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring_mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- spring mvc的入口 加载spring mvc 前端控制器 restful -->
<!-- restful模式,必须注意在spring-mvc.xml中配置,刨除静态资源 -->
<servlet>
<servlet-name>dispatcher_restful</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher_restful</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2>spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 在restful模式下,添加静态资源 -->
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
<mvc:resources location="/" mapping="/**"></mvc:resources>
<!-- 扫描spring的组件 -->
<context:component-scan base-package="com.tarena.controller"></context:component-scan>
<!-- 扫描 spring mvc的注解 @RequestMapping @ResponseBody -->
<mvc:annotation-driven></mvc:annotation-driven>
<!--拦截器的配置部分-->
<mvc:interceptors>
<mvc:interceptor>
<!--需要拦截的地址-->
<mvc:mapping path="/**" />
<!--不需要拦截的地址-->
<mvc:exclude-mapping path="/login_restful.html" />
<mvc:exclude-mapping path="/js/**" />
<mvc:exclude-mapping path="/user_restful/**" />
<!--定义拦截器类-->
<bean class="com.tarena.interceptor.SecurityInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- spring mvc处理响应的jsp -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--能配置多少个property,可以查文档和查询源代码 -->
<!--最大上传文件的大小 -->
<property name="maxUploadSize" value="8388608"></property>
<property name="resolveLazily" value="true"></property>
</bean>
</beans>
2.表单提交
1>html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div style="text-align:center;">
<form action="fileupload/upload.do" method="post" enctype="multipart/form-data">
<input type="text" name="fileDesc" /><br />
<input type="file" name="fileName" /><br />
<input type="submit" value="上传" />
</form>
</div>
</body>
</html>
2>controller中的代码
@Controller
@RequestMapping("/fileupload")
public class UploadController {
@RequestMapping(value = "/upload.do", method = RequestMethod.POST)
public String upload(@RequestParam(value = "fileName", required = false) MultipartFile file,
@RequestParam(value = "fileDesc") String desc, HttpServletRequest request, ModelMap model) {
String result = "error";
System.out.println("fileDesc=" + desc);
// 准备出文件上传到服务器中的哪个目录中
String realPath = request.getServletContext().getRealPath("/upload");
File realPathFile = new File(realPath);
if (!realPathFile.exists())
realPathFile.mkdir();
// 判断文件是否为空
if (!file.isEmpty()) {
// 获取上传文件的信息
String orifileName = file.getOriginalFilename();
System.out.println("原始文件名=" + orifileName);
String contentType = file.getContentType();
System.out.println("原始文件类型=" + contentType);
String name = file.getName();
System.out.println("表单元素的名字=" + name);
long size = file.getSize();
System.out.println("文件的容量=" + size);
try {
if (!"image/png".equals(contentType)) {
// 保存文件
file.transferTo(new File(realPath, orifileName));
// 构建页面提示信息
String message = "文件上传成功,文件的位置" + request.getContextPath() + "/upload/" + orifileName;
model.addAttribute("message", message);
result = "success";
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
model.addAttribute("message", "文件上传失败");
}
}
return result;
}
}
3.ajax实现文件上传
1>js文件
jQuery.extend({createUploadIframe: function (id, uri) {//id为当前系统时间字符串,uri是外部传入的json对象的一个参数
//create frame
var frameId = 'jUploadFrame' + id; //给iframe添加一个独一无二的id
var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"'; //创建iframe元素
if (window.ActiveXObject) {//判断浏览器是否支持ActiveX控件
if (typeof uri == 'boolean') {
iframeHtml += ' src="' + 'javascript:false' + '"';
} else if (typeof uri == 'string') {
iframeHtml += ' src="' + uri + '"';
}
}
iframeHtml += ' />';
jQuery(iframeHtml).appendTo(document.body); //将动态iframe追加到body中
return jQuery('#' + frameId).get(0); //返回iframe对象
},
createUploadForm: function (id, fileElementId, data) {//id为当前系统时间字符串,fileElementId为页面<input type='file' />的id,data的值需要根据传入json的键来决定
//create form
var formId = 'jUploadForm' + id; //给form添加一个独一无二的id
var fileId = 'jUploadFile' + id; //给<input type='file' />添加一个独一无二的id
var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data" ></form>'); //创建form元素
if (data) {//通常为false
for (var i in data) {
jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form); //根据data的内容,创建隐藏域,这部分我还不知道是什么时候用到。估计是传入json的时候,如果默认传一些参数的话要用到。
}
} var oldElement = jQuery('#' + fileElementId); //得到页面中的<input type='file' />对象
var newElement = jQuery(oldElement).clone(); //克隆页面中的<input type='file' />对象
jQuery(oldElement).attr('id', fileId); //修改原对象的id
jQuery(oldElement).before(newElement); //在原对象前插入克隆对象
jQuery(oldElement).appendTo(form); //把原对象插入到动态form的结尾处
//set attributes
jQuery(form).css('position', 'absolute'); //给动态form添加样式,使其浮动起来,
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body'); //把动态form插入到body中
return form;
},
ajaxFileUpload: function (s) {//这里s是个json对象,传入一些ajax的参数
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s); //此时的s对象是由jQuery.ajaxSettings和原s对象扩展后的对象
var id = new Date().getTime(); //取当前系统时间,目的是得到一个独一无二的数字
var form = jQuery.createUploadForm(id, s.fileElementId, (typeof (s.data) == 'undefined' ? false : s.data)); //创建动态form
var io = jQuery.createUploadIframe(id, s.secureuri); //创建动态iframe
var frameId = 'jUploadFrame' + id; //动态iframe的id
var formId = 'jUploadForm' + id; //动态form的id
// Watch for a new set of requests
if (s.global && !jQuery.active++) {//当jQuery开始一个ajax请求时发生
jQuery.event.trigger("ajaxStart"); //触发ajaxStart方法
} var requestDone = false; //请求完成标志
// Create the request object
var xml = {}; if (s.global)
jQuery.event.trigger("ajaxSend", [xml, s]); //触发ajaxSend方法
// Wait for a response to come back
var uploadCallback = function (isTimeout) {//回调函数
var io = document.getElementById(frameId); //得到iframe对象
try { if (io.contentWindow) {//动态iframe所在窗口对象是否存在
xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
} else if (io.contentDocument) {//动态iframe的文档对象是否存在
xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
}
} catch (e) {
jQuery.handleError(s, xml, null, e);
} if (xml || isTimeout == "timeout") {//xml变量被赋值或者isTimeout == "timeout"都表示请求发出,并且有响应
requestDone = true; //请求完成
var status; try {
status = isTimeout != "timeout" ? "success" : "error"; //如果不是“超时”,表示请求成功
// Make sure that the request was successful or notmodified
if (status != "error") { // process the data (runs the xml through httpData regardless of callback)
var data = jQuery.uploadHttpData(xml, s.dataType); //根据传送的type类型,返回json对象,此时返回的data就是后台操作后的返回结果
// If a local callback was specified, fire it and pass it the data
if (s.success)
s.success(data, status); //执行上传成功的操作
// Fire the global callback
if (s.global)
jQuery.event.trigger("ajaxSuccess", [xml, s]);
} else
jQuery.handleError(s, xml, status);
} catch (e) {
status = "error";
jQuery.handleError(s, xml, status, e);
} // The request was completed
if (s.global)
jQuery.event.trigger("ajaxComplete", [xml, s]); // Handle the global AJAX counter
if (s.global && ! --jQuery.active)
jQuery.event.trigger("ajaxStop"); // Process result
if (s.complete)
s.complete(xml, status);
jQuery(io).unbind();//移除iframe的事件处理程序
setTimeout(function () {//设置超时时间
try {
jQuery(io).remove();//移除动态iframe
jQuery(form).remove();//移除动态form
} catch (e) {
jQuery.handleError(s, xml, null, e);
}
}, 100)
xml = null
}
} // Timeout checker
if (s.timeout > 0) {//超时检测
setTimeout(function () { // Check to see if the request is still happening
if (!requestDone) uploadCallback("timeout");//如果请求仍未完成,就发送超时信号
}, s.timeout);
} try { var form = jQuery('#' + formId);
jQuery(form).attr('action', s.url);//传入的ajax页面导向url
jQuery(form).attr('method', 'POST');//设置提交表单方式
jQuery(form).attr('target', frameId);//返回的目标iframe,就是创建的动态iframe
if (form.encoding) {//选择编码方式
jQuery(form).attr('encoding', 'multipart/form-data');
} else {
jQuery(form).attr('enctype', 'multipart/form-data');
}
jQuery(form).submit();//提交form表单
} catch (e) {
jQuery.handleError(s, xml, null, e);
}
jQuery('#' + frameId).load(uploadCallback); //ajax 请求从服务器加载数据,同时传入回调函数
return { abort: function () { } };
},
uploadHttpData: function (r, type) { var data = !type;
data = type == "xml" || data ? r.responseXML : r.responseText; // If the type is "script", eval it in global context
if (type == "script")
jQuery.globalEval(data); // Get the JavaScript object, if JSON is used.
if (type == "json")
eval("data = " + data); // evaluate scripts within html
if (type == "html")
jQuery("<div>").html(data).evalScripts(); return data;
}
})
2>ajax.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/common/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="js/ajaxfileupload.js"></script>
<script type="text/javascript" src="js/upload.js"></script>
</head>
<body>
<div style="text-align:center;">
<form id="upload_formid">
<input type="text" name="fileDesc" /><br />
<input id="fileid" type="file" name="fileName" /><br />
<input type="button" value="上传" /><br />
</form>
</div>
</body>
</html>
3>controller中
@RequestMapping(value = "/uploadajax/desc/{desc}", method = RequestMethod.POST)
@ResponseBody
public Result uploadAjax(
@RequestParam(value = "fileName", required = true) MultipartFile file,
@PathVariable(value = "desc") String desc,
HttpServletRequest request,
HttpServletResponse response) {
Result result=null;
PrintWriter out=null;
System.out.println("desc="+desc);
try {
out=response.getWriter();
//指定上传的文件放在哪个目录中
String realPath=request.getServletContext().getRealPath("/upload");
File realPathFile=new File(realPath);
if(!realPathFile.exists()) realPathFile.mkdir();
if(!file.isEmpty()){
String orifileName=file.getOriginalFilename();
file.transferTo(new File(realPath,orifileName));
out.print("上传成功");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
out.print("上传失败");
}
out.close();
return result;
}
}
4表单批量上传
1>upload_batch.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/upload.js"></script>
</head>
<body>
<div style="text-align:center;">
<form method="post"
action="fileupload/uploads.do"
enctype="multipart/form-data">
<table border="1" align="center">
<tr>
<td>上传文件说明</td>
<td><input type="text" name="fileDesc" /></td>
</tr>
<tr>
<td>文件</td>
<td id="more">
<input type="file" name="fileName" />
<input type="button" value="添加..."
οnclick="addMore();"/>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="上传" />
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
2>upload.js
$(function(){
$("#upload_formid input[type=button]").click(function(){
upload_file();
});
});
function upload_file(){
//取出非文件域的内容
var desc=$("#upload_formid input[type=text]").val();
//文件上传
$.ajaxFileUpload({
url:"/testmavenspringmvc/fileupload/uploadajax/desc/"+desc,
secureuri:false,
fileElementId:"fileid",
type:"post",
dataType:"text",
success:function(data,status){
alert(data);
data=data.replace(/<PRE.*?>/g,'');
data=data.replace("<PRE>",'');
data=data.replace("</PRE>",'');
data=data.replace(/<pre.*?>/g,'');
data=data.replace("<pre>",'');
data=data.replace("</pre>",'');
alert(data);
},
error:function(){
alert("请求失败!");
}
});
}
function addMore(){
var td_ele=document.getElementById("more");
var br_ele=document.createElement("br");
var input_file=document.createElement("input");
input_file.type="file";
input_file.name="fileName";
var input_button=document.createElement("input");
input_button.type="button";
input_button.value="删除";
input_button.οnclick=function(){
td_ele.removeChild(input_file);
td_ele.removeChild(input_button);
td_ele.removeChild(br_ele);
};
td_ele.appendChild(br_ele);
td_ele.appendChild(input_file);
td_ele.appendChild(input_button);
}
3>controller
@RequestMapping(value = "/uploads.do", method = RequestMethod.POST)
public String uploads(@RequestParam(value = "fileName", required = false) MultipartFile[] files,
@RequestParam(value = "fileDesc") String desc, HttpServletRequest request, ModelMap model) {
String result = "error";
System.out.println("fileDesc=" + desc);
// 准备出文件上传到服务器中的哪个目录中
String realPath = request.getServletContext().getRealPath("/upload");
File realPathFile = new File(realPath);
if (!realPathFile.exists())
realPathFile.mkdir();
String message="";
// 判断文件是否为空
if (files != null && files.length > 0) {
for (MultipartFile file : files) {
// 获取上传文件的信息
String orifileName = file.getOriginalFilename();
System.out.println("原始文件名=" + orifileName);
String contentType = file.getContentType();
System.out.println("原始文件类型=" + contentType);
String name = file.getName();
System.out.println("表单元素的名字=" + name);
long size = file.getSize();
System.out.println("文件的容量=" + size);
try {
if (!"image/png".equals(contentType)) {
// 保存文件
file.transferTo(new File(realPath, orifileName));
// 构建页面提示信息
message += "文件上传成功,文件的位置"
+ request.getContextPath()
+ "/upload/"
+ orifileName
+"<br />";
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
model.addAttribute("message", "文件上传失败");
}
}
model.addAttribute("message", message);
}
result="success";
return result;
}