框架:ssm
图片服务器:FastDFSClient
前端:
(1)item-add.jsp:
<script type="text/javascript" src="/js/F_File1.2.js"></script>
<link rel="stylesheet" type="text/css" href="/css/font-style.css">
<style type="text/css">
#js-pre {
width: 500px;
border: 1px solid #ccc;
}
#js-pre:after {
content: '';
display: block;
height: 0;
visibility: hidden;
clear: both;
}
.img-box {
float: left;
}
.img-border {
position: relative;
box-sizing: border-box;
height: 100px;
width: 100px;
border: 1px solid #ccc
}
.js-upload_delete {
position: absolute;
top: 0;
right: 0;
}
.red {
font-size: 20px;
color: red;
}
img {
height: 100px;
width: 100%;
}
</style>
<div style="padding:10px 10px 10px 10px">
<form id="itemAddForm" class="itemForm" method="post">
<table cellpadding="5">
<tr>
<td>商品图片:</td>
<td>
<input type="file" name="image1" id="js-file" multiple/> //文件上传框
<input type="hidden" name="image" id="photoUrl"/>
//name的值image与数据库表中的属性一致,用来接收后台处理过的url,且自动映射到数据库中。
<div id="js-pre"> </div> //预览图片
<button id="js-button" type="button">上传</button> //上传按钮
</td>
</tr>
</form>
<div style="padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a>
</a>
</div>
</div>
<script>
/*等比例缩放图片的函数
*param{object} ImgD 需要缩放的图片
*param{number} iwidth 预计图片的宽度
*param{number} iheight 预计的图片的高度
*/
function DrawImage(ImgD,iwidth,iheight){
var image=new Image();//新建一个image
image.src=ImgD.src;//新建的image与传入的image关联,便于调整传入图片的比例
if(image.width>0 && image.height>0){//如果传入图片大于预计图片大小进行等比例缩放 否则不进行能比例缩放
if((image.width/image.height) >= (iwidth/iheight)){
if(image.width>iwidth){//如果宽度大于预计,基于宽度进行等比例缩放
ImgD.width=iwidth;
ImgD.height=(image.height*iwidth)/image.width;
}else{
ImgD.width=image.width;
ImgD.height=image.height;
}
}else{
if(image.height>iheight){//如果传入图片高度大于预计,则基于高度进行等比例缩放
ImgD.height=iheight;
ImgD.width=(image.width*iheight)/image.height;
}else{
ImgD.width=image.width;
ImgD.height=image.height;
}
}
}
}
$(function(){
var f = new FFile({
name: 'image1',
fileInput: '#js-file', //html file控件
upButton: '#js-button', //提交按钮
pre: '#js-pre', //预览地址
url: '/pic/upload', //ajax地址
onSuccess: function(res){
console.log(res)
}, //文件全部上传完毕时
})
})
//提交表单
function submitForm(){
//有效性验证
if(!$('#itemAddForm').form('validate')){
$.messager.alert('提示','表单还未填写完成!');
return ;
}
$.post("/item/save",$("#itemAddForm").serialize(), function(data){
if(data.status == 200){
$.messager.alert('提示','新增商品成功!');
}
});
}
</script>
(2)F_File1.2.js
function FFile(obj) {
this.FileSet = {
name: obj.name? obj.name:null, //唯一名,用来与其他文件区分
fileInput: obj.fileInput?obj.fileInput: null, //html file控件
upButton: obj.upButton? obj.upButton:null, //提交按钮
pre: obj.pre?obj.pre:null, //预览地址
url: obj.url? obj.url:null, //ajax地址
dir: obj.dir?obj.dir:null,
fileFilter: [], //过滤后的文件数组
filter: obj.filter?obj.filter:function(files){
var arrFiles = [];
for (var i = 0, file; file = files[i]; i++) {
if (file.type.indexOf("image") == 0) {
arrFiles.push(file);
} else {
alert('文件"' + file.name + '"不是图片。');
}
}
return arrFiles;
}, //过滤的文件,默认判断如果是图片可以加入临时数组
onSuccess: obj.onSuccess?obj.onSuccess:function(data){
console.log('success');
}, //文件上传成功时
onFailure: obj.onFailure?obj.onFailure:function(data){
console.log('error');
}, //文件上传失败时,
onComplete: obj.onComplete?obj.onComplete:function(){
console.log('complete');
},
}
this.init();
}
FFile.prototype = {
//获取选择文件,file控件或拖放
funGetFiles: function(e) {
// 获取文件列表对象
var files = e.target.files || e.dataTransfer.files;
//继续添加文件
this.FileSet.fileFilter = this.FileSet.fileFilter.concat(this.FileSet.filter(files));
this.funDealFiles();
return this;
},
//选中文件的处理与回调
funDealFiles: function() {
for (var i = 0, file; file = this.FileSet.fileFilter[i]; i++) {
//增加唯一索引值
file.index = i;
}
//执行选择回调
this.onSelect(this.FileSet.fileFilter);
return this;
},
/*
* 对保存在fileFilter的图片,生成预览
* @param file {array} 传递进来的含有所有file的数组
*/
onSelect: function(files) {
var html = '',
self = this,
i = 0;
$(this.FileSet.pre).html();//清空预览地址
var funAppendImage = function() {
file = files[i];
if (file) {
var reader = new FileReader()
reader.onload = function(e) { //生成的图片
html += '<div id="js-uploadList_'+self.FileSet.name+i+'" class="img-box">';
html += '<div class="img-border">';
html += '<span class="js-upload_delete icon-delete_fill red" data-index="'+ i +'"></span>';
html += '<img src="'+e.target.result+'"></img>';
html += '</div>';
html += '</div>';
i++;
funAppendImage();
}
reader.readAsDataURL(file);
} else {
$(self.FileSet.pre).html(html);
if (html) {
//删除方法
$(".js-upload_delete").click(function() {
self.funDeleteFile(files[parseInt($(this).attr("data-index"))]);
return false;
});
}
}
};
funAppendImage();
},
//删除对应的文件
funDeleteFile: function(fileDelete) {
var arrFile = [];
for (var i = 0, file; file = this.FileSet.fileFilter[i]; i++) {
if (file != fileDelete) {
arrFile.push(file);
} else {
this.onDelete(fileDelete);
}
}
this.FileSet.fileFilter = arrFile;
return this;
},
/*
*删除函数
*@param fileDelete {str} 传递过来要删除的File
*/
onDelete: function(file){//清除图片
let self = this;
$("#js-uploadList_" + self.FileSet.name+ file.index).empty();
},
//文件上传
funUploadFile: function() {
var self = this;
if (location.host.indexOf("sitepointstatic") >= 0) {
//非站点服务器上运行
return;
}
var imgArray = [];
var formData = new FormData();
for (var i = 0, file; file = this.FileSet.fileFilter[i]; i++) {
(function(file) {
var formData = new FormData();
formData.append(self.FileSet.name,file);
$.ajax({
url: self.FileSet.url,
type: 'post',
data: formData,
contentType: false,
processData: false,
success: function(data) {
self.FileSet.onSuccess(data);
self.funDeleteFile(file);
//将从后台传回来的data转成json对象
var map = eval('(' + data + ')');
//取json对象中的url
urldata=map.url;
//回调函数
loadData(urldata);
},
error: function(data) {
self.FileSet.onFailure(data);
}
})
if(!self.FileSet.fileFilter.length){
//执行完成
self.FileSet.onComplete();
}
})(file);
}
function loadData(urldata) {
//将url放入数组imgArray中
imgArray.push(urldata);
//将url赋值给id="photoUrl"的输入框
$("#photoUrl").val(imgArray.join(","));
}
},
init: function() {
var self = this;
//判断必须参数是否为空
if(self.FileSet.fileInput == null || self.FileSet.pre == null || self.FileSet.upButton == null) {
console.log('必须提供 input的id 预览区的id 以及 button的id');
return false;
}
//文件选择控件选择
if (self.FileSet.fileInput) {
$(self.FileSet.fileInput).on('change',function(e){
self.funGetFiles(e);
})
}
//上传按钮提交
if (self.FileSet.upButton) {
$(self.FileSet.upButton).on('click', function(e) {
self.funUploadFile(e);
})
}
}
}
后台:
//图片上传
@Controller
public class PictureController {
//取resource.properties中的信息
@Value("${IMAGE_SERVER_URL}")
private String IMAGE_SERVER_URL;
@RequestMapping(value="/pic/upload",method=RequestMethod.POST,produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")
@ResponseBody
public String uploadFile(MultipartFile image1,Model model) {
//将map换成String可解决浏览器不兼容问题
try {
//把图片上传到图片服务器
FastDFSClient fastDFSClient = new FastDFSClient("classpath:conf/client.conf");
//取文件扩展名
String originalFilename = image1.getOriginalFilename();
String extName = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
//得到一个图片的地址和文件名
String url=fastDFSClient.uploadFile(image1.getBytes(), extName);
//补充为完整的url
url=IMAGE_SERVER_URL+url;
//封装到map中返回
Map result=new HashMap<>();
result.put("error", 0);
result.put("url", url);
//解决浏览器不兼容问题
return JsonUtils.objectToJson(result);
}catch(Exception e){
e.printStackTrace();
Map result=new HashMap<>();
result.put("error", 1);
result.put("message", "图片上传失败");
//解决浏览器不兼容问题
return JsonUtils.objectToJson(result);
}
}
}
public class FastDFSClient {
private TrackerClient trackerClient = null;
private TrackerServer trackerServer = null;
private StorageServer storageServer = null;
private StorageClient1 storageClient = null;
public FastDFSClient(String conf) throws Exception {
if (conf.contains("classpath:")) {
conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
}
ClientGlobal.init(conf);
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = null;
storageClient = new StorageClient1(trackerServer, storageServer);
}
/**
* 上传文件方法
* <p>Title: uploadFile</p>
* <p>Description: </p>
* @param fileName 文件全路径
* @param extName 文件扩展名,不包含(.)
* @param metas 文件扩展信息
* @return
* @throws Exception
*/
public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileName, extName, metas);
return result;
}
public String uploadFile(String fileName) throws Exception {
return uploadFile(fileName, null, null);
}
public String uploadFile(String fileName, String extName) throws Exception {
return uploadFile(fileName, extName, null);
}
/**
* 上传文件方法
* <p>Title: uploadFile</p>
* <p>Description: </p>
* @param fileContent 文件的内容,字节数组
* @param extName 文件扩展名
* @param metas 文件扩展信息
* @return
* @throws Exception
*/
public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileContent, extName, metas);
return result;
}
public String uploadFile(byte[] fileContent) throws Exception {
return uploadFile(fileContent, null, null);
}
public String uploadFile(byte[] fileContent, String extName) throws Exception {
return uploadFile(fileContent, extName, null);
}
}
前端多图片上传代码改编自https://www.cnblogs.com/fuckyougod/p/6952065.html.