圖片上傳與刪除
之前寫了一篇博客記錄了關於修改資料中的圖片上傳(傳送門),這次用到了直接上傳圖片的功能,對上一篇博客進行了簡單的優化與改進。
改進問題:
- 之前刪除該數據時,僅僅刪除了數據庫中的數據,而項目下面的圖片文件仍然存在,這就導致以後即使數據庫清空之後,項目文件夾下刪除的圖片記錄仍然存在的問題。
- 直接使用ajax上傳圖片。
1.上傳文件
下面貼一下代碼:
<button type="button" onclick="newPicture()" class="btn btn-primary tab-modify">新增</button>
由於頁面使用了bootscript,CSS功底不好,顯得頁面比較亂,湊合先用着了
<!-- 新增圖片 -->
<div id="tanchuang-tab">
<div class="tanchuang-tab">
<!-- <form id="updateForm"> -->
<form class="form-horizontal over-hd" role="form" id="updateForm"
method="post" enctype="multipart/form-data" action="picture/insertPicture.do">
<div class="kaizhi-box col-xs-12 tanchuang-content"
style="left: 0%;">
<span id="x-close3"
style="margin:0px;position:absolute;right:2%;top:3%;">x</span>
<div class="" style="width: 100%;margin:0 auto;padding-top:20px;">
<div class="form-group"
style="margin-right: 10%;margin-left: 10%;">
<label for="firstname" class="col-sm-5 control-label"
style="font-size: 16px;">所屬管理員:</label>
<div class="col-sm-7">
<input id="pOwner" name="pOwner" style="display:none;"/>
<select id="selectOwner" class="form-control-select"
style="width:100%;height:34px;border: 1px solid #ccc;border-radius:4px">
</select>
</div>
</div>
<div class="form-group" style="margin-left: 24%;" >
<label for="firstname" class="col-sm-3 control-label" style="font-size: 16px;">圖片:</label>
<div class="col-sm-7">
<div id="localImag">
<img id="preview" src=""
width="100" height="100">
</div>
<input type="file" id="inputFile" name="file" accept="image/*"
onchange="javascript:setImagePreview();" />
</div>
</div>
<div class="text-center btn-box">
<button type="button" class="btn btn-primary btn-width"
id="btn-submit3">確定</button>
<button type="button" class="btn btn-primary btn-width"
id="btn-cancel3">取消</button>
</div>
</div>
</div>
</form>
</div>
</div>
js部分:(頁面可以參考上面的傳送連接裏的博客,比較清晰(傳送門))
//下面用於圖片上傳預覽功能
function setImagePreview(avalue) {
var docObj = document.getElementById("inputFile");
var imgObjPreview = document.getElementById("preview");
if (docObj.files && docObj.files[0]) {
//火狐下,直接設img屬性
imgObjPreview.style.display = 'block';
imgObjPreview.style.width = '100px';
imgObjPreview.style.height = '100px';
//imgObjPreview.src = docObj.files[0].getAsDataURL();
//火狐7以上版本不能用上面的getAsDataURL()方式獲取,需要一下方式
imgObjPreview.src = window.URL.createObjectURL(docObj.files[0]);
} else {
//IE下,使用濾鏡
docObj.select();
var imgSrc = document.selection.createRange().text;
var localImagId = document.getElementById("localImag");
//必須設置初始大小
localImagId.style.width = "150px";
localImagId.style.height = "180px";
//圖片異常的捕捉,防止用戶修改後綴來僞造圖片
try {
localImagId.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)";
localImagId.filters
.item("DXImageTransform.Microsoft.AlphaImageLoader").src = imgSrc;
} catch (e) {
alert("您上傳的圖片格式不正確,請重新選擇!");
return false;
}
imgObjPreview.style.display = 'none';
document.selection.empty();
}
return true;
}
// 點擊確認按鈕觸發
$('#btn-submit3').click(function() {
var owner = $('#selectOwner option:selected').val(); // 獲取下拉框裏選中的值
$("#pOwner").val(owner);
var fileObj = document.getElementById("inputFile").files[0]; // js 獲取文件對象
if (typeof (fileObj) == "undefined" || fileObj.size <= 0) {
alert("請選擇上傳的圖片!");
return;
}
var formFile = new FormData();
formFile.append("pOwner", owner);
formFile.append("file", fileObj);
var data = formFile;
$.ajax({
url : 'picture/insertPicture.do',
type : 'post',
dataType : 'json',
data : data,
cache: false, //上傳文件無需緩存
processData: false, // 用於對參數進行序列化處理,這裏必須設爲false
contentType:false, // 必須
success : function(data) {
console.log(data);
if (data.state == 200) {
alert(data.message);
var to = "${pageContext.request.contextPath}/picture/pictureList.do";
doPost(to);
}
if(data.state == 300){
alert("圖片上傳失敗!");
return;
}
}
});
});
$('#btn-cancel3').click(function() {
console.log("2222");
$("#selectOwner").find("option").remove();
//var name = $("#inputFile").val();
//$("#inputFile").val(null);
//$("#preview").src(null);
var obj = document.getElementById('inputFile') ;
obj.outerHTML=obj.outerHTML;
$('#tanchuang-tab').hide();
});
// 使用post提交訪問請求
function doPost(to){
//to爲跳轉鏈接
var myForm = document.createElement("form");
myForm.method = "post";
myForm.action = to;
document.body.appendChild(myForm); //
myForm.submit();
document.body.removeChild(myForm); // 提交後移除創建的form
}
使用ajax提交表單可能都不陌生了,但是當表單裏存在文件時,ajax普通的寫法就會報錯了,這裏的寫法是參考網上的資料整理的,
這裏利用FormData對象來將數據封裝起來,其中pOwner是from裏提交的另一個參數
var formFile = new FormData();
formFile.append("pOwner", owner);
formFile.append("file", fileObj);
在ajax中processData: false
必須false纔會避開jQuery對 formdata 的默認處理
java後臺的東西
我這裏將初始文件名也保存到數據庫裏了,picture_url裏存的是圖片的路徑和名稱,這是存在了項目根目錄的upload文件夾下面了。
在展示的時候,展示的圖片名稱是上傳的文件名,而圖片的顯示卻不能用文件名來顯示,因爲上傳的文件如果出現重名的的話,將影響圖片的回顯。這裏我使用UUID給圖片重命名,或者使用MD5對當前時間進行加密,然後取值作爲圖片名稱,這樣圖片就可以避免重名的問題了。每張圖片都是唯一標識的。
首先是Controller類:
@RequestMapping("insertPicture")
@ResponseBody
public JsonResult<String> insertPicture(@RequestParam(value="file")MultipartFile pictureFile,HttpServletRequest request, String pOwner) throws IOException{
System.out.println("pOwner:" + pOwner);
// pictureURL是數據庫裏picture_url的值,這裏用到一個封裝的工具類UploadUtil
String pictureURL= UploadUtil.imageUpload(pictureFile, request);
System.out.println("pictureURL:" + pictureURL);
//獲取上傳時的文件名
String pictureName = FilenameUtils.getName(pictureFile.getOriginalFilename());
System.out.println("pictureName:" + pictureName);
// 把圖片數據保存到數據庫
Picture picture = new Picture();
picture.setPictureName(pictureName);
picture.setPictureUrl(pictureURL);
picture.setPictureOwner(pOwner);
int insert = pictureService.insert(picture);
if (insert > 0 && pictureURL != "") {
return new JsonResult<>(200, "上傳成功!", null);
}
return new JsonResult<>(300, "上傳失敗", null);
}
上傳文件工具類:UploadUtil.java
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
public class UploadUtil {
public static String imageUpload(@RequestParam(value="file") MultipartFile file,HttpServletRequest req){
// 獲取要上傳的目標位置,即是項目的upload文件夾所在的絕對路徑
String path = req.getSession().getServletContext().getRealPath("upload");
// 獲取文件的擴展名
String ext = FilenameUtils.getExtension(file.getOriginalFilename());
String filename = UUID.randomUUID().toString().replaceAll("-", "")+"."+ ext;
// 寫入文件成功之後,返回的數據,也就是數據庫裏要存的文件的url
String src="upload/"+filename;
File targetFile= new File(path,filename);
try {
if(!targetFile.exists()){
//寫入文件
file.transferTo(targetFile);
}
return src;
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//寫入文件失敗,則返回空字符串
return "";
}
}
返回的JSON工具類:JsonResult.java
import java.io.Serializable;
/**
* 用於封裝服務器到客戶端的Json返回值
*
* @author soft01
*
*/
public class JsonResult<T> implements Serializable {
// Serializable將對象的狀態保存在存儲媒體中以便可以在以後重新創建出完全相同的副本
public static final int SUCCESS = 0;
public static final int ERROR = 1;
public static final int OTHER = 2;
private int state;
private String message = "";
private T data;
private String pass = "";
public JsonResult() {
state = SUCCESS;
}
// 爲了方便,重載n個構造器
public JsonResult(int state, String message, T data) {
super();
this.state = state;
this.message = message;
this.data = data;
}
public JsonResult(int state, String error) {
this(state, error, null);
}
public JsonResult(int state, T data) {
this(state, "", data);
}
public JsonResult(String error) {
this(ERROR, error, null);
}
public JsonResult(T data) {
this(SUCCESS, "", data);
}
public JsonResult(int state) {
this(state, "", null);
}
public JsonResult(Throwable e) {
this(ERROR, e.getMessage(), null);
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static int getSuccess() {
return SUCCESS;
}
public static int getError() {
return ERROR;
}
@Override
public String toString() {
return "JsonResult [state=" + state + ", message=" + message
+ ", pass=" + pass + ", data=" + data + "]";
}
}
到這裏文件上傳就算完成了,這時可以檢查數據庫中的值和項目文件夾下是否有上傳的圖片了。
數據庫裏的數據:
2.刪除數據,並且刪除對應的文件
根據圖片的id刪除圖片,前臺傳來圖片的Id,後臺查詢獲得對應圖片的url,進行截取文件名,然後遍歷圖片文件夾,最後刪除。
前臺頁面:
<table class="table table-hover"
style="border-bottom: 1px solid #ccc;text-align:center">
<thead>
<tr>
<th style="display:none;">ID</th>
<th>預覽</th>
<th>圖片名</th>
<th>所屬管理員</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${pageInfo.list }" var="picture">
<tr>
<td style="display:none;">${picture.id}</td>
<td><img src="<%=basePath%>${picture.pictureUrl}" width="90px" height="90px" /></td>
<td>${picture.pictureName }</td>
<td>${picture.pictureOwner }</td>
<td><button type="button"
onclick="delPicture(${picture.id})"
class="btn btn-primary tab-modify">刪除</button></td>
</tr>
</c:forEach>
</tbody>
</table>
function delPicture(pictureId) {
if (!confirm("確定要刪除嗎?"))
return;
$.ajax({
url : 'picture/delPictureById.do',
data : {
'pictureId' : pictureId
},
type : 'post',
dataType : 'json',
success : function(data) {
alert(data.message);
window.location.reload();
}
});
}
java後臺:
/**
* 刪除圖片
* @param pictureId
* @param request
* @return
*/
@RequestMapping("delPictureById")
@ResponseBody
public JsonResult<String> delPictureById(String pictureId, HttpServletRequest request){
Integer Id = Integer.valueOf(pictureId);
String realPath = request.getServletContext().getRealPath("upload");
System.out.println(realPath);
Picture picture = pictureService.selectByPrimaryKey(Id);
System.out.println("picture:" + picture);
if (picture != null) {
String picUrl = picture.getPictureUrl();
System.out.println("picUrl:" + picUrl);
//獲取文件名,用於後面的遍歷查找刪除
String name = picUrl.substring(7);
System.out.println(name);
//獲取目標文件夾:項目中圖片所在的絕對路徑
File folder = new File(realPath);
File[] files = folder.listFiles();
for(File file : files){
if (file.getName().equals(name)) {
boolean delete = file.delete();
if (delete) {
int i = pictureService.deleteByPrimaryKey(Id);
if (i > 0) {
return new JsonResult<>(200, "刪除成功!", null);
}
}
}
}
}
return new JsonResult<>(300, "刪除失敗!", null);
}
至此,刪除圖片就結束了,刪除之後,可以檢查一下,upload文件夾下是否還存在相應的文件。