摘要: 世界邦超級自由行,廣募天下英雄豪杰
如果你想找的不僅僅是一個工作機會,不僅僅是一份薪水,而是一個共同為之奮斗的事業(yè),如果你偏偏對旅行又情有獨鐘,從內心地熱愛旅行,并擁有創(chuàng)業(yè)的激情,那么世界邦會是你不二的最佳選擇。
一、旅游產品銷售 (電話銷售)
職位職責:
1、通過電話與客戶進行有效溝通了解客戶需求, 尋找銷售機會;
2、對... 閱讀全文
2011年12月22日 #
高工資后面意味著高能力,高付出,高責任感,高壓力,高考核,高績效。高產出
web應用集成測試的時候,各位還需要啟動web容器,然后打開瀏覽器,輸入ulr,然后看到瀏覽器的輸出嗎?
建議:以上的代碼可以加入到父類的pom中,以后繼承此父pom后,只需要按以上2步,就可以做到web應用測試自動化了。
下面我們用maven做到自動化!
我們利用maven的生命周期和jetty插件來實現(xiàn)。
下面描述下做的自動化web集成測試實現(xiàn)的原理。
1,在生命周期pre-integration-test啟動jetty容器
2,在生命周期integration-test中測試我們寫的***IT.java類
3,在post-integration-test shutdow jetty容器。
在pom.xml中加入代碼如下:
<profiles>
<profile>
<id>ittest</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>run-integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<contextPath>/</contextPath>
<stopPort>9966</stopPort>
<stopKey>stop-jetty-for-it</stopKey>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>6211</port>
</connector>
</connectors>
</configuration>
<executions>
<execution>
<id>start-it-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-it-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<profile>
<id>ittest</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>run-integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<contextPath>/</contextPath>
<stopPort>9966</stopPort>
<stopKey>stop-jetty-for-it</stopKey>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>6211</port>
</connector>
</connectors>
</configuration>
<executions>
<execution>
<id>start-it-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-it-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
然后就可以編寫測試用例了
步驟如下:
1,定義一個以此命名的****IT的測試類(integration test縮寫), 在里面華麗的寫好你的測試邏輯。
再此不舉例了,主要一個思路可以用httpclint來實現(xiàn)里面的測試代碼。
2,然后 執(zhí)行 mvn clean post-integration-test -Pittest
好了 就可以看到我們測試用例是否通過。
摘要: 在linux服務器上,因為gui顯示的問題。我們直接jconsole時。就會報Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException: No X11 DISPLAY variable was set, but this program performed an operation which requires it.&nb... 閱讀全文
我們部門底層的web應用有一套處理編碼的流程機制,主要處理因歷史原因或者跨部門產品之間gbk和utf8剪不清理還亂的關系。
前2天同事有詢問相關編碼的問題,在此做個整理,希望能夠對大家有所幫助。
首先是編碼的歷史,這是一個很有意思的解讀 。寫的很幽默,便于理解。
下面主要寫于與java想關的編碼,主要解讀unicode ,utf8 和gbk。
參考資料:
前2天同事有詢問相關編碼的問題,在此做個整理,希望能夠對大家有所幫助。
首先是編碼的歷史,這是一個很有意思的解讀 。寫的很幽默,便于理解。
下面主要寫于與java想關的編碼,主要解讀unicode ,utf8 和gbk。
JVM里面的任何字符串資源都是Unicode,就是說,任何String類型的數據都是Unicode編碼。沒有例外,因此我們可以這么說,JVM里面的String是不帶編碼的。因為他就有且只對應一種Unicode。
一個字符的Unicode編碼是確定的。也就是說Unicode是一種字符集,里面字符與編碼是一一對應的,這里有個碼表可查,unicode 碼表。但是在實際傳輸過程中,由于不同系統(tǒng)平臺的設計不一定一致,以及出于節(jié)省空間的目的,對Unicode編碼的實現(xiàn)方式有所不同。Unicode的實現(xiàn)方式稱為Unicode轉換格式(Unicode Transformation Format,簡稱為UTF)。我們常用的就是UTF8.
UTF8是如何存儲一個Unicode編碼的呢。也就是utf8作為一種Unicode Transformation Format是如何工作的呢?
首先utf8 是可變長的,UTF-8使用一至四個字節(jié)為每個字符編碼。參照下表,我們把精力放在第1列,第3列,和注釋。

