ssh框架+sitemesh編輯器上傳圖片被載入裝飾器問題導致上傳圖片失敗
最近被kindeditor上傳圖片的問題困擾了一星期,在看了許多解決方法後經過無數次:( 真的是無數次 終於成功了。。。記性不好就寫下來好了
因為用的是jsp,所以kindeditor的部分檔案要修改,我把我的修改部分寫下面
首先要修改kindeditor/plugins/image/image.js檔案
把php/upload_json.php換成jsp/upload_json.jsp
/******************************************************************************* * KindEditor - WYSIWYG HTML Editor for Internet * Copyright (C) 2006-2011 kindsoft.net * * @author Roddy <
[email protected]> * @site http://www.kindsoft.net/ * @licence http://www.kindsoft.net/license.php *******************************************************************************/ KindEditor.plugin('image', function(K) { var self = this, name = 'image', allowImageUpload = K.undef(self.allowImageUpload, true), allowImageRemote = K.undef(self.allowImageRemote, true), formatUploadUrl = K.undef(self.formatUploadUrl, true), allowFileManager = K.undef(self.allowFileManager, false), uploadJson = K.undef(self.uploadJson, self.basePath + 'jsp/upload_json.jsp'), imageTabIndex = K.undef(self.imageTabIndex, 0), imgPath = self.pluginsPath + 'image/images/', extraParams = K.undef(self.extraFileUploadParams, {}), filePostName = K.undef(self.filePostName, 'imgFile'), fillDescAfterUploadImage = K.undef(self.fillDescAfterUploadImage, false), lang = self.lang(name + '.'); self.plugin.imageDialog = function(options) { var imageUrl = options.imageUrl, imageWidth = K.undef(options.imageWidth, ''), imageHeight = K.undef(options.imageHeight, ''), imageTitle = K.undef(options.imageTitle, ''), imageAlign = K.undef(options.imageAlign, ''), showRemote = K.undef(options.showRemote, true), showLocal = K.undef(options.showLocal, true), tabIndex = K.undef(options.tabIndex, 0), clickFn = options.clickFn; var target = 'kindeditor_upload_iframe_' + new Date().getTime(); var hiddenElements = []; for(var k in extraParams){ hiddenElements.push('<input type="hidden" name="' + k + '" value="' + extraParams[k] + '" />'); } var html = [ '<div style="padding:20px;">', //tabs '<div class="tabs"></div>', //remote image - start '<div class="tab1" style="display:none;">', //url '<div class="ke-dialog-row">', '<label for="remoteUrl" style="width:60px;">' + lang.remoteUrl + '</label>', '<input type="text" id="remoteUrl" class="ke-input-text" name="url" value="" style="width:200px;" /> ', '<span class="ke-button-common ke-button-outer">', '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', '</span>', '</div>', //size '<div class="ke-dialog-row">', '<label for="remoteWidth" style="width:60px;">' + lang.size + '</label>', lang.width + ' <input type="text" id="remoteWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> ', lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> ', '<img class="ke-refresh-btn" src="' + imgPath + 'refresh.png" width="16" height="16" alt="" style="cursor:pointer;" title="' + lang.resetSize + '" />', '</div>', //align '<div class="ke-dialog-row">', '<label style="width:60px;">' + lang.align + '</label>', '<input type="radio" name="align" class="ke-inline-block" value="" checked="checked" /> <img name="defaultImg" src="' + imgPath + 'align_top.gif" width="23" height="25" alt="" />', ' <input type="radio" name="align" class="ke-inline-block" value="left" /> <img name="leftImg" src="' + imgPath + 'align_left.gif" width="23" height="25" alt="" />', ' <input type="radio" name="align" class="ke-inline-block" value="right" /> <img name="rightImg" src="' + imgPath + 'align_right.gif" width="23" height="25" alt="" />', '</div>', //title '<div class="ke-dialog-row">', '<label for="remoteTitle" style="width:60px;">' + lang.imgTitle + '</label>', '<input type="text" id="remoteTitle" class="ke-input-text" name="title" value="" style="width:200px;" />', '</div>', '</div>', //remote image - end //local upload - start '<div class="tab2" style="display:none;">', '<iframe name="' + target + '" style="display:none;"></iframe>', '<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="' + target + '" action="' + K.addParam(uploadJson, 'dir=image') + '">', //file '<div class="ke-dialog-row">', hiddenElements.join(''), '<label style="width:60px;">' + lang.localUrl + '</label>', '<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> ', '<input type="button" class="ke-upload-button" value="' + lang.upload + '" />', '</div>', '</form>', '</div>', //local upload - end '</div>' ].join(''); var dialogWidth = showLocal || allowFileManager ? 450 : 400, dialogHeight = showLocal && showRemote ? 300 : 250; var dialog = self.createDialog({ name : name, width : dialogWidth, height : dialogHeight, title : self.lang(name), body : html, yesBtn : { name : self.lang('yes'), click : function(e) { // Bugfix: http://code.google.com/p/kindeditor/issues/detail?id=319 if (dialog.isLoading) { return; } // insert local image if (showLocal && showRemote && tabs && tabs.selectedIndex === 1 || !showRemote) { if (uploadbutton.fileBox.val() == '') { alert(self.lang('pleaseSelectFile')); return; } dialog.showLoading(self.lang('uploadLoading')); uploadbutton.submit(); localUrlBox.val(''); return; } // insert remote image var url = K.trim(urlBox.val()), width = widthBox.val(), height = heightBox.val(), title = titleBox.val(), align = ''; alignBox.each(function() { if (this.checked) { align = this.value; return false; } }); if (url == 'http://' || K.invalidUrl(url)) { alert(self.lang('invalidUrl')); urlBox[0].focus(); return; } if (!/^\d*$/.test(width)) { alert(self.lang('invalidWidth')); widthBox[0].focus(); return; } if (!/^\d*$/.test(height)) { alert(self.lang('invalidHeight')); heightBox[0].focus(); return; } clickFn.call(self, url, title, width, height, 0, align); } }, beforeRemove : function() { viewServerBtn.unbind(); widthBox.unbind(); heightBox.unbind(); refreshBtn.unbind(); } }), div = dialog.div; var urlBox = K('[name="url"]', div), localUrlBox = K('[name="localUrl"]', div), viewServerBtn = K('[name="viewServer"]', div), widthBox = K('.tab1 [name="width"]', div), heightBox = K('.tab1 [name="height"]', div), refreshBtn = K('.ke-refresh-btn', div), titleBox = K('.tab1 [name="title"]', div), alignBox = K('.tab1 [name="align"]', div); var tabs; if (showRemote && showLocal) { tabs = K.tabs({ src : K('.tabs', div), afterSelect : function(i) {} }); tabs.add({ title : lang.remoteImage, panel : K('.tab1', div) }); tabs.add({ title : lang.localImage, panel : K('.tab2', div) }); tabs.select(tabIndex); } else if (showRemote) { K('.tab1', div).show(); } else if (showLocal) { K('.tab2', div).show(); } var uploadbutton = K.uploadbutton({ button : K('.ke-upload-button', div)[0], fieldName : filePostName, form : K('.ke-form', div), target : target, width: 60, afterUpload : function(data) { dialog.hideLoading(); if (data.error === 0) { var url = data.url; if (formatUploadUrl) { url = K.formatUrl(url, 'absolute'); } if (self.afterUpload) { self.afterUpload.call(self, url, data, name); } if (!fillDescAfterUploadImage) { clickFn.call(self, url, data.title, data.width, data.height, data.border, data.align); } else { K(".ke-dialog-row #remoteUrl", div).val(url); K(".ke-tabs-li", div)[0].click(); K(".ke-refresh-btn", div).click(); } } else { alert(data.message); } }, afterError : function(html) { dialog.hideLoading(); self.errorDialog(html); } }); uploadbutton.fileBox.change(function(e) { localUrlBox.val(uploadbutton.fileBox.val()); }); if (allowFileManager) { viewServerBtn.click(function(e) { self.loadPlugin('filemanager', function() { self.plugin.filemanagerDialog({ viewType : 'VIEW', dirName : 'image', clickFn : function(url, title) { if (self.dialogs.length > 1) { K('[name="url"]', div).val(url); if (self.afterSelectFile) { self.afterSelectFile.call(self, url); } self.hideDialog(); } } }); }); }); } else { viewServerBtn.hide(); } var originalWidth = 0, originalHeight = 0; function setSize(width, height) { widthBox.val(width); heightBox.val(height); originalWidth = width; originalHeight = height; } refreshBtn.click(function(e) { var tempImg = K('<img src="' + urlBox.val() + '" />', document).css({ position : 'absolute', visibility : 'hidden', top : 0, left : '-1000px' }); tempImg.bind('load', function() { setSize(tempImg.width(), tempImg.height()); tempImg.remove(); }); K(document.body).append(tempImg); }); widthBox.change(function(e) { if (originalWidth > 0) { heightBox.val(Math.round(originalHeight / originalWidth * parseInt(this.value, 10))); } }); heightBox.change(function(e) { if (originalHeight > 0) { widthBox.val(Math.round(originalWidth / originalHeight * parseInt(this.value, 10))); } }); urlBox.val(options.imageUrl); setSize(options.imageWidth, options.imageHeight); titleBox.val(options.imageTitle); alignBox.each(function() { if (this.value === options.imageAlign) { this.checked = true; return false; } }); if (showRemote && tabIndex === 0) { urlBox[0].focus(); urlBox[0].select(); } return dialog; }; self.plugin.image = { edit : function() { var img = self.plugin.getSelectedImage(); self.plugin.imageDialog({ imageUrl : img ? img.attr('data-ke-src') : 'http://', imageWidth : img ? img.width() : '', imageHeight : img ? img.height() : '', imageTitle : img ? img.attr('title') : '', imageAlign : img ? img.attr('align') : '', showRemote : allowImageRemote, showLocal : allowImageUpload, tabIndex: img ? 0 : imageTabIndex, clickFn : function(url, title, width, height, border, align) { if (img) { img.attr('src', url); img.attr('data-ke-src', url); img.attr('width', width); img.attr('height', height); img.attr('title', title); img.attr('align', align); img.attr('alt', title); } else { self.exec('insertimage', url, title, width, height, border, align); } // Bugfix: [Firefox] 上傳圖片後,總是出現正在載入的樣式,需要延遲執行hideDialog setTimeout(function() { self.hideDialog().focus(); }, 0); } }); }, 'delete' : function() { var target = self.plugin.getSelectedImage(); if (target.parent().name == 'a') { target = target.parent(); } target.remove(); // [IE] 刪除圖片後立即點選圖片按鈕出錯 self.addBookmark(); } }; self.clickToolbar(name, self.plugin.image.edit); });
再是kindeditor/jsp/upload_json.jsp檔案
在頭上加 <%@ page import="org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper" %>
把jsp/lib包裡面的三個包匯入專案web-inf/lib裡面
把
替換成FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8"); List items = upload.parseRequest(request); Iterator itr = items.iterator(); while (itr.hasNext()) { FileItem item = (FileItem) itr.next(); String fileName = item.getName(); long fileSize = item.getSize(); if (!item.isFormField()) { //檢查檔案大小 if(item.getSize() > maxSize){ out.println(getError("上傳檔案大小超過限制。")); return; } //檢查副檔名 String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){ out.println(getError("上傳副檔名是不允許的副檔名。\n只允許" + extMap.get(dirName) + "格式。")); return; } SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt; try{ File uploadedFile = new File(savePath, newFileName); item.write(uploadedFile); }catch(Exception e){ out.println(getError("上傳檔案失敗。")); return; } JSONObject obj = new JSONObject(); obj.put("error", 0); obj.put("url", saveUrl + newFileName); out.println(obj.toJSONString()); } }
MultiPartRequestWrapper wrapper = (MultiPartRequestWrapper) request;
//獲得上傳的檔名
String fileName = wrapper.getFileNames("imgFile")[0];//imgFile,imgFile,imgFile
//獲得檔案過濾器
File file = wrapper.getFiles("imgFile")[0];
//檢查副檔名
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt))
{
out.println(getError("上傳副檔名是不允許的副檔名。\n只允許" + extMap.get(dirName) + "格式。"));
return;
}
//檢查檔案大小
if (file.length() > maxSize)
{
out.println(getError("上傳檔案大小超過限制。"));
return;
}
//重構上傳圖片的名稱
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String newImgName = df.format(new Date()) + "_"
+ new Random().nextInt(1000) + "." + fileExt;
byte[] buffer = new byte[1024];
//獲取檔案輸出流
FileOutputStream fos = new FileOutputStream(savePath +"/" + newImgName);
//System.out.println("########" + saveUrl + "@@"+ newImgName);
//獲取記憶體中當前檔案輸入流
InputStream in = new FileInputStream(file);
try
{
int num = 0;
while ((num = in.read(buffer)) > 0)
{
fos.write(buffer, 0, num);
}
}
catch (Exception e)
{
e.printStackTrace(System.err);
} finally
{
in.close();
fos.close();
}
JSONObject obj = new JSONObject();
obj.put("error",0);
obj.put("url", saveUrl + newImgName);
out.println(obj.toJSONString());
然後是測試頁面webcontent/index.jsp
<script charset="utf-8" src="../kindeditor/kindeditor.js"></script>
<script charset="utf-8" src="../kindeditor/lang/zh_CN.js"></script>
<link rel="stylesheet" href="../kindeditor/themes/simple/simple.css" />
<textarea id="editor_1" rows="40" cols="40" name="introduce" ></textarea>
<script>
KindEditor.ready(function(K) {
window.editor = K.create('#editor_1',
{
imageUploadJson : '/kindeditor/jsp/upload_json.jsp',
fileManagerJson : '/kindeditor/jsp/file_manager_json.jsp',
afterUpload :function(url){
alert(url);
},
allowImageUpload : true,
resizeType : 1,
allowPreviewEmoticons : false,
allowUpload : true,
items : [
'fontname', 'fontsize', '|', 'textcolor', 'bgcolor', 'bold', 'italic', 'underline',
'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist',
'insertunorderedlist', '|','image', 'emoticons', 'link' , 'unlink']
}
);
});
</script>
因為在裝飾器頁面寫過basepath了所以只貼出部分有用的程式碼了
這樣圖片上傳的部分就好了
下面寫如何解決上傳圖片提示上傳錯誤(返回資料被裝飾器裝飾)的解決方法
首先開啟decorators.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!-- <!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
-->
<decorators defaultdir="/WEB-INF/decorators">
<excludes>
<pattern>/temp.jsp</pattern>
<pattern>/styles/*</pattern>
<pattern>/scripts/*</pattern>
<pattern>/statics/*</pattern>
<pattern>/images/*</pattern>
<pattern>/plugins/*</pattern>
<pattern>/struts/*</pattern>
<pattern>*.json</pattern>
<pattern>*_validator=true</pattern>
<pattern>*.jsv</pattern>
<span style="white-space:pre"> </span><!-- 這行很關鍵!!-->
<pattern>/kindeditor/*</pattern>
<span style="white-space:pre"> </span><!-- 這行是用來過濾kindeditor資料夾下所有檔案 避免被裝飾器裝飾的 當然還要再配置一個sitemesh.xml 在後面說 -->
</excludes>
<decorator name="main" page="main.jsp">
<pattern>/*</pattern>
</decorator>
</decorators>
在web-inf下再建立一個sitemesh.xml檔案,否則上面的過濾起不了作用
<?xml version="1.0" encoding="UTF-8"?>
<sitemesh>
<property name="decorators-file" value="/WEB-INF/decorators.xml" />
<excludes file="${decorators-file}" />
<page-parsers>
<parser default="true" class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
<parser content-type="text/html" class ="com.opensymphony.module.sitemesh.parser.HTMLPageParser"/>
<parser content-type="text/html;charset=UTF-8" class="com.opensymphony.module.sitemesh.parser.HTMLPageParser"/>
</page-parsers>
<decorator-mappers>
<!-- for print -->
<mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper">
<param name="decorator" value ="printable"/>
<param name="parameter.name" value ="printable"/>
<param name="parameter.value" value ="true"/>
</mapper>
<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
<param name="config" value ="${decorators-file}" />
</mapper>
</decorator-mappers>
</sitemesh>
在 sitemesh.xml 中配置了兩個 DecoratorMapper : 1 PrintableDecoratorMapper 2 ConfigDecoratorMapper PrintableDecoratorMapper 是供列印專用,在 url 後加上 printable=true 即會使用 decorator.xml 中指定的 printable 裝飾器來對頁面進行裝飾,一般來說列印頁面是隻需要列印本頁面的內容,其餘的如頭、腳、導航欄、左右選單等是不需要列印的,通過裝飾器可以輕鬆實現列印頁面的過濾。 這樣就算大功告成了,先寫到這,有遺漏的後面再補好了。
相關推薦
ssh框架+sitemesh編輯器上傳圖片被載入裝飾器問題導致上傳圖片失敗
最近被kindeditor上傳圖片的問題困擾了一星期,在看了許多解決方法後經過無數次:( 真的是無數次 終於成功了。。。記性不好就寫下來好了 因為用的是jsp,所以kindeditor的部分檔案要修改,我把我的修改部分寫下面 首先要修改kindeditor/plugins
4-2日裝飾器,帶參數的裝飾器
tar 相關操作 rom 裝飾器 有用 緩存 false war cto 1,函數的有用信息 from functools import wraps#引用模塊 def wrapper(f): # f = func1 @wraps(f) def inner
python 通用裝飾器,帶有參數的裝飾器,
func == nbsp cti none 結果 能夠 參數 %s # 使用裝飾器對有返回值的函數進行裝飾# def func(functionName): # print(‘---func-1----‘) # def func_in():
python 裝飾器 晉級 系統自帶的裝飾器
計算 print def wrap time args turn per func #帶參數的裝飾器 #500個函數 # import time # FLAGE = False # def timmer_out(flag): # def timmer(func):
js圖片(載入已經滾動的區域的圖片)懶載入的實現方法
這種方法,會載入已經滾動區域的所有圖片,比如進入頁面就到了底部,那麼整個頁面的圖片都會載入。 區別於JS實現可視區域懶載入 、Jquery實現可是區域懶載入 <!DOCTYPE html> <html lang="en"> <head>
裝飾器的補充(疊加多個裝飾器,有參裝飾器,三元表達式,生成式,匿名函數)
-s def names 多個 not 登錄 index 補充 art 1,疊加多個裝飾器 1),加載順序(outter函數的調用順序):自下而上 2),執行順序(wrapper函數的執行順序):自上而下 def outter1(func1): #func1=wr
裝飾器的補充(疊加多個裝飾器,有參裝飾器,三元表示式,生成式,匿名函式)
1,疊加多個裝飾器 1),載入順序(outter函式的呼叫順序):自下而上 2),執行順序(wrapper函式的執行順序):自上而下 def outter1(func1): #func1=wrapper2的記憶體地址 print('載入了outter1') def wrap
20181130(裝飾器補充,疊加多個裝飾器,有參裝飾器,三元表示式,生成式,匿名函式,內建函式)
一、裝飾器的補充 1、函式屬性的傳遞 Python裝飾器(decorator)在實現的時候,被裝飾後的函式其實已經是另外一個函數了(函式名等函式屬性會發生改變),為了不影響,Python的functools包中提供了一個叫wraps的decorator來消除這樣的副作用。寫一個decora
20181130(裝飾器補充,疊加多個裝飾器,有參裝飾器,三元表達式,生成式,匿名函數,內置函數)
names hello 對應關系 tools src recv log 原始的 裝飾 一、裝飾器的補充 1、函數屬性的傳遞 Python裝飾器(decorator)在實現的時候,被裝飾後的函數其實已經是另外一個函數了(函數名等函數屬性會發生改變),為了不影響,Pytho
【裝飾器】詳解Python的裝飾器--為已經存在的函式或物件新增額外的功能
寫的非常好的文章,原文在:http://www.cnblogs.com/cicaday/p/python-decorator.html Python中的裝飾器是你進入Python大門的一道坎,不管你跨不跨過去它都在那裡。 為什麼需要裝飾器 我們假設你的程式實現了say_hello()和s
整理裝飾器的形成過程,背誦裝飾器的固定格式
固定格式 def wrapper(func): 2.傳入函式值f def inner(*args, **kwargs): #執行函式前進行的操作 ret = func(*args,**kwargs) # 5.執行f()函式 #執行函式後進行的操作
python裝飾器:有引數的裝飾器、不定長引數的裝飾器、裝飾有返回值的函式、通用的裝飾器
將一個函式作為另一個函式的引數,返回值賦給這個函式 def func(funcname): print("----fun 1---") def fun_in(): print("----fun_in----1") funcname() print("----
Python-裝飾器以及對帶有引數的裝飾器的理解
請編寫一個decorator,能在函式呼叫的前後打印出’begin call’和’end call’的日誌。 再思考一下能否寫出一個@log的decorator,使它既支援: @log def f(): pass 又支援: @log('e
python裝飾器,自己實現一個簡單的裝飾器
裝飾器演變過程 1.先來看個方法: def add(x,y): return x+y 其功能顯而易見,實現一個加法,boss覺得這個功能太單一,需要加些功能1,校驗(因為python是強型別語言,int 和str
python裝飾器詳解(三)---裝飾器高階用法
1. 在裝飾器函式裡傳入引數def a_decorator_passing_arguments(function_to_decorate): def a_wrapper_accepting_arguments(arg1,arg2): print("Igot
關於圖片預載入事件,點選選擇圖片後直接顯示在頁面上
如圖所示 呢麼我們來看demo詳情。如下所示: 頁面demo如下所示: <img
SSH框架實現圖片上傳
第一步,先寫上傳的jsp頁面upload.jsp,注意:一定要在form裡面加enctype="multipart/form-data" <!--在開頭加上這個,以防萬一--> <%@taglib prefix="s" uri="/struts-tags"%> <
SSH 框架下圖片上傳與顯示
這幾天在弄畢設,有幾個需求是要上傳圖片的,看了很多教程,各有各的說法,關鍵點、細節很多說不明白,自己倒騰了幾天,弄出來了,給大家分享一下。上傳圖片的JSP<%@ page language="java" import="java.util.*" pageEncoding
ssh框架 使用struts上傳圖片
@SuppressWarnings("serial") public class Add_action extends ActionSupport { private ImgServlet imgServlet; //圖片詳細 private String detailed;
ssh框架--圖片(檔案)上傳
看過很多關於圖片上傳的demo,但是都比較亂。本案例經過我幾次調整,整理成了一個工具類,與大家分享之。 第一步:準備工作。如果status2.3.4版本以下,struts2在上傳檔案的時候 upload.parseRequest(request)值將為空,解決辦法是寫一個繼