Java实现上传图片功能

[an error occurred while processing the directive]

以本产品的上传商品图片为例,它包含了”上传图片后的预览”、”清空预览图片”、”保存图片"三个部分。上传图片后,先将图片文件临时存放到session中,如果需要保存图片,再从session中获取到文件并保存到服务器。

1、 上传图片预览

上传图片预览实现了上传图片,并且在页面显示图片,此时还没有在服务器完成修改操作:

(1) 上传图片HTML代码。

支持100k大小的
jpg、png、jpeg格
式图片

(2) 上传图片js代码。

使用到了Layui框架的upload模块。upload.render函数设置请求后端的url、允许的图片类型、图片大小等信息:

//上传商品图片

var uploadCommImage = upload.render({

elem: '#uploadImage',

url: commPictureUpload_url,

accept: 'images',

acceptMime: 'image/jpg, image/jpeg, image/png',

exts: 'jpg|jpeg|png',

size: 100,

before: function (obj) {

//预读本地文件示例,不支持ie8

obj.preview(function (index, file, result) {

$('#commImage').attr('src', result); //图片链接(base64

});

},

done: function (res) {

bDesertLastOperation = false;

$("input[name='lastOperationToPicture']").val(LAST_OPERATION_TO_PICTURE_Upload);

if (res.ERROR == "EC_NoError") { //上传成功

var msg = res.msg == "" ? "上传图片成功" : res.msg;

return layer.msg(msg);

} else { //上传失败

var msg = res.msg == "" ? "上传图片失败" : res.msg;

return layer.msg(msg);

}

},

error: function (index, upload) {

//演示失败状态,并实现重传

var demoText = $('#hintText');

demoText.html('上传失败重试');

demoText.find('.demo-reload').on('click', function () {

uploadCommImage.upload();

});

}

});

(3) 后端接收前端传递的图片。

使用了Spring的MultipartFile来接收上传的图片文件:

/** 上传图片到D:/nbr/pic/private_db/companyX/tempXXXXXX.jpg(png/jpeg),临时保存之。

* 此时,还未确定图片的名字,所以命名带有temp字眼。这个临时文件的路径和MultipartFile对象被保存在会话中,给后面的操作使用

* 之后,用户可能创建、修改、删除商品,这个临时文件将会被处理,比如重命名为138.jpg,对应商品F_ID=138 */

@RequestMapping(value = "/uploadPictureEx", method = RequestMethod.POST)

@ResponseBody

