今天從慕課網學了如何用java在圖檔上添加水印(包括文字水印和圖檔水印),自己學着寫了一遍了解了下,這裡先寫個簡單的檔案上傳,往後再開始寫水印功能。(也可以去慕課網看相應視訊,連結:http://www.imooc.com/learn/482)。
環境:struts2環境。
一、單檔案上傳。
1、檔案上傳界面主要代碼:index.jsp:
<body>
<h4>上傳圖檔</h4>
<hr />
<form name="uploadFile" action="${pageContext.request.contextPath }/waterMark.action" method="post" enctype="multipart/form-data">
<input type="file" name="image"/><br />
<input type="submit" name="uploadImage" value="上傳圖檔"/>
</form>
</body>
2、配置struts.xml檔案:
<package name="default" extends="struts-default">
<action name="waterMark" class="com.wjl.watermark.WaterMarkAction" method="waterMark">
<param name="uploadPath">/images</param>
<result name="success">waterMark.jsp</result>
</action>
</package>
3、編寫Action代碼:
a、集中處理檔案上傳的WaterMarkAction:
package com.wjl.watermark;
import java.io.File;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class WaterMarkAction extends ActionSupport{
private File image;//上傳的檔案(注意,file并不是指前端jsp上傳過來的檔案本身,而是檔案上傳過來存放在臨時檔案夾下面的檔案)
private String imageFileName;//送出過來的file的名字
private String uploadPath;//檔案上傳的路徑(在struts.xml檔案中進行配置)
private PicInfo pic = new PicInfo();//上傳後的檔案對象
public String waterMark() throws Exception{
String realUploadPath = ServletActionContext.getServletContext().getRealPath(uploadPath);
//上傳圖檔
UploadService uploadService = new UploadService();
pic.setImageURL(uploadService.uploadImage(image, imageFileName, uploadPath, realUploadPath));
return SUCCESS;
}
//image、imageFileName、uploadPath、pic的get/set方法
}
b、進行檔案上傳的UploadService:
package com.wjl.watermark;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class UploadService {
/**
* 該方法用來上傳檔案
* @param image:上傳的圖檔對象
* @param imageFileName:上傳的檔案名稱
* @param uploadPath:上傳檔案的相對路徑
* @param realUploadPath:上傳檔案的絕對路徑
* */
public String uploadImage(File image,String imageFileName,String uploadPath,String realUploadPath){
InputStream is =null;
OutputStream os = null;
try {
is = new FileInputStream(image);
os = new FileOutputStream(realUploadPath+File.separator+imageFileName);
byte[] buffer = new byte[1024];//每次讀取的檔案資訊
int len = 0;
while((len=is.read(buffer))>0){
os.write(buffer);//寫入檔案資訊
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//關閉流避免資源浪費
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//傳回上傳後的檔案絕對路徑
return uploadPath+File.separator+imageFileName;
}
}
c、上傳後的檔案資訊PicInfo:
package com.wjl.watermark;
public class PicInfo {
private String imageURL;
private String logoImageURL;
//兩個屬性的get/set方法
}
4、圖檔上傳後的頁面展示waterMark.jsp:
先引入s标簽:<%@ taglib uri="/struts-tags" prefix="s"%>
<body>
<table width="99%" align="center">
<tr>
<td width="50%">
<img src=${pageContext.request.contextPath }<s:property value="pic.imageURL"/> width="350" >
</td>
<td width="50%">
<img src=${pageContext.request.contextPath }<s:property value="pic.logoImageURL"/> width="350" >
</td>
</tr>
</table>
</body>
5、在webRoot目錄下建立images目錄,啟動伺服器進行測試。
二、多檔案上傳。
1、檔案上傳界面主要代碼:index.jsp。
<body>
<h4>上傳圖檔</h4>
<hr />
<form name="uploadFile" action="${pageContext.request.contextPath }/waterMark.action" method="post" enctype="multipart/form-data">
<input type="file" name="image"/><br />
<input type="file" name="image"/><br />
<input type="file" name="image"/><br />
<input type="file" name="image"/><br />
<input type="file" name="image"/><br />
<input type="file" name="image"/><br />
<input type="file" name="image"/><br />
<input type="submit" name="uploadImage" value="上傳圖檔"/>
</form>
</body>
2、struts.xml配置檔案與單檔案上傳一緻。
3、用來進行檔案上傳的UploadService和記錄上傳後的檔案PicInfo與單檔案上傳相同,集中處理的WaterMarkAction主要修改如下:
package com.wjl.watermark;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class WaterMarkAction extends ActionSupport{
private File[] image;
private String[] imageFileName;
private String uploadPath;
private List<PicInfo> picInfo = new ArrayList<PicInfo>();
public String waterMark() throws Exception{
String realUploadPath = ServletActionContext.getServletContext().getRealPath(uploadPath);
if(image!=null && image.length>0){
PicInfo pic=null;
UploadService uploadService = new UploadService();
for(int i=0;i<image.length;i++){
pic = new PicInfo();
//上傳圖檔
pic.setImageURL(uploadService.uploadImage(image[i], imageFileName[i], uploadPath, realUploadPath));
picInfo.add(pic);
}
}
return SUCCESS;
}
//image、imageFileName、uploadPath、pic的get/set方法
}
4、圖檔上傳後的頁面展示waterMark.jsp:
記得引入s标簽:<%@ taglib uri="/struts-tags" prefix="s"%>
<body>
<table width="99%" align="center">
<s:iterator value="picInfo">
<tr>
<td width="50%">
<img src=${pageContext.request.contextPath }<s:property value="imageURL"/> width="350" >
</td>
<td width="50%">
<img src=${pageContext.request.contextPath }<s:property value="logoImageURL"/> width="350" >
</td>
</tr>
</s:iterator>
</table>
</body>
5、進行測試。
注意點:
1、檔案上傳之後記得關閉各種流,避免出現亂七八糟的問題。
2、進行檔案上傳的form表單一定要設定enctype="multipart/form-data";
3、WaterMarkAction中的File image中的image變量必須與index.jsp中type="file"類型的input框name值相同,否則無法對應上。
4、WaterMarkAction中的imageFileName不是我們自己配置的而是由Struts自帶的,它遵循的原則是:前台file控件的name名稱+"FileName"。我這裡file控件的name是image,是以檔案名稱我定義imageFileName。若控件名稱為file那麼則應該定義成fileFileName,file的MIME類型也遵循同樣的原則。否則擷取不到檔案名稱。
5、用來記錄上傳後的檔案資訊的PicInfo對象中的兩個屬性一定要給get/set方法,否則在waterMark.jsp頁面中無法直接使用其屬性。
6、picInfo這個對象給定的get/set方法一定要是getPicInfo/setPicInfo,要是弄成getPic/setPic,那麼在waterMark.jsp頁面中直接使用imageURL和logoImageURL就會擷取不到值。(我會犯這個錯就是因為原本picInfo的名稱是pic後來改成picInfo的,但是get/set方法沒有變化是以就沒擷取到。)