UTF8是如何存儲一個Unicode編碼的呢。也就是utf8作為一種Unicode Transformation Format是如何工作的呢?
首先utf8 是可變長的,UTF-8使用一至四個字節(jié)為每個字符編碼。參照下表,我們把精力放在第1列,第3列,和注釋。
對于ASCII字符,可以用七個bit位來表示,x6 x5 x4 x3 x2 x1 x0.第八個bit永遠是0。
第128到2047個字節(jié),要用10個bit來表示,110yyyyy(C0-DF) 10zzzzzz(80-BF)
舉個例子:“中國”的中,unicode編碼是“\u4e2d", 對應的編碼除了查表,java可以用命令行,運行 native2ascii 進行轉化。
用window 自帶的附件中的計算器(查看->科學型),轉化成10進制為20013,二進制是100111000101101
通過上面的表,可知,轉化成utf8后為三個字節(jié)。
第2048到65535個字節(jié),要用16個bit來表示,Utf-8把這些字節(jié)編成下面這樣的三個byte。1110xxxx(E0-EF) 10yyyyyy 10zzzzzz
大于65535其余用4個byte來表示。舉個例子:“中國”的中,unicode編碼是“\u4e2d", 對應的編碼除了查表,java可以用命令行,運行 native2ascii 進行轉化。
用window 自帶的附件中的計算器(查看->科學型),轉化成10進制為20013,二進制是100111000101101
通過上面的表,可知,轉化成utf8后為三個字節(jié)。
只需要將剛才轉化的二進制(上面標紅的)將下面的xxxx,yyyyyy,zzzzzz補齊即可。
1110xxxx(E0-EF) 10yyyyyy 10zzzzzz,我們從低位開始補起,不夠的用0補齊。
11100100 10111000 10101101 ,換成16進制為E4 B8 AD。
好了我們用java代碼來驗證下,是否正確。
輸出果然是:e4 b8 ad。
utf8 wiki中有下描述:
反過來,我們還是拿剛才的”中“為例,11100100 10111000 10101101 ,第一個字節(jié)開始為110,則讀第二個字節(jié)為10,第三個字節(jié)為10,則認為是utf8字符。
于是就有了一個那個經典的“聯(lián)通"干不過”移動“的經典段子。
我們在xp下,隨便建立一個文件,輸入"聯(lián)通",保存,這時你在打開是,發(fā)現(xiàn)”聯(lián)通"2個字符不見了。奇怪嗎??????
通過上面的描述GBk和UTF8關系也就很明朗了,完全可以通過Unicode進行中轉。
同事在詢問編碼的問題時,一開始對類似如下代碼,相互轉變不太理解。
其實我們可以把getBytes("gbk"),這個函數當做將unicode用gkb加密的過程,而new String(”xxx“,"編碼”)看成是解密的一個過程。
大家思考一下最后面的那個輸出可以得到正確的結果嗎?為什么?
下面我們來討論 ,通過http協(xié)議下的url傳輸后,編碼轉化問題。
首先說明的是本人本地默認編碼是gbk。
我們只用Servlet,不使用任何框架比如spring(因為使用框架時,框架也有一套自己自己的機制)如下代碼
jetty容器下輸出為
resin下為:
換做127.0.0.1/test?encode=%E5%93%88 ,utf8編碼的”哈“
jetty和resin下都輸出如下
為什么會是這樣?
我們拿jetty分析,在jetty的源碼中,
也就是如果_queryEncoding為null時,默認是用utf8進行解碼的。而resin也不例外。
jetty中_queryEncoding的值可以通過org.mortbay.jetty.Request.queryEncoding 這個屬性給賦值而resin采用的是req.getCharacterEncoding()中的值為標準。
要想在jetty下 127.0.0.1/test?encode=%B9%FE,獲取到正確的字符,代碼如下
resin下只需要
通過上面想說明的是,不同的容器,默認編碼的策略是不一致的。只要我們了解編碼的基礎知識。通過一些封裝就很容易掌控這個局面。
11100100 10111000 10101101 ,換成16進制為E4 B8 AD。
好了我們用java代碼來驗證下,是否正確。
public static void main(String[] args) {
String ha = "中";
byte b[] = null;
try {
b = ha.getBytes("utf-8");
} catch (Exception e) {
System.exit(-1);
}
for (int i = 0; i < b.length; i++) {
System.out.print(Integer.toHexString(b[i]).substring(6) + " ");
}
}
String ha = "中";
byte b[] = null;
try {
b = ha.getBytes("utf-8");
} catch (Exception e) {
System.exit(-1);
}
for (int i = 0; i < b.length; i++) {
System.out.print(Integer.toHexString(b[i]).substring(6) + " ");
}
}
utf8 wiki中有下描述:
- 對于UTF-8編碼中的任意字節(jié)B,如果B的第一位為0,則B為ASCII碼,并且B獨立的表示一個字符;
- 如果B的第一位為1,第二位為0,則B為一個非ASCII字符(該字符由多個字節(jié)表示)中的一個字節(jié),并且不為字符的第一個字節(jié)編碼;
- 如果B的前兩位為1,第三位為0,則B為一個非ASCII字符(該字符由多個字節(jié)表示)中的第一個字節(jié),并且該字符由兩個字節(jié)表示;
- 如果B的前三位為1,第四位為0,則B為一個非ASCII字符(該字符由多個字節(jié)表示)中的第一個字節(jié),并且該字符由三個字節(jié)表示;
- 如果B的前四位為1,第五位為0,則B為一個非ASCII字符(該字符由多個字節(jié)表示)中的第一個字節(jié),并且該字符由四個字節(jié)表示;
因此,對UTF-8編碼中的任意字節(jié),根據第一位,可判斷是否為ASCII字符;根據前二位,可判斷該字節(jié)是否為一個字符編碼的第一個字節(jié); 根據前四位(如果前兩位均為1),可確定該字節(jié)為字符編碼的第一個字節(jié),并且可判斷對應的字符由幾個字節(jié)表示;根據前五位(如果前四位為1),可判斷編碼 是否有錯誤或數據傳輸過程中是否有錯誤。
反過來,我們還是拿剛才的”中“為例,11100100 10111000 10101101 ,第一個字節(jié)開始為110,則讀第二個字節(jié)為10,第三個字節(jié)為10,則認為是utf8字符。
于是就有了一個那個經典的“聯(lián)通"干不過”移動“的經典段子。
我們在xp下,隨便建立一個文件,輸入"聯(lián)通",保存,這時你在打開是,發(fā)現(xiàn)”聯(lián)通"2個字符不見了。奇怪嗎??????
我們知道默認保存的編碼是ANSI,實際也是類GBK的編碼。
對應16進制為c1 aa cd a8, 轉化成二進制為11000001 10101010 11001101 10101000 ,我們來看,110xxxxx,10xxxxxx 正好符合utf8的形式。
這時候文件編寫器以為你的文件是utf8的文件,然后默認已utf8的形式給你打開展示。于是就出現(xiàn)亂碼了。如果你在”聯(lián)通“后面隨便加幾個字符。就不出出現(xiàn)靈異事件了。
那么我們繼續(xù)討論 GBK和Unicode是什么關系呢?
實際上GBK我們可以看做是字符集,他也有自己一一對應的碼表。google一下,很容易查到。這里有個Unicode和GBk對應的表Unicode-GBk。
在java中,
進行轉化,其實就是類似查一個Unicode和GBk對應表進行轉化的。大家看一下Charset這個抽象類的那些子類就明白了。這時候文件編寫器以為你的文件是utf8的文件,然后默認已utf8的形式給你打開展示。于是就出現(xiàn)亂碼了。如果你在”聯(lián)通“后面隨便加幾個字符。就不出出現(xiàn)靈異事件了。
那么我們繼續(xù)討論 GBK和Unicode是什么關系呢?
實際上GBK我們可以看做是字符集,他也有自己一一對應的碼表。google一下,很容易查到。這里有個Unicode和GBk對應的表Unicode-GBk。
在java中,
"我愛你莎莎".getBytes("gbk");
通過上面的描述GBk和UTF8關系也就很明朗了,完全可以通過Unicode進行中轉。
同事在詢問編碼的問題時,一開始對類似如下代碼,相互轉變不太理解。
byte b1[] = null;
b1 = "我愛你莎莎".getBytes("gbk");
System.out.println(new String(b1,"gbk"));
byte b2[] = null;
b2 = "我愛你莎莎".getBytes("utf8");
System.out.println(new String(b2,"utf8"));
System.out.println(new String (new String (b2,"gbk").getBytes("gbk"),"utf8"));
b1 = "我愛你莎莎".getBytes("gbk");
System.out.println(new String(b1,"gbk"));
byte b2[] = null;
b2 = "我愛你莎莎".getBytes("utf8");
System.out.println(new String(b2,"utf8"));
System.out.println(new String (new String (b2,"gbk").getBytes("gbk"),"utf8"));
大家思考一下最后面的那個輸出可以得到正確的結果嗎?為什么?
下面我們來討論 ,通過http協(xié)議下的url傳輸后,編碼轉化問題。
首先說明的是本人本地默認編碼是gbk。
我們只用Servlet,不使用任何框架比如spring(因為使用框架時,框架也有一套自己自己的機制)如下代碼
public class HttpEncode extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = req.getQueryString();
System.out.println(req.getCharacterEncoding());
String encode = null;
try {
encode = req.getParameter("encode");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(str);
System.out.println(encode);
}
}
我們分別用jetty(版本6.1)和resin(版本3.1.8)下容器,測試如下請求 127.0.0.1/test?encode=%B9%FE 其中%B9%FE為GBk的編碼的漢字”哈“@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = req.getQueryString();
System.out.println(req.getCharacterEncoding());
String encode = null;
try {
encode = req.getParameter("encode");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(str);
System.out.println(encode);
}
}
jetty容器下輸出為
null
encode=%B9%FE
?
encode=%B9%FE
?
null
encode=%B9%FE
null
encode=%B9%FE
null
換做127.0.0.1/test?encode=%E5%93%88 ,utf8編碼的”哈“
jetty和resin下都輸出如下
null
encode=%E5%93%88
哈
encode=%E5%93%88
哈
為什么會是這樣?
我們拿jetty分析,在jetty的源碼中,
public String getParameter(String name)
{
if (!_paramsExtracted)
extractParameters();
return (String) _parameters.getValue(name, 0);
}
{
if (!_paramsExtracted)
extractParameters();
return (String) _parameters.getValue(name, 0);
}
對應的
extractParameters(); 部分代碼 if (_queryEncoding==null)
_uri.decodeQueryTo(_baseParameters);
然后
_uri.decodeQueryTo(_baseParameters);
然后
public void decodeQueryTo(MultiMap parameters)
{
if (_query==_fragment)
return;
_utf8b.reset();
UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b);
}
{
if (_query==_fragment)
return;
_utf8b.reset();
UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b);
}
也就是如果_queryEncoding為null時,默認是用utf8進行解碼的。而resin也不例外。
jetty中_queryEncoding的值可以通過org.mortbay.jetty.Request.queryEncoding 這個屬性給賦值而resin采用的是req.getCharacterEncoding()中的值為標準。
要想在jetty下 127.0.0.1/test?encode=%B9%FE,獲取到正確的字符,代碼如下
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = req.getQueryString();
System.out.println(req.getCharacterEncoding());
req.setAttribute("org.mortbay.jetty.Request.queryEncoding", "gbk");
String encode = null;
try {
encode = req.getParameter("encode");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(str);
System.out.println(encode);
}
String str = req.getQueryString();
System.out.println(req.getCharacterEncoding());
req.setAttribute("org.mortbay.jetty.Request.queryEncoding", "gbk");
String encode = null;
try {
encode = req.getParameter("encode");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(str);
System.out.println(encode);
}
resin下只需要
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = req.getQueryString();
req.setCharacterEncoding("gbk");
System.out.println(req.getCharacterEncoding());
String encode = null;
try {
encode = req.getParameter("encode");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(str);
System.out.println(encode);
}
String str = req.getQueryString();
req.setCharacterEncoding("gbk");
System.out.println(req.getCharacterEncoding());
String encode = null;
try {
encode = req.getParameter("encode");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(str);
System.out.println(encode);
}
通過上面想說明的是,不同的容器,默認編碼的策略是不一致的。只要我們了解編碼的基礎知識。通過一些封裝就很容易掌控這個局面。
參考資料:
Unicode wiki: http://zh.wikipedia.org/wiki/Unicode
jetty 源碼
jetty 源碼