這段時(shí)間在做一個(gè)Java Web項(xiàng)目需要用到CKEditor做編輯器,但這個(gè)編輯器取值和圖片上傳不太好弄铅歼,特別是圖片上傳公壤,寫(xiě)篇文章紀(jì)念一下。
寫(xiě)在最前:Eclipse如何將項(xiàng)目部署到tomcat椎椰,而不是workspace的somewhere
這個(gè)很重要厦幅,不然上傳的文件怎么生成URI呢?MyEclipse不知道有沒(méi)有這個(gè)問(wèn)題慨飘,本人沒(méi)有測(cè)試确憨。但Eclipse是默認(rèn)將web項(xiàng)目部署到.metadata.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps下的,很無(wú)語(yǔ)套媚!
-
先放一張配置好后的Server
Step 1:停掉你的Tomcat服務(wù)器缚态,并刪除當(dāng)前配置的server
-
一般雙擊Server看到的Server Locations是灰掉的,不能操作堤瘤,所以要?jiǎng)h掉重配
Step 2:直接新建一個(gè)Server
Step 3:雙擊Server進(jìn)行配置
- 選擇Deploy path到你tomcat的webapps下
- 重新發(fā)布項(xiàng)目到Server就可以在tomcat的webapps下看到你的項(xiàng)目了凉当。
在JSP中引入CKEditor
Step 1:首先你得需要一個(gè)CKEditor
- 去官網(wǎng)下載for java版本洽损,或者用我的這個(gè)版本
鏈接:http://pan.baidu.com/s/1dECfVax 密碼:mzbw
-
將整個(gè)文件夾拷到你得WebContent下
- 然后導(dǎo)入CKEditor的核心jar包厦取,我這兒也有
鏈接:http://pan.baidu.com/s/1b1wEq6 密碼:xd4n
Step 2:使用CKEditor
- 在合適位置(一般是在head里)引用CKEditor的JS文件
//appPath是你得項(xiàng)目路徑赖淤,這個(gè)可以很容易獲得= =不行就用相對(duì)路徑試試
<script type="text/javascript" src="<%=appPath%>/ckeditor/ckeditor.js"></script>
- 遵循官網(wǎng)推薦的原則,使用自帶的taglib
//在JSP頁(yè)面的Page標(biāo)簽后引入
<%@ taglib uri="http://ckeditor.com" prefix="ckeditor"%>
//一般是要有form包裹起來(lái)慎皱,因?yàn)楹竺孢€要提交到服務(wù)器的
<textarea name="editor" cols="100" id="editor" rows="10"></textarea>
<ckeditor:replace replace="editor" basePath="/ckeditor/" />//這里的replace后跟的是textarea的name值
這里用的是經(jīng)典的方法老虫,利用CKEditor替換掉textarea中的值。網(wǎng)上也有一些使用JS來(lái)替換的茫多,我也試了但并沒(méi)有成功祈匙,還是taglib比較給力。
- 成功后頁(yè)面是這樣的天揖。
- 當(dāng)然你見(jiàn)到的這些東西都是可設(shè)置的夺欲,就在ckeditor文件夾下的config.js中,網(wǎng)上有太多的教程今膊,就不說(shuō)明了些阅。這里推薦一篇超詳細(xì)的配置
Step 3:重點(diǎn)來(lái)了,如何獲得CKEditor的內(nèi)容呢斑唬?
我嘗試了N遍市埋,試圖直接從被替換掉的textarea中獲取前臺(tái)輸入的內(nèi)容黎泣,然而并沒(méi)有成功,永遠(yuǎn)得到的都是null
- 換個(gè)思路缤谎!在前臺(tái)使用一個(gè)什么來(lái)代替ckeditor框來(lái)上傳到后臺(tái)抒倚,賦值的事就交給JS來(lái)處理
<div class="control-group">
<input name="articleContent" id="content" type="hidden" />//中轉(zhuǎn)的input框
</div>
</form>
//ckeditor框中內(nèi)容并沒(méi)有提交到后臺(tái)
<div class="control-group">
<label>內(nèi)容:</label><br />
<textarea name="editor" cols="100" id="editor" rows="10"></textarea>
<ckeditor:replace replace="editor" basePath="/ckeditor/" />
</div>
- 注意:我的textarea框在</form>后,并沒(méi)有提交到后臺(tái)坷澡,而是通過(guò)JS獲得textarea的值再賦給隱藏的input的value
- JS賦值衡便,下面的代碼寫(xiě)在你提交事件的那個(gè)函數(shù)里,然后后臺(tái)就可以通過(guò)獲取articleContent的值來(lái)間接得到CKEditor中輸入的值了~
var value = CKEDITOR.instances.editor.getData();//固定格式洋访,沒(méi)什么毛病
$("#content").val(value);//這里用的JQuery,比較清爽= =
Step 4:該上傳圖片了
配置好CKEditor后谴餐,是可以直接從其他網(wǎng)站Copy文章(帶圖片)然后上傳的姻政,但是如果我的文章是原創(chuàng)怎么辦呢,那就不得不上傳圖片了岂嗓。嘗試過(guò)去給CKEditor配它的另一半CKfinder汁展,但沒(méi)有成功,上傳服務(wù)器那一下總是出錯(cuò)厌殉。此路不通食绿,只有繞行~
思路:利用Struts2的圖片上傳綁定到CKEditor
- 首先,你得有上傳這個(gè)功能(默認(rèn)是沒(méi)有的9薄)器紧,找到WebContent\ckeditor\plugins\image\dialogs目錄下的image.js,搜索upload楼眷,將hidden改為false或0铲汪,這樣點(diǎn)擊圖像就能看到上傳功能了。
- 然后罐柳,寫(xiě)一個(gè)Struts2上傳文件(圖片)的功能掌腰,擢這里參考人家寫(xiě)好的代碼,比較詳細(xì)但只取Action與Util類以及action配置就好张吉,其它的有些問(wèn)題齿梁,需要做些小修改。
- 導(dǎo)入文章中的代碼后肮蛹,小修改下
//some code
//修改編碼為UTF-8勺择,其實(shí)這兒GBK也沒(méi)什么不可,我強(qiáng)迫癥蔗崎!
response.setCharacterEncoding("UTF-8");
//some code
//修改上傳路徑(物理路徑)酵幕,到Apache tomcat下面的webapps文件中的一個(gè)目錄(便于給URL),這樣重新部署時(shí)之前上傳的文件就不會(huì)被刪除
String uploadPath = "C:\\AllProjects\\apache-tomcat\\webapps\\uploads\\"+DateUtil.getDirDate()+"\\";
//修改返回圖像URL到你剛剛指定的目錄
out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + "http://localhost:8080/uploads/"+ DateUtil.getDirDate() +"/"+ fileName + "','')");
- 配置Struts的Action缓苛。
<action name="uploadfile" class="com.xxx.web.action.CkeditorUploadAction"></action>
這里要是運(yùn)行報(bào)錯(cuò)芳撒,可能就是action配置的namespace錯(cuò)了邓深,根據(jù)報(bào)錯(cuò)將action配置到指定的namespace就好
- 最后,綁定CKEditor的上傳事件到剛剛的action笔刹,打開(kāi)CKEditor的config.js加入下面這一句
config.filebrowserUploadUrl = 'uploadfile';//這個(gè)uploadfile是你剛剛的Action的name
16.04.24更新
- 之前的部分只能實(shí)現(xiàn)簡(jiǎn)單的圖片上傳芥备,需求不止于此。如果要上傳附件(即不止是圖片舌菜,可能是任何文件)萌壳,該怎么辦呢。這里需要對(duì)上傳Action進(jìn)行處理下日月,并且將Struts2的上傳文件大小限制調(diào)整到適合大小即可袱瓮。
step 1:對(duì)原來(lái)的上傳Action進(jìn)行處理
package com.xxx.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import util.DateUtil;
import com.opensymphony.xwork2.ActionSupport;
public class CkeditorUploadAction extends ActionSupport{
private File upload;
private String uploadContentType;
private String uploadFileName;
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String execute() throws Exception {
HttpServletResponse response = ServletActionContext.getResponse();
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
// CKEditor提交的很重要的一個(gè)參數(shù)
String callback = ServletActionContext.getRequest().getParameter("CKEditorFuncNum");
InputStream is = new FileInputStream(upload);
// String uploadPath = ServletActionContext.getServletContext().getRealPath("uploads/"+DateUtil.getDirDate());//這個(gè)目錄是在你的項(xiàng)目下
String uploadPath = "C:\\AllProjects\\apache-tomcat\\webapps\\uploads\\"+DateUtil.getDirDate()+"\\";//這里改成tomcat下的webapps下
System.out.println("uploadpath:"+uploadPath);
File dirfile=new File(uploadPath);
if(!dirfile.exists()){
dirfile.mkdirs();
}
System.out.println("filename:"+uploadFileName);//直接使用上傳文件的名字,沒(méi)有重新命名了= =偷懶爱咬,但也有好處
File toFile = new File(uploadPath, uploadFileName);
OutputStream os = new FileOutputStream(toFile);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
is.close();
os.close();
// 返回“圖像”選項(xiàng)卡并顯示圖片
out.println("<script type=\"text/javascript\">");
out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + "http://localhost:8080/uploads/"+ DateUtil.getDirDate() +"/"+ uploadFileName + "','')");
out.println("</script>");
return null;
}
}
Step 2:修改struts.properties
- 在struts.properties將struts.multipart.maxSize改為適當(dāng)?shù)拇笮〕呓瑁J(rèn)為2M,一般不適用
struts.multipart.maxSize=52428800 <!-- 這里是50M精拟,單位是Byte燎斩,根據(jù)需要調(diào)整->
生命不息,折騰不止