实现原理:利用ajaxfileupload.js + springmvc进行图片文件的上传,再利用base64编码技术得到图片的编码字符串,并返回到页面进行img预览。还可以吧编码字符串存入数据库,较大文件不建议存入数据库。(需要jquery支持)
js代码:
/**
* 图片上传
*/
function ajaxFileUpload() {
$.ajaxFileUpload({
url:'../../../hr/upload.do', //需要链接到服务器地址
secureuri:false,
fileElementId:'file', //文件选择框的id属性
dataType: 'json', //服务器返回的格式类型
success: function (data, status) //成功
{
var json = eval("("+data+")");//解析返回的json
var imageCode = json.imageCode;
if(imageCode!='-1'){
$("#showImg").attr("src", imageCode);
$("#input_photo").val(imageCode);
}else{
alert("上传失败!只允许上传图片类型(jpg,gif,png)且小于1M的照片");
}
},
error: function (data, status, e) //异常
{
alert("出错了,请重新上传!");
}
});
}
java代码:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import com.cpeam.hr.util.ImageUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* 图片上传控制器
* @author tanfei
* @date 2013-09-23
*/
@Controller
@RequestMapping("/hr")
public class ImgUploadAction {
@RequestMapping(value="uploadImg")
public void uploadImg() {
}
/**
* 上传
* @param file
* @param request
* @param model
* @return
*/
@RequestMapping(value="/upload",method=RequestMethod.POST)
public void fileUpload(@RequestParam("file")CommonsMultipartFile file,HttpServletRequest request
,HttpServletResponse response){ //图片文件上传
Map<String, Object> resMap = new HashMap<String, Object>();
String imageCode = "-1";//默认上传失败
/**判断文件是否为空,空直接返回上传错误**/
if(!file.isEmpty()){
//获得文件后缀名
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
if(suffix.equals(".jpg") || suffix.equals(".gif") || suffix.equals(".png")) {//检测图片类型
if(file.getSize() > 1000000) {
imageCode = "-1";
//throw new Exception("上传失败:文件大小不能超过1M");
}else {
try {
//将上传的图片转换成base64编码字符串
imageCode = "data:image/gif;base64," + ImageUtil.encodeImageToStr(file.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}else{
imageCode = "-1";
}
resMap.put("imageCode", imageCode);
response.setContentType("text/html;charset=UTF-8");//指定响应内容类型,避免<pre...
try {
PrintWriter out = response.getWriter();
Gson gson = new GsonBuilder().create();
String gsonStr = gson.toJson(resMap);
out.write(gsonStr);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
springmvc文件配置:
<!-- 文件上传相关start tanfei 2013-09-20-->
<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 指定所上传文件的总大小不能超过200KB。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->
<property name="maxUploadSize" value="200000"/>
</bean>
<!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->
<!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 -->
<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop>
<prop key="java.lang.Exception">error_all</prop>
</props>
</property>
</bean>
<!-- 文件上传相关end -->
jquery插件ajaxfileupload.js:
jQuery.extend({
createUploadIframe: function(id, uri)
{
//create frame
var frameId = 'jUploadFrame' + id;
var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';
if(window.ActiveXObject)
{
if(typeof uri== 'boolean'){
iframeHtml += ' src="' + 'javascript:false' + '"';
}
else if(typeof uri== 'string'){
iframeHtml += ' src="' + uri + '"';
}
}
iframeHtml += ' />';
jQuery(iframeHtml).appendTo(document.body);
return jQuery('#' + frameId).get(0);
},
createUploadForm: function(id, fileElementId,data)
{
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
var oldElement = jQuery('#' + fileElementId);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
/***** 增加参数的支持 *****/
if (data) {
for (var i in data) {
$('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
}
}
//set attributes
jQuery(form).css('position', 'absolute');
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body');
return form;
},
ajaxFileUpload: function(s) {
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s);
var id = new Date().getTime();
// ADD s.data
var form = jQuery.createUploadForm(id, s.fileElementId, s.data);
var io = jQuery.createUploadIframe(id, s.secureuri);
var frameId = 'jUploadFrame' + id;
var formId = 'jUploadForm' + id;
// Watch for a new set of requests
if ( s.global && ! jQuery.active++ )
{
jQuery.event.trigger( "ajaxStart" );
}
var requestDone = false;
// Create the request object
var xml = {}
if ( s.global )
jQuery.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
var uploadCallback = function(isTimeout)
{
var io = document.getElementById(frameId);
try
{
if(io.contentWindow)
{
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)
{
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")
{
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 );
// 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()
setTimeout(function()
{ try
{
jQuery(io).remove();
jQuery(form).remove();
} 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);
jQuery(form).attr('method', 'POST');
jQuery(form).attr('target', frameId);
if(form.encoding)
{
jQuery(form).attr('encoding', 'multipart/form-data');
}
else
{
jQuery(form).attr('enctype', 'multipart/form-data');
}
jQuery(form).submit();
} catch(e)
{
jQuery.handleError(s, xml, null, e);
}
jQuery('#' + frameId).load(uploadCallback );
return {abort: function () {}};
},
/** handleError 方法在jquery1.4.2之后移除了,此处重写改方法 **/
handleError: function( s, xhr, status, e ) {
// If a local callback was specified, fire it
if ( s.error ) {
s.error.call( s.context || s, xhr, status, e );
}
// Fire the global callback
if ( s.global ) {
(s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
}
},
uploadHttpData: function( r, type ) {
//alert("-->" + r.responseText);
try{
//debugger;
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" ){
/*** 如果返回的是字符串(JSON格式字符串),下面会报错,导致无法走入sucess方法 加上\" ***/
// eval( "data = " + data );
eval("data = \" "+data+" \" ");
}
// evaluate scripts within html
if ( type == "html" ){
jQuery("<div>").html(data).evalScripts();
}
}catch(e) {
}
return data;
}
})