public Map uploadPictureEx(@ModelAttribute("SpringWeb") Commodity commodity, ModelMap model, HttpServletRequest req, @RequestParam("file") MultipartFile file) {

if (!canCallCurrentAction(req.getSession(), BaseAction.EnumUserScope.STAFF.getIndex())) {

logger.debug("无权访问本Action");

return null;

}

(4) 清空session中的商品图片信息。

上传的图片文件还有它应存放的位置信息我们是把它们存放在session当中的,所以如果之前有上传过,需要先清空:

// 清空会话,确保session不受污染

req.getSession().removeAttribute(EnumSession.SESSION_CommodityPictureDestination.getName());

req.getSession().removeAttribute(EnumSession.SESSION_PictureFILE.getName());

(5) 检查文件的类型、大小。

String fileName = file.getOriginalFilename();

String picType = "image/" + fileName.substring(fileName.lastIndexOf(".") + 1);

if (!picType.equals(JPEGType) && !picType.equals(PNGType) && !picType.equals(JPGType)) {

logger.error("商品图片的类型不对。当前类型为:" + picType);

map.put(BaseAction.JSON_ERROR_KEY, EnumErrorCode.EC_OtherError.toString());

map.put(KEY_HTMLTable_Parameter_msg, "商品图片的类型必须是.jpg/.jpeg/.png格式");

break;

}

Long size = file.getSize();

ErrorInfo ecOut = new ErrorInfo();

ConfigGeneral commodityLogoVolumeMax = (ConfigGeneral) CacheManager.getCache(company.getDbName(), EnumCacheType.ECT_ConfigGeneral).read1(BaseCache.CommodityLogoVolumeMax, getStaffFromSession(req.getSession()).getID(), ecOut,

company.getDbName());

if (size <= 0 || size > Long.parseLong(commodityLogoVolumeMax.getValue())) {

logger.error("商品图片大小不能超过100K。当前size=" + size);

map.put(KEY_HTMLTable_Parameter_msg, "商品图片大小不能超过100K");

(6) 检查磁盘的空间大小。

/** 检查磁盘空间是否足够和存储路径是否存在 */

public static boolean checkDiskSpaceAndCreateFolder(Map params, String path) {

File diskPath = new File(Disk);

if (!diskPath.exists()) {

logger.error("该路径不存在:" + diskPath);

params.put(BaseAction.KEY_HTMLTable_Parameter_msg, "服务器错误");

params.put(BaseAction.JSON_ERROR_KEY, EnumErrorCode.EC_OtherError.toString());

return false;

}

ErrorInfo ecOut = new ErrorInfo();

BxConfigGeneral extraDiskSpaceSize = (BxConfigGeneral) CacheManager.getCache(BaseAction.DBName_Public, EnumCacheType.ECT_BXConfigGeneral).read1(BaseCache.EXTRA_DISK_SPACE_SIZE, BaseBO.SYSTEM, ecOut, BaseAction.DBName_Public);

long minUsablePatitionSpace = 1;

logger.info("磁盘可用空间为:" + diskPath.getUsableSpace() / (1024 * 1024 * 1024) + "GB");

if (diskPath.getUsableSpace() - Integer.valueOf(extraDiskSpaceSize.getValue()) < minUsablePatitionSpace) {

logger.error("磁盘空间不足!");

params.put(BaseAction.KEY_HTMLTable_Parameter_msg, "服务器错误");

params.put(BaseAction.JSON_ERROR_KEY, EnumErrorCode.EC_OtherError.toString());

return false;

}

// 判断文件夹是否存在,如果不存在,创建相应的文件夹,String1传回来DBName

File uploadDir = new File(path);

if (!uploadDir.exists()) {

uploadDir.mkdirs();

}

return true;

}

(7) 设置图片的存放位置。

String path = BaseAction.CommodityPictureDir;

logger.info("商品图片上传路径:" + path);

(8) 定义图片的临时名称。

根据文件的类型定义文件的临时名称pictureName,如temp12345.jpg:

// 判断是jpg还是png类型,上传名称。如果多个线程在这里写,会存在隐患:出现相同的临时图片文件,不同的商品引用相同的图片

String pictureName = "";

if (picType.contains(JPGType)) {

pictureName = "temp" + System.currentTimeMillis() % 1000000 + ".jpg";

} else if (picType.contains(PNGType)) {

pictureName = "temp" + System.currentTimeMillis() % 1000000 + ".png";

} else {

pictureName = "temp" + System.currentTimeMillis() % 1000000 + ".jpeg";

}

(9) 根据存放位置构建File对象。

File commodityPictureDestination = new File(path + "/" + company.getDbName() + "/" + pictureName);

(10) 将图片信息保存在session中。

req.getSession().setAttribute(EnumSession.SESSION_CommodityPictureDestination.getName(), commodityPictureDestination);

req.getSession().setAttribute(EnumSession.SESSION_PictureFILE.getName(), file);

(11) 前端效果图。

2、 保存图片(1) 更新数据库图片位置信息。从session中获取图片文件位置信息,设置商品对象图片位置,最后更新数据库对应商品的图片位置字段:

Commodity commodity = (Commodity) baseModel;

// ... 截取参数和handleCreateEx()中类似。

File dest = (File) req.getSession().getAttribute(EnumSession.SESSION_CommodityPictureDestination.getName());

// 处理商品图片字段

int lastOperationToPicture = commodity.getLastOperationToPicture();

switch (lastOperationToPicture) {

case LAST_OPERATION_TO_PICTURE_Upload:

if (dest != null) {

StringBuilder filePath = new StringBuilder(dest.getPath().replaceAll("\\\\", "/"));// filePath一定形如d:/nbr/pic/nbr_MYJ/18.jpg

for (int i = 0; i < DIR.length(); i++) {

filePath.setCharAt(i, Character.toLowerCase(filePath.charAt(i)));// 确保下面的替换真正替换到东西

}

logger.debug("filePath=" + filePath.toString());

String commPictureDir = filePath.toString().replaceAll(DIR, "/p");

commodity.setPicture(commPictureDir);

}

break;

case LAST_OPERATION_TO_PICTURE_None:

commodity.setPicture(FLAG_WillNotUpdatePictureInSP);

break;

case LAST_OPERATION_TO_PICTURE_Clear:

(2) 从session中拿到MultipartFile file文件对象。

// 上传图片(如果有)

MultipartFile file = (MultipartFile) req.getSession().getAttribute(EnumSession.SESSION_PictureFILE.getName());

if (dest != null && file != null) {

renameCommodityPicture(req, dbName, bmFromDB, dest, file, ec);

}

(3) 判断磁盘是否已经有该图片文件,如果有则删除。

// 现在传入的文件是否已经存在,如果有删除该文件

do {

File file5 = new File(BaseAction.CommodityPictureDir + dbName + "/" + bm.getID() + ".jpg");

if (file5.exists()) {

file5.delete();

break;

}

file5 = new File(BaseAction.CommodityPictureDir + dbName + "/" + bm.getID() + ".jpeg");

if (file5.exists()) {

file5.delete();

break;

}

file5 = new File(BaseAction.CommodityPictureDir + dbName + "/" + bm.getID() + ".png");

if (file5.exists()) {

file5.delete();

break;

}

} while (false);

(4) 将上传的图片保存到磁盘中。

file.transferTo(dest);

(5) 重命名文件名称。此时的文件名还是临时文件名temp12345.jpg,根据商品ID将临时文件重命名:

String commodityPicturePath = BaseAction.CommodityPictureDir + dbName + "/" + bm.getID() + commodityPictureType;

File companyBusinessLicensePictureDestination1 = new File(commodityPicturePath);

dest.renameTo(companyBusinessLicensePictureDestination1);

(6) 清空session中的图片信息。最后清空掉session中的图片信息,释放内存:

// 上传图片成功删除对应session

req.getSession().removeAttribute(EnumSession.SESSION_CommodityPictureDestination.getName());

req.getSession().removeAttribute(EnumSession.SESSION_PictureFILE.getName());

3、清空图片(1) 清空图片js代码。

//清除商品图片

$("#cleanImage").click(function () {

$.ajax({

url: commPictureDelete_url,

type: method_post,

async: true,

dataType: "json",

data: {},

success: function succFunction (data) { //此接口后端不会返回错误码

$('.explain').show();

$('#commImage').attr('src', ' ');

bDesertLastOperation = false;

$("input[name='lastOperationToPicture']").val(LAST_OPERATION_TO_PICTURE_Clear);

},

error: function (XMLHttpRequest, textStatus, errorThrown) {

layer.msg(XMLHttpRequest.status + ":" + XMLHttpRequest.statusText);

layer.msg("清空商品图片失败");

}

})

})

(2) 清空图片后端代码,清空session中的图片信息。

logger.info("清空商品图片的session");

session.removeAttribute(EnumSession.SESSION_CommodityPictureDestination.getName());

session.removeAttribute(EnumSession.SESSION_PictureFILE.getName());

(3) 更新数据库图片信息。清空图片后,如果要保存修改,后端就将商品图片设置为空,并更新数据库。

case LAST_OPERATION_TO_PICTURE_Clear:

case LAST_OPERATION_TO_PICTURE_None:

default:

commodity.setPicture("");

break;

}

List> bmFromDB = null;

DataSourceContextHolder.setDbName(dbName);

bmFromDB = commodityBO.createObjectEx(getStaffFromSession(req.getSession()).getID(), iUseCaseID, baseModel);

(4) 配置虚拟映射路径。 如果在tomcat服务器上部署,并且想把代码和上传的图片分离开,那么需要配置tomcat虚拟映射路径才能访问到图片。在pom.xml文件中配置了tomcat虚拟映射路径:

/p

D:/nbr/pic

false

true

新建p.xml,配置映射,path 为虚拟目录 docBase 为实际目录:

[an error occurred while processing the directive]

Copyright © 2088 2010年南非世界杯_韩国世界杯 - sopeiyin.com All Rights Reserved.
友情链接