String value = java.net.URLEncoder.encode("中文","utf-8");
Cookie cookie = new Cookie("chinese_code",value);
cookie.setMaxAge(60*60*24*6);
response.addCookie(cookie);
encode() 只有一個參數的已經過時了,現在可以設置編碼格式, 取cookie值的時候 也不用解碼了。
我們注意到它里面包含了這段配置:<load-on-startup>1</load-on-startup>,那么這個配置有什么作用呢?
貼一段英文原汁原味的解釋如下:
Servlet specification:
The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.
翻譯過來的意思大致如下:
1)load-on-startup元素標記容器是否在啟動的時候就加載這個servlet(實例化并調用其init()方法)。
2)它的值必須是一個整數,表示servlet應該被載入的順序
2)當值為0或者大于0時,表示容器在應用啟動時就加載并初始化這個servlet;
3)當值小于0或者沒有指定時,則表示容器在該servlet被選擇時才會去加載。
4)正數的值越小,該servlet的優先級越高,應用啟動時就越先加載。
5)當值相同時,容器就會自己選擇順序來加載。
所以,<load-on-startup>x</load-on-startup>,中x的取值1,2,3,4,5代表的是優先級,而非啟動延遲時間。
如下題目:
2.web.xml中不包括哪些定義(多選)
a.默認起始頁
b.servlet啟動延遲時間定義
c.error處理頁面
d.jsp文件改動后重新載入時間
答案:b,d
通常大多數Servlet是在用戶第一次請求的時候由應用服務器創建并初始化,但<load-on-startup>n</load-on-startup> 可以用來改變這種狀況,根據自己需要改變加載的優先級!
研究發現:屬性(變量)可分為三類(對象屬性、全局變量和局部變量)
對象屬性:聲明時以“this.”開頭,只能被“類的實例”即對象所調用,不能被“類內部(對外不對內)”調用;全局變量:聲明時直接以變量名開頭,可以任意調用(對內對外);局部變量:只能被
“類內部(對內不對外)”調用。
JS函數的聲明與訪問原理
<script type="text/javas
//類
var testClass = function(){
//對象屬性(對外不對內,類調用)
this.age ="25";
//全局變量(對內對外)
name="jack";
//局部變量(對內不對外)
var address = "beijing";
//全局函數(對內對外)
add = function(a,b){
//可訪問:全局變量和局部變量
multiply(a,b);
return a+b;
}
//實例函數(由類的對象調用)
this.minus = function(a,b){
//可以訪問:對象屬性、全局變量和局部變量
return a-b;
}
//局部函數(內部直接調用)
var multiply = function(a,b){
//只能訪問:全局變量和局部變量
return a*b;
}
}
//類函數(由類名直接調用)
testClass.talk= function(){
//只能訪問:全局變量和全局函數
this.what = function(){
alert("What can we talk about?");
about();
}
var about = function(){
alert("about name:"+name);
alert("about add(1,1):"+add(1,1));
}
}
//原型函數(由類的對象調用)
testClass.prototype.walk = function(){
//只能訪問:全局變量和全局函數
this.where = function(){
alert("Where can we go?");
go();
}
var go = function(){
alert("go name:"+name);
alert("go add(1,1):"+add(1,1));
}
}
</script>
下面看看如何調用:
<script type="text/javas
//獲取一個cbs類的實例
var cbs= new testClass();
//調用類的對象屬性age
alert("age:"+cbs.age);
//獲取類函數talk的實例
var talk = new testClass.talk();
//調用類函數的實例函數
talk.what();
//獲取原型函數walk的實例
var walk = new cbs.walk();
//調用原型函數的實例函數
walk.where();
</script>
早起的國內互聯網都使用GBK編碼,久之,所有項目都以GBK來編碼了。對于J2EE項目,為了減少編碼的干擾通常都是設置一個編碼的Filter,強制將Request/Response編碼改為GBK。例如一個Spring的常見配置如下:
<filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>GBK</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter>
毫無疑問,這在GBK編碼的頁面訪問、提交數據時是沒有亂碼問題的。但是遇到Ajax就不一樣了。Ajax強制將中文內容進行UTF-8編碼,這樣導致進入后端后使用GBK進行解碼時發生亂碼。網上的所謂的終極解決方案都是扯淡或者過于復雜,例如下面的文章:
這樣的文章很多,顯然:
如果提交數據的時候能夠告訴后端傳輸的編碼信息是否就可以避免這種問題?比如Ajax請求告訴后端是UTF-8,其它請求告訴后端是GBK,這樣后端分別根據指定的編碼進行解碼是不是就解決問題了。
有兩個問題:
解決了上述問題,來看具體實現方案。 列一段Java代碼:
import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.util.ClassUtils; import org.springframework.web.filter.OncePerRequestFilter; /** 自定義編碼過濾器 * @author imxylz (imxylz#gmail.com) * @sine 2011-6-9 */ public class MutilCharacterEncodingFilter extends OncePerRequestFilter { static final Pattern inputPattern = Pattern.compile(".*_input_encode=([\\w-]+).*"); static final Pattern outputPattern = Pattern.compile(".*_output_encode=([\\w-]+).*"); // Determine whether the Servlet 2.4 HttpServletResponse.setCharacterEncoding(String) // method is available, for use in the "doFilterInternal" implementation. private final static boolean responseSetCharacterEncodingAvailable = ClassUtils.hasMethod(HttpServletResponse.class, "setCharacterEncoding", new Class[] { String.class }); private String encoding; private boolean forceEncoding = false; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String url = request.getQueryString(); Matcher m = null; if (url != null && (m = inputPattern.matcher(url)).matches()) {//輸入編碼 String inputEncoding = m.group(1); request.setCharacterEncoding(inputEncoding); m = outputPattern.matcher(url); if (m.matches()) {//輸出編碼 response.setCharacterEncoding(m.group(1)); } else { if (this.forceEncoding && responseSetCharacterEncodingAvailable) { response.setCharacterEncoding(this.encoding); } } } else { if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) { request.setCharacterEncoding(this.encoding); if (this.forceEncoding && responseSetCharacterEncodingAvailable) { response.setCharacterEncoding(this.encoding); } } } filterChain.doFilter(request, response); } public void setEncoding(String encoding) { this.encoding = encoding; } public void setForceEncoding(boolean forceEncoding) { this.forceEncoding = forceEncoding; } }
解釋下:
http://confluence.redsaga.com/pages/viewpage.action?pageId=1643
JavaScript API :http://confluence.redsaga.com/display/BUFFALO/JavaScript+API?修改后的結果以post方式提交給/fck/servlet/ContextServlet,該url對應的即為ContextServlet。
ContextServlet負責讀取FCKeditor里的內容,并賦予給session中的ContextBean。doPost()方法用于實現該功能
需要注意兩個問題,
其一:FCKeditor內的中文信息讀取是可能出現亂碼,需要額外的處理:
?? String?name=new?String(request.getParameter("EditorDefault").getBytes("ISO-8859-1"),"UTF-8");
其二:由于servlet處于FacesContext范圍外,因此不能通過FacesContext.getCurrentInstance()來得到當前FacesContext,因此ContextServlet定義了自己的方法用于獲取FacesContext:
?? ContextServlet處理完了FCKeditor內容后,將跳轉到form.jsp。
這樣一個簡單的編輯功能就完成了。
3.遺留問題:
?? 我在上傳文件時還是會出現中文亂碼的問題,按照其他人說的那樣把網頁的charset=utf-8改成gb2312一樣會有問題,還請各位高手賜教^_^
另外,關于整個demo的源代碼如果大家需要,可以留言給我,我用郵箱發給您。不足之處,還請各位多多指點
開發環境: FCKeditor 版本 FCKeditor_2.3.1 FCKeditor.Java 2.3 下載地址: http://www.fckeditor.net/download/default.html 開始: 解壓 FCKeditor_2.3.1 包中的 fckconfig.js、fckeditor.js、fckstyles.xml、fcktemplates.xml 文件夾到項目中的 WebContent 目錄 解壓 FCKeditor-2.3.zip 包中的 \web\WEB-INF\lib 下的兩個 jar 文件到項目的 WebContent\WEB-INF\lib 目錄 解壓 FCKeditor-2.3.zip 包中的 \src 下的 FCKeditor.tld 文件到項目的 WebContent\WEB-INF 目錄 刪除 WebContent\edit 目錄下的 _source 文件夾 修改 web.xml 文件,加入以下內容
代碼
< servlet > 新建一個提交頁 jsp1.jsp 文件和一個接收頁 jsp2.jsp 文件 jsp1.jsp 代碼如下: 代碼 <%@ page contentType = "text/html;charset=UTF-8" language = "java" %> 在 WebContent 目錄下新建 UserFiles 文件夾,在此文件夾下新建 File,Image,Flash 三個文件夾。 ok現在運行一下看看吧! |
試用了一下FCKeditor,根據網上的文章小結一下:
1.下載
FCKeditor.java 2.3 (FCKeditot for java)
FCKeditor 2.2 (FCKeditor基本文件)
2.建立項目:tomcat/webapps/TestFCKeditor.
3.將FCKeditor2.2解壓縮,將整個目錄FCKeditor復制到項目的根目錄下,
目錄結構為:tomcat/webapps/TestFCKeditor/FCKeditor
然后將FCKeditor-2.3.zip(java)壓縮包中\web\WEB-INF\lib\目錄下的兩個jar文件拷到項目的\WEB-INF\lib\目錄下。把其中的src目錄下的FCKeditor.tld文件copy到TestFCKedit/FCKeitor/WEB-INF/下
4.將FCKeditor-2.3.zip壓縮包中\web\WEB-INF\目錄下的web.xml文件合并到項目的\WEB-INF\目錄下的web.xml文件中。
5. 修改合并后的web.xml文件,將名為SimpleUploader的Servlet的enabled參數值改為true,
以允許上傳功能,Connector Servlet的baseDir參數值用于設置上傳文件存放的位置。
添加標簽定義:
<taglib>
<taglib-uri>/TestFCKeditor</taglib-uri>
<taglib-location>/WEB-INF/FCKeditor.tld</taglib-location>
</taglib>
運行圖:
6. 上面文件中兩個servlet的映射分別為:/editor/filemanager/browser/default/connectors/jsp/connector
和/editor/filemanager/upload/simpleuploader,需要在兩個映射前面加上/FCKeditor,
即改為/FCKeditor/editor/filemanager/browser/default/connectors/jsp/connector和
/FCKeditor/editor/filemanager/upload/simpleuploader。
7.進入skin文件夾,如果你想使用fckeditor默認的這種奶黃色,
那就把除了default文件夾外的另兩個文件夾直接刪除.
8.刪除/FCKeditor/目錄下除fckconfig.js, fckeditor.js, fckstyles.xml, fcktemplates.xml四個文件以外的所有文件
刪除目錄/editor/_source,
刪除/editor/filemanager/browser/default/connectors/下的所有文件
刪除/editor/filemanager/upload/下的所有文件
刪除/editor/lang/下的除了fcklanguagemanager.js, en.js, zh.js, zh-cn.js四個文件的所有文件
9.打開/FCKeditor/fckconfig.js
修改 FCKConfig.DefaultLanguage = 'zh-cn' ;
把FCKConfig.LinkBrowserURL等的值替換成以下內容:
FCKConfig.LinkBrowserURL
= FCKConfig.BasePath + "filemanager/browser/default/browser.html?Connector=connectors/jsp/connector" ;
FCKConfig.ImageBrowserURL
= FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector" ;
FCKConfig.FlashBrowserURL
= FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/jsp/connector" ;
FCKConfig.LinkUploadURL = FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=File' ;
FCKConfig.FlashUploadURL = FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=Flash' ;
FCKConfig.ImageUploadURL = FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=Image' ;
10.其它
fckconfig.js總配置文件,可用記錄本打開,修改后將文件存為utf-8 編碼格式。找到:
FCKConfig.TabSpaces = 0 ; 改為FCKConfig.TabSpaces = 1 ; 即在編輯器域內可以使用Tab鍵。
如果你的編輯器還用在網站前臺的話,比如說用于留言本或是日記回復時,那就不得不考慮安全了,
在前臺千萬不要使用Default的toolbar,要么自定義一下功能,要么就用系統已經定義好的Basic,
也就是基本的toolbar,找到:
FCKConfig.ToolbarSets["Basic"] = [
['Bold','Italic','-','OrderedList','UnorderedList','-',/*'Link',*/'Unlink','-','Style','FontSize','TextColor','BGColor','-',
'Smiley','SpecialChar','Replace','Preview'] ] ;
這是改過的Basic,把圖像功能去掉,把添加鏈接功能去掉,因為圖像和鏈接和flash和圖像按鈕添加功能都能讓前臺
頁直接訪問和上傳文件, fckeditor還支持編輯域內的鼠標右鍵功能。
FCKConfig.ContextMenu = ['Generic',/*'Link',*/'Anchor',/*'Image',*/'Flash','Select','Textarea','Checkbox','Radio','TextField','HiddenField',
/*'ImageButton',*/'Button','BulletedList','NumberedList','TableCell','Table','Form'] ;
這也是改過的把鼠標右鍵的“鏈接、圖像,FLASH,圖像按鈕”功能都去掉。
找到: FCKConfig.FontNames = 'Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;
加上幾種我們常用的字體
FCKConfig.FontNames
= '宋體;黑體;隸書;楷體_GB2312;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;
7.添加文件 /TestFCKeditor/test.jsp:
<%@ page language="java" import="com.fredck.FCKeditor.*" %>
<%@ taglib uri="/TestFCKeditor" prefix="FCK" %>
<script type="text/javascript" src="/TestFCKeditor/FCKeditor/fckeditor.js"></script>
<%--
三種方法調用FCKeditor
1.FCKeditor自定義標簽 (必須加頭文件 <%@ taglib uri="/TestFCKeditor" prefix="FCK" %> )
2.script腳本語言調用 (必須引用 腳本文件 <script type="text/javascript" src="/TestFCKeditor/FCKeditor/fckeditor.js"></script> )
3.FCKeditor API 調用 (必須加頭文件 <%@ page language="java" import="com.fredck.FCKeditor.*" %> )
--%>
<%--
<form action="show.jsp" method="post" target="_blank">
<FCK:editor id="content" basePath="/TestFCKeditor/FCKeditor/"
width="700"
height="500"
skinPath="/TestFCKeditor/FCKeditor/editor/skins/silver/"
toolbarSet = "Default"
>
input
</FCK:editor>
<input type="submit" value="Submit">
</form>
--%>
<form action="show.jsp" method="post" target="_blank">
<table border="0" width="700"><tr><td>
<textarea id="content" name="content" style="WIDTH: 100%; HEIGHT: 400px">input</textarea>
<script type="text/javascript">
var oFCKeditor = new FCKeditor('content') ;
oFCKeditor.BasePath = "/TestFCKeditor/FCKeditor/" ;
oFCKeditor.Height = 400;
oFCKeditor.ToolbarSet = "Default" ;
oFCKeditor.ReplaceTextarea();
</script>
<input type="submit" value="Submit">
</td></tr></table>
</form>
<%--
<form action="show.jsp" method="post" target="_blank">
<%
FCKeditor oFCKeditor ;
oFCKeditor = new FCKeditor( request, "content" ) ;
oFCKeditor.setBasePath( "/TestFCKeditor/FCKeditor/" ) ;
oFCKeditor.setValue( "input" );
out.println( oFCKeditor.create() ) ;
%>
<br>
<input type="submit" value="Submit">
</form>
--%>
添加文件/TestFCKeditor/show.jsp:
<%
String content = request.getParameter("content");
out.print(content);
%>
8.瀏覽http://localhost:8080/TestFCKeditor/test.jsp
ok!
<display-name>元素定義這個web應用的名字,Java Web 服務器的Web管理工具將用這個名字來標志Web應用。
<description>元素用來聲明Web應用的描述信息
<context-param>元素用來配置外部引用的,在servlet中如果要獲得該元素中配置的值,String param-value = getServletContext().getInitParameter("param-name")
<filter>
<filter-name>SampleFilter</filter-name>
<filter-class>com.lpdev.SampleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SampleFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
以上是配置了一個servlet過濾器,對于servlet容器收到的客戶請求以及發出的響應結果,servlet都能檢查和修改其中的信息,以上代碼指名當客戶請求訪問Web應用中的所有JSP文件時,將觸發SampleFilter過濾器工作,具體的過濾事務在由<filter-class>中指定的類來完成
<servlet>
<servlet-name>IncludeServlet</servlet-name>
<servlet-class>com.lpdev.IncludeServlet</servlet-class>
<init-param>
<param-name>copyright</param-name>
<param-value>/foot.jspf</param-value>
<load-on-startup>1</load-on-startup>
</init-param>
</servlet>
配置Servlet,<servlet-name>是servlet的名字,<servlet-class>是實現這個Servlet的類,<init-param>定義Servlet的初始化參數(參數名和參數值),一個Servlet可以有多個<init-param>,在Servlet類中通過getInitParameter(String name)方法訪問初始化參數
<servlet-mapping>
<servlet-name>IncludeServlet</servlet-name>
<url-pattern>/IncludeServlet</url-pattern>
</servlet-mapping>
配置Servlet映射,<servlet-mapping>元素用來設定客戶訪問某個Servlet的URL,這里只需給出對于整個web應用的相對的URL路徑,<url-pattern>中的“/”表示開始于Web應用的根目錄例如,如果你在你本地機器上使用Tomcat4.1.x,并且創建了名為“myapp”的應用程序,<url-pattern>/IncludeServlet</url-pattern>該Servlet的完整web地址就是http://localhost:8080/myapp/IncludeServlet
<session-config>元素用來設定HttpSession的生命周期,該元素只有一個<session-timeout>屬性,時間單位是“秒”。
<welcome-file-list>當用戶訪問web時,如果僅僅給出web應用的Root URL,沒有指定具體文件名,容器調用該配置,該元素可以包含多個<welcome-file>屬性。
<taglib>元素用來設置web引用的tag library,例示定義了一個“/mytaglib”標簽庫,它對應的tld文件為:/WEB_INF/mytaglib.tld
<taglib>
<taglib-url>/mytaglib</taglib-url>
<taglib-locationg>/WEB-INF/mytaglib.tld</taglib-location>
</taglib>
<resource-ref>如果web應用由Servlet容器管理的某個JNDI Resource,必須在web.xml中聲明對這個JNDI Resource的引用。
<resource-ref>
<description>DB Connection</description> //說明
<res-ref-name>jdbc/sampleDB</res-ref-name> //引用資源的JNDI名字
<res-type>javax.sql.DataSource</res-type> //引用資源的類名字
<res-auth>Container</res-auth> //管理引用資源的Manager
</resource-ref>
<security-constraint>用來為Web應用定義安全約束
<security-constraint>
<web-resource-collection>//聲明受保護的web資源
<web-resource-name>ResourceServlet</web-resource-name>//標識受保護web資源
<url-pattern>/ResourceServlet</url-pattern>//指定受保護的URL路徑
<http-method>GET</http-method>//指定受保護的方法
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>//可以訪問受保護資源的角色
<description>this applies only to admin secrity role</description>
<role-name>admin</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>元素指定當Web客戶訪問受保護資源時,系統彈出的登陸對話框的類型。例示配置了基于表單驗證的登陸界面
<login-config>
<auth-method>FORM</auth-method>//BASIC(基本驗證法),DIGEST(摘要驗證),FORM(表單驗證)
<real-name>設定安全域的名稱</realname>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
<security-role>指明這個Web應用引用的所有角色名字
<security-role>
<description>描述</description>
<role-name>admin</role-name>
</security-role>