
2015年11月20日
提示:編寫Eclipse常用快捷鍵寫成文檔,主要是為了自己熟悉一下這些快捷鍵,方便以后查找和編程中使用!
一、編輯類快捷鍵
1、Ctrl + 1 快速修復(fù),可以解決很多問題,例如import類、try catch包圍等。
2、Ctrl + Shift + F 格式化當(dāng)前代碼。
3、Ctrl + Shift + M 添加類的import引入。
4、Ctrl + Shift + M 組織類的import引入,既有Ctrl + Shift + M 的作用,又可以幫你去除沒有用的引入。
5、Ctrl + Y 重做與Ctrl + Z 相反的作用。
6、Alt + / 內(nèi)容輔助
7、Ctrl + D 刪除當(dāng)前行或者選中的多行
8、Alt + Down 當(dāng)前行和下面一行交換位置
9、Alt + Up 當(dāng)前行和上面一行交換位置
10、Shift + Enter 在當(dāng)前行的下一行插入空行
11、Ctrl + / 注釋當(dāng)前行,再次按則取消注釋
二、選擇快捷鍵
1、Alt + Shift + Up 選擇封裝元素
2、Alt + Shift + Left 選擇上一個(gè)元素
3、Alt + Shift + Right選擇下一個(gè)元素
4、Shift + Left 從光標(biāo)處開始往左選擇字符串
5、Shift + Right 從光標(biāo)處開始往右選擇字符串
6、Ctrl + Shift + Left 選中光標(biāo)左邊的單詞
7、Ctrl + Shift + Right 選中光標(biāo)右邊的單詞
三、移動(dòng)快捷鍵
1、Ctrl + Left 光標(biāo)移到左邊單詞的開頭,
2、Ctrl + Right 光標(biāo)移到右邊單詞的末尾。
四、搜索快捷鍵
1、Ctrl + K 參照選中的文字快速定位到下一個(gè),如果沒有選中文字則搜索上一次使用搜索的文字。
2、Ctrl + Shift + K 參照選中的文字快速定位到上一個(gè)。
3、Ctrl + J 正向增量查找,按下這個(gè)快捷鍵后,你所輸入的每個(gè)字母編輯器都提供快速匹配到某個(gè)單詞,如果沒有在狀態(tài)欄中顯示沒有找到,退出這個(gè)模式按ESC鍵。
4、Ctrl + Shift + J 反向增量查找
5、Ctrl + Shift + U 列出所有包含字符串的行
6、Ctrl + G 工作區(qū)中的聲明
7、Ctrl + Shift + G 工作區(qū)中的引用
五、導(dǎo)航快捷鍵
1、Ctrl + Shift + T 搜索類
2、Ctrl + Shift + R 搜索工程中的文件
3、Ctrl + E 快速顯示當(dāng)前編輯區(qū)的下拉列表
4、F4 打開類型層次結(jié)構(gòu)
5、F3 跳轉(zhuǎn)到聲明處
6、Alt + Left 前一個(gè)編輯頁(yè)面
7、Alt + Right 下一個(gè)編輯頁(yè)面
8、Ctrl + PageUp/PageDown在編輯器中,切換已經(jīng)打開的文件
六、調(diào)試快捷鍵
1、F5 單步跳入
2、F6 單步跳過
3、F7 單步還回
4、F8 繼續(xù)
5、Ctrl + Shift + D 顯示變量的值
6、Ctrl + shift + B 在當(dāng)前行設(shè)置或者去掉斷點(diǎn)
7、Ctrl + R 運(yùn)行至行,比較好用可以省好多的斷點(diǎn)
七、重構(gòu)快捷鍵
1、Alt + Shift + R 重命名類名、方法名、屬性(變量)名。
2、Alt + Shift + M 把一段函數(shù)內(nèi)的代碼抽取成方法,這是重構(gòu)里面最常用的方法之一,特別是對(duì)于一大坨代碼很有用。
3、Alt + Shift + C 修改函數(shù)結(jié)構(gòu),比較實(shí)用有N個(gè)函數(shù)調(diào)用了這個(gè)方法修改一次就行了。
4、Alt + Shift + L 抽取本地變量,可以直接把一些魔法數(shù)字和字符串抽取成一個(gè)變量,尤其是多出調(diào)用的時(shí)候。
5、Alt + Shift + F 把Class中的局部變量變?yōu)槿肿兞?/div>
6、Alt + Shift + I 合并變量,將創(chuàng)建簡(jiǎn)化
7、Alt + Shift + Z 撤銷重構(gòu)
八、其他快捷鍵
1、Alt + Enter 顯示當(dāng)前選擇資源的屬性,在windows下查看文件的屬性就是這個(gè)快捷鍵,通常可以用來(lái)查看文件在windows中的實(shí)際路徑。
2、Ctrl + Up文本編輯器向上滾行
3、Ctrl + Down 文本編輯器向下滾行
4、Ctrl + M 最大化當(dāng)前的Edit或者View,再按則縮小
5、Ctrl + O 快速顯示Outline
6、Ctrl + T 快速顯示當(dāng)前類的繼承結(jié)構(gòu),選中接口方法按下這快捷可以跳轉(zhuǎn)到實(shí)現(xiàn)類,在項(xiàng)目DAO中經(jīng)常用。
7、Ctrl + W 關(guān)閉當(dāng)前Editer
8、Ctrl + L 文本編輯器轉(zhuǎn)至行
9、F2 顯示工具提示描述,選擇類或者變量按下該鍵會(huì)有提示出來(lái)
posted @
2015-11-20 16:36 ForMeBlog 閱讀(450) |
評(píng)論 (0) |
編輯 收藏

2015年8月18日
今天遇到調(diào)用encodeURL調(diào)用二次的疑問,雖然之前知道要調(diào)用二次,但是具體不是太清楚里面具體的運(yùn)行過程,這是轉(zhuǎn)載的這個(gè)寫的比較詳細(xì),把整個(gè)運(yùn)行過程詳細(xì)解讀了一下,非常不錯(cuò)所以轉(zhuǎn)載過了供其他人分享。
.encodeURL函數(shù)主要是來(lái)對(duì)URI來(lái)做轉(zhuǎn)碼,它默認(rèn)是采用的UTF-8的編碼.
. UTF-8編碼的格式:一個(gè)漢字來(lái)三個(gè)字節(jié)構(gòu)成,每一個(gè)字節(jié)會(huì)轉(zhuǎn)換成16進(jìn)制的編碼,同時(shí)添加上%號(hào).
假設(shè)頁(yè)面端輸入的中文是一個(gè)“中”,按照下面步驟進(jìn)行解碼
1.第一次encodeURI,按照utf-8方式獲取字節(jié)數(shù)組變成[-28,-72-83],對(duì)字節(jié)碼數(shù)組進(jìn)行遍歷,把每個(gè)字節(jié)轉(zhuǎn)化成對(duì)應(yīng)的16進(jìn)制數(shù),這樣就變成了[E4,B8,AD],最后變成[%E4,%B8,%AD] 此時(shí)已經(jīng)沒有了多字節(jié)字符,全部是單字節(jié)字符。
2、第二次encodeURI,進(jìn)行編碼,會(huì)把%看成一個(gè)轉(zhuǎn)義字符,并不編碼%以后字符,會(huì)把%編碼成%25.把數(shù)組最后變成[%25E4,%25B8,%25AD]然后就把處理后的數(shù)據(jù)[%25E4,%25B8,%25AD]發(fā)往服務(wù)器端,
當(dāng)應(yīng)用服務(wù)器調(diào)用getParameter方法,getParameter方法會(huì)去向應(yīng)用服務(wù)器請(qǐng)求參數(shù)
應(yīng)用服務(wù)器最初獲得的就是發(fā)送來(lái)的[%25E4,%25B8,%25AD],應(yīng)用服務(wù)器會(huì)對(duì)這個(gè)數(shù)據(jù)進(jìn)行URLdecode操作,應(yīng)用服務(wù)器進(jìn)行解碼的這一次,不管是按照UTF-8,還是GBK,還是ISO-8859,,都能得到[%E4,%B8,%AD],因?yàn)槎紩?huì)把%25解析成%.并把這個(gè)值返回給getParameter方法
3\、再用UTF-8解碼一次,就得到"中"了。
想想看,如果不編碼兩次,當(dāng)服務(wù)器自動(dòng)解碼的時(shí)候,假如是按照ISO-8859去解碼UTF-8編碼的東西,就是會(huì)出現(xiàn)亂碼。
JS:
- document.authorityForm.action = basePath3+"User_viewUser.do?id="+id+"&roleName="+encodeURI(encodeURI(roleName))+"&roleType="+roleType;
JAVA后臺(tái):
- roleName = java.net.URLDecoder.decode(getRequest().getParameter("roleName"),"UTF-8");
posted @
2015-08-18 11:20 ForMeBlog 閱讀(421) |
評(píng)論 (0) |
編輯 收藏

2015年6月11日
一、概念
Annontation是Java5開始引入的新特征。中文名稱一般叫注解。它提供了一種安全的類似注釋的機(jī)制,用來(lái)將任何的信息或元數(shù)據(jù)(metadata)與程序元素(類、方法、成員變量等)進(jìn)行關(guān)聯(lián)。
更通俗的意思是為程序的元素(類、方法、成員變量)加上更直觀更明了的說(shuō)明,這些說(shuō)明信息是與程序的業(yè)務(wù)邏輯無(wú)關(guān),并且是供指定的工具或框架使用的。
Annontation像一種修飾符一樣,應(yīng)用于包、類型、構(gòu)造方法、方法、成員變量、參數(shù)及本地變量的聲明語(yǔ)句中。
二、原理
Annotation其實(shí)是一種接口。通過Java的反射機(jī)制相關(guān)的API來(lái)訪問annotation信息。相關(guān)類(框架或工具中的類)根據(jù)這些信息來(lái)決定如何使用該程序元素或改變它們的行為。
annotation是不會(huì)影響程序代碼的執(zhí)行,無(wú)論annotation怎么變化,代碼都始終如一地執(zhí)行。
Java語(yǔ)言解釋器在工作時(shí)會(huì)忽略這些annotation,因此在JVM 中這些annotation是“不起作用”的,只能通過配套的工具才能對(duì)這些annontaion類型的信息進(jìn)行訪問和處理。
Annotation與interface的異同:
1)、Annotation類型使用關(guān)鍵字@interface而不是interface。
這個(gè)關(guān)鍵字聲明隱含了一個(gè)信息:它是繼承了java.lang.annotation.Annotation接口,并非聲明了一個(gè)interface
2)、Annotation類型、方法定義是獨(dú)特的、受限制的。
Annotation 類型的方法必須聲明為無(wú)參數(shù)、無(wú)異常拋出的。這些方法定義了annotation的成員:方法名成為了成員名,而方法返回值成為了成員的類型。而方法返回值類型必須為primitive類型、Class類型、枚舉類型、annotation類型或者由前面類型之一作為元素的一維數(shù)組。方法的后面可以使用 default和一個(gè)默認(rèn)數(shù)值來(lái)聲明成員的默認(rèn)值,null不能作為成員默認(rèn)值,這與我們?cè)诜?span style="font-family: DejaVu Serif, serif" face="DejaVu Serif, serif">annotation類型中定義方法有很大不同。
Annotation類型和它的方法不能使用annotation類型的參數(shù)、成員不能是generic。只有返回值類型是Class的方法可以在annotation類型中使用generic,因?yàn)榇朔椒軌蛴妙愞D(zhuǎn)換將各種類型轉(zhuǎn)換為Class。
3)、Annotation類型又與接口有著近似之處。
它們可以定義常量、靜態(tài)成員類型(比如枚舉類型定義)。Annotation類型也可以如接口一般被實(shí)現(xiàn)或者繼承。
三、應(yīng)用場(chǎng)合
annotation一般作為一種輔助途徑,應(yīng)用在軟件框架或工具中,在這些工具類中根據(jù)不同的 annontation注解信息采取不同的處理過程或改變相應(yīng)程序元素(類、方法及成員變量等)的行為。
例如:Junit、Struts、Spring等流行工具框架中均廣泛使用了annontion。使代碼的靈活性大提高。
四、常見標(biāo)準(zhǔn)的Annotation
從java5版本開始,自帶了三種標(biāo)準(zhǔn)annontation類型,
(1)、Override
java.lang.Override 是一個(gè)marker annotation類型,它被用作標(biāo)注方法。它說(shuō)明了被標(biāo)注的方法重載了父類的方法,起到了斷言的作用。如果我們使用了這種annotation在一個(gè)沒有覆蓋父類方法的方法時(shí),java編譯器將以一個(gè)編譯錯(cuò)誤來(lái)警示。
這個(gè)annotaton常常在我們?cè)噲D覆蓋父類方法而確又寫錯(cuò)了方法名時(shí)加一個(gè)保障性的校驗(yàn)過程。
(2)、Deprecated
Deprecated也是一種marker annotation。當(dāng)一個(gè)類型或者類型成員使用@Deprecated修飾的話,編譯器將不鼓勵(lì)使用這個(gè)被標(biāo)注的程序元素。所以使用這種修飾具有一定的 “延續(xù)性”:如果我們?cè)诖a中通過繼承或者覆蓋的方式使用了這個(gè)過時(shí)的類型或者成員,雖然繼承或者覆蓋后的類型或者成員并不是被聲明為 @Deprecated,但編譯器仍然要報(bào)警。
注意:@Deprecated這個(gè)annotation類型和javadoc中的 @deprecated這個(gè)tag是有區(qū)別的:前者是java編譯器識(shí)別的,而后者是被javadoc工具所識(shí)別用來(lái)生成文檔(包含程序成員為什么已經(jīng)過時(shí)、它應(yīng)當(dāng)如何被禁止或者替代的描述)。
(3)、SuppressWarnings
此注解能告訴Java編譯器關(guān)閉對(duì)類、方法及成員變量的警告。
有時(shí)編譯時(shí)會(huì)提出一些警告,對(duì)于這些警告有的隱藏著Bug,有的是無(wú)法避免的,對(duì)于某些不想看到的警告信息,可以通過這個(gè)注解來(lái)屏蔽。
SuppressWarning不是一個(gè)marker annotation。它有一個(gè)類型為String[]的成員,這個(gè)成員的值為被禁止的警告名。對(duì)于javac編譯器來(lái)講,被-Xlint選項(xiàng)有效的警告名也同樣對(duì)@SuppressWarings有效,同時(shí)編譯器忽略掉無(wú)法識(shí)別的警告名。
annotation語(yǔ)法允許在annotation名后跟括號(hào),括號(hào)中是使用逗號(hào)分割的name=value對(duì)用于為annotation的成員賦值:
代碼:
@SuppressWarnings(value={"unchecked","fallthrough"})
public void lintTrap() { /* sloppy method body omitted */ }
在這個(gè)例子中SuppressWarnings annotation類型只定義了一個(gè)單一的成員,所以只有一個(gè)簡(jiǎn)單的value={...}作為name=value對(duì)。又由于成員值是一個(gè)數(shù)組,故使用大括號(hào)來(lái)聲明數(shù)組值。
注意:我們可以在下面的情況中縮寫annotation:當(dāng)annotation只有單一成員,并成員命名為"value="。這時(shí)可以省去"value="。比如將上面的SuppressWarnings annotation進(jìn)行縮寫:
代碼:
@SuppressWarnings({"unchecked","fallthrough"})
如果SuppressWarnings所聲明的被禁止警告?zhèn)€數(shù)為一個(gè)時(shí),可以省去大括號(hào):
@SuppressWarnings("unchecked")
五、自定義annontation示例
示例共涉及四個(gè)類:
清單1:Author.java
package com.magc.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 定義作者信息,name和group
* @author magc
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Author {
String name();
String group();
}
清單2:Description.java
/**
*
*/
package com.magc.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author magc
*
* 定義描述信息 value
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface Description {
String value();
}
清單3:Utility.java
package com.magc.annotation;
@Description(value = "這是一個(gè)有用的工具類")
public class Utility {
@Author(name = "haoran_202",group="com.magc")
public String work()
{
return "work over!";
}
}
注:這是個(gè)普通的Java類,運(yùn)行了@Description和@Author注解。
清單3:AnalysisAnnotation.java
package com.magc.annotation;
import java.lang.reflect.Method;
public class AnalysisAnnotation {
/**
* 在運(yùn)行時(shí)分析處理annotation類型的信息
*
*
*/
public static void main(String[] args) {
try {
//通過運(yùn)行時(shí)反射API獲得annotation信息
Class rt_class = Class.forName("com.magc.annotation.Utility");
Method[] methods = rt_class.getMethods();
boolean flag = rt_class.isAnnotationPresent(Description.class);
if(flag)
{
Description description = (Description)rt_class.getAnnotation(Description.class);
System.out.println("Utility's Description--->"+description.value());
for (Method method : methods) {
if(method.isAnnotationPresent(Author.class))
{
Author author = (Author)method.getAnnotation(Author.class);
System.out.println("Utility's Author--->"+author.name()+" from "+author.group());
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
注:這是個(gè)與自定義@Description和@Author配套的基礎(chǔ)框架或工具類,通過此類來(lái)獲得與普通Java類Utility.java關(guān)聯(lián)的信息,即描述和作者。
運(yùn)行AnalysisAnnotation,輸出結(jié)果為:
Utility's Description--->這是一個(gè)有用的工具類
Utility's Author--->haoran_202 from com.magc
posted @
2015-06-11 18:06 ForMeBlog 閱讀(255) |
評(píng)論 (0) |
編輯 收藏

2015年3月12日
在ORACLE 數(shù)據(jù)庫(kù)中有一種方法可以實(shí)現(xiàn)級(jí)聯(lián)查詢
select * //要查詢的字段
from table //具有子接點(diǎn)ID與父接點(diǎn)ID的表
start with selfid=id //給定一個(gè)startid(字段名為子接點(diǎn)ID,及開始的ID號(hào))
connect by prior selfid=parentid //聯(lián)接條件為子接點(diǎn)等于父接點(diǎn),不能反
這個(gè)SQL主要用于菜單的級(jí)聯(lián)查詢,給一個(gè)父接點(diǎn)可以查出所有的子接點(diǎn)。及子接點(diǎn)的子接點(diǎn),一查到底,很實(shí)用。不過呢這個(gè)程序只能在oracle里面用,我目前還不知道在其它數(shù)據(jù)庫(kù)里是怎么調(diào)用的。等我找到了,再貼出來(lái)與大家分享。
這個(gè)程序,估計(jì)好多人看不明白,其實(shí)放了這么久我也一時(shí)沒看明白,重新測(cè)了一下,補(bǔ)充說(shuō)明一下,不然我下次又看不懂了。
以一個(gè)windows系統(tǒng)的菜單為例。我那一個(gè)這樣的表menu。
說(shuō)明:
mid:菜單的ID號(hào)
mname:菜單名稱
mpid:菜單的
quickey:快捷鍵
validate:權(quán)限表(存放userid,或者角色id)
mid |
mname |
mpid |
quickey |
validate |
1 |
文件 |
|
ctrl+f |
1,2,3,4,11,23,45 |
2 |
編輯 |
|
ctrl+e |
|
3 |
新建 |
1 |
alt+w |
|
4 |
文件夾 |
3 |
|
|
如果我想知道在“文件”菜單下有那些子菜單的話。我就可以這樣用這個(gè)SQL程序:
select * from menu
start with mid=1
connect by prior mid=mpid;
這樣就可以把 “文件”里的子菜單全部列出來(lái)了。當(dāng)然實(shí)際應(yīng)用不會(huì)這么簡(jiǎn)單,如附加其實(shí)條件,尤其是權(quán)限管理,這時(shí)根據(jù)你的系統(tǒng)要求,是對(duì)個(gè)個(gè)驗(yàn)證,還是對(duì)角色驗(yàn)證,把這些人的ID放在validate這個(gè)字段里,組成一個(gè)字符串,N個(gè)ID用逗號(hào)隔開,(注意,在往數(shù)據(jù)庫(kù)保存時(shí)要注意對(duì)字符串處理一下,截取掉最后一個(gè)逗號(hào)這樣可以節(jié)省很多麻煩)
select * from menu
where validate in(……)
and mid in(
select mid from menu //這里不能用*號(hào)了。
start with mid=1
connect by prior mid=mpid;
)
最后再補(bǔ)充一點(diǎn)關(guān)于隨機(jī)查詢的代碼
select * from user order by sys_guid()
posted @
2015-03-12 12:04 ForMeBlog 閱讀(1478) |
評(píng)論 (0) |
編輯 收藏

2015年1月21日
今天看到某網(wǎng)友關(guān)于“如何以Java實(shí)現(xiàn)網(wǎng)頁(yè)截圖技術(shù)”的咨詢帖,由于出現(xiàn)該咨詢的地點(diǎn)非常不適合較長(zhǎng)回復(fù),故以博文形式回答。
事實(shí)上,如果您想以Java實(shí)現(xiàn)網(wǎng)頁(yè)截圖,也就是“輸入一段網(wǎng)址,幾秒鐘過后就能截取一張網(wǎng)頁(yè)縮略圖”的效果。那么,您至少有3種方式可以選擇。
1、最直接的方式——使用Robot
方法詳解:該方法利用Robat提供的強(qiáng)大桌面操作能力,硬性調(diào)用瀏覽器打開指定網(wǎng)頁(yè),并將網(wǎng)頁(yè)信息保存到本地。
優(yōu)勢(shì):簡(jiǎn)單易用,不需要任何第三方插件。
缺點(diǎn):不能同時(shí)處理大量數(shù)據(jù),技術(shù)含量過低,屬于應(yīng)急型技巧。
實(shí)現(xiàn)方法:使用如下代碼即可
- public static void main(String[] args) throws MalformedURLException,
- IOException, URISyntaxException, AWTException {
-
- Desktop.getDesktop().browse(
- new URL("http://google.com/intl/en/").toURI());
- Robot robot = new Robot();
- robot.delay(10000);
- Dimension d = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());
- int width = (int) d.getWidth();
- int height = (int) d.getHeight();
-
- robot.keyRelease(KeyEvent.VK_F11);
- robot.delay(2000);
- Image image = robot.createScreenCapture(new Rectangle(0, 0, width,
- height));
- BufferedImage bi = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_RGB);
- Graphics g = bi.createGraphics();
- g.drawImage(image, 0, 0, width, height, null);
-
- ImageIO.write(bi, "jpg", new File("google.jpg"));
- }
2、最常規(guī)的方式——利用JNI,調(diào)用第三方C/C++組件
方法詳解:目前來(lái)講,Java領(lǐng)域?qū)τ诰W(wǎng)頁(yè)截圖組件的開發(fā)明顯不足(商機(jī)?),當(dāng)您需要完成此種操作時(shí),算得上碰到了Java的軟肋。但是,眾所周知Java也擁有強(qiáng)大的JNI能力,可以輕易將C/C++開發(fā)的同類組件引為己用。
優(yōu)勢(shì):實(shí)現(xiàn)簡(jiǎn)單,只需要封裝對(duì)應(yīng)的DLL文件,就可以讓Java實(shí)現(xiàn)同類功能。
劣勢(shì):同其他JNI實(shí)現(xiàn)一樣,在跨平臺(tái)時(shí)存在隱患,而且您的程序?qū)⒉辉賹儆诩僇ava應(yīng)用。
實(shí)現(xiàn)方法:可參見此用例,具體封裝何種C/C++組件請(qǐng)自行選擇。
PS:示例來(lái)源于ACA HTML to Image Converter項(xiàng)目(http://www.acasystems.com/en/web-thumb-activex/faq-convert-html-to-image-in-java.htm ),這是一個(gè)收費(fèi)的HTML轉(zhuǎn)Image第三方組件,但封裝方式在Java中大同小異。
引用JNI封裝:
- import sun.awt.*;
- import java.awt.*;
- import javax.swing.*;
- import java.awt.event.*;
- import java.awt.*;
- import java.awt.peer.*;
- public class Snap
- {
- static
- {
- System.loadLibrary("Snap");
- }
- public static void main( String[] argv )
- {
- Snap t_xSnap = new Snap();
- t_xSnap.Start("http://www.google.com", "snapshot-google.png");
- }
- public native void Start(String pi_strURL, String pi_strImageName);
- }
CPP部分的實(shí)現(xiàn):
- #include <windows.h>
- #include <atlbase.h>
- #include "snap.h"
- #pragma comment(lib,"atl.lib")
- #import "./../../acawebthumb.dll" no_namespace
- JNIEXPORT void JNICALL Java_Snap_Start(JNIEnv *pEnv, jobject, jstring pi_strUrl, jstring pi_strFileName)
- {
- CoInitialize(0);
- _bstr_t t_strUrl = pEnv->GetStringUTFChars(pi_strUrl, 0);
- _bstr_t t_strFileName = pEnv->GetStringUTFChars(pi_strFileName, 0);
- IThumbMakerPtr HTML_Converter = NULL;
- HRESULT hr = HTML_Converter.CreateInstance(L"ACAWebThumb.ThumbMaker");
- if (SUCCEEDED(hr))
- {
- HTML_Converter->SetURL(t_strUrl);
- if ( 0 == HTML_Converter->StartSnap() )
- HTML_Converter->SaveImage(t_strFileName);
- }
- if (HTML_Converter)
- HTML_Converter.Release();
- CoUninitialize();
- }
以該組件圖像化yahoo界面的效果圖:
3、最扎實(shí)的方法——自行解析HTML標(biāo)記,并將其圖像化
方法詳解:眾所周知,HTML之所以在瀏覽器中以具體的網(wǎng)頁(yè)格式出現(xiàn),并非服務(wù)器端傳了一整個(gè)應(yīng)用到客戶端,而是源自于瀏覽器對(duì)于客戶端自行解析的結(jié)果。因此,只要我們將對(duì)應(yīng)的解析一一實(shí)現(xiàn),那么將網(wǎng)頁(yè)圖形化,就將不是什么難事。
優(yōu)勢(shì):純Java實(shí)現(xiàn),一勞永逸,一旦開發(fā)完成則永遠(yuǎn)通用,而且有一定的商用價(jià)值。
劣勢(shì):開發(fā)費(fèi)時(shí),且需要針對(duì)不同語(yǔ)法做精確分析,才能保證輸出的基本正確。尤其在涉及到JavaScript解析時(shí),難度將尤其增大。
實(shí)現(xiàn)方法:目前尚無(wú)具體案例可供參考。但是,由于Java有jdic之類的瀏覽器項(xiàng)目存在(https://jdic.dev.java.net/ ),而Java圖形界面又屬繪制生成。從理論上說(shuō),我們可以將所有具備Graphics的組件圖形化保存。
而如果自行解析,那么您需要建立HTML解析器(或使用第三方的,萬(wàn)幸Java在這方面的組件很多),了解Java2D機(jī)制,了解何時(shí)該使用drawString繪制文字,何時(shí)又該使用drawImage插入圖片等等。
補(bǔ)充:
這是一個(gè)利用內(nèi)置瀏覽器截圖的示例,使用了DJNativeSwing組件。
示例工程下載地址(Eclipse工程,含lib):http://greenvm.googlecode.com/files/Screenshot.7z
- import java.awt.BorderLayout;
- import java.awt.Dimension;
- import java.awt.FlowLayout;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import javax.imageio.ImageIO;
- import javax.swing.JFrame;
- import javax.swing.JPanel;
- import javax.swing.SwingUtilities;
- import chrriis.dj.nativeswing.swtimpl.NativeComponent;
- import chrriis.dj.nativeswing.swtimpl.NativeInterface;
- import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
- import chrriis.dj.nativeswing.swtimpl.components.WebBrowserAdapter;
- import chrriis.dj.nativeswing.swtimpl.components.WebBrowserEvent;
- public class Main extends JPanel {
-
-
-
- private static final long serialVersionUID = 1L;
-
- final static public String LS = System.getProperty("line.separator", "/n");
-
- final static public String FS = System.getProperty("file.separator", "http://");
-
- final static StringBuffer jsDimension;
-
- static {
- jsDimension = new StringBuffer();
- jsDimension.append("var width = 0;").append(LS);
- jsDimension.append("var height = 0;").append(LS);
- jsDimension.append("if(document.documentElement) {").append(LS);
- jsDimension.append(
- " width = Math.max(width, document.documentElement.scrollWidth);")
- .append(LS);
- jsDimension.append(
- " height = Math.max(height, document.documentElement.scrollHeight);")
- .append(LS);
- jsDimension.append("}").append(LS);
- jsDimension.append("if(self.innerWidth) {").append(LS);
- jsDimension.append(" width = Math.max(width, self.innerWidth);")
- .append(LS);
- jsDimension.append(" height = Math.max(height, self.innerHeight);")
- .append(LS);
- jsDimension.append("}").append(LS);
- jsDimension.append("if(document.body.scrollWidth) {").append(LS);
- jsDimension.append(
- " width = Math.max(width, document.body.scrollWidth);")
- .append(LS);
- jsDimension.append(
- " height = Math.max(height, document.body.scrollHeight);")
- .append(LS);
- jsDimension.append("}").append(LS);
- jsDimension.append("return width + ':' + height;");
- }
-
- public Main(final String url, final int maxWidth, final int maxHeight) {
- super(new BorderLayout());
- JPanel webBrowserPanel = new JPanel(new BorderLayout());
- final String fileName = System.currentTimeMillis() + ".jpg";
- final JWebBrowser webBrowser = new JWebBrowser(null);
- webBrowser.setBarsVisible(false);
- webBrowser.navigate(url);
- webBrowserPanel.add(webBrowser, BorderLayout.CENTER);
- add(webBrowserPanel, BorderLayout.CENTER);
- JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 4, 4));
- webBrowser.addWebBrowserListener(new WebBrowserAdapter() {
-
- public void loadingProgressChanged(WebBrowserEvent e) {
-
- if (e.getWebBrowser().getLoadingProgress() == 100) {
- String result = (String) webBrowser
- .executeJavascriptWithResult(jsDimension.toString());
- int index = result == null ? -1 : result.indexOf(":");
- NativeComponent nativeComponent = webBrowser
- .getNativeComponent();
- Dimension originalSize = nativeComponent.getSize();
- Dimension imageSize = new Dimension(Integer.parseInt(result
- .substring(0, index)), Integer.parseInt(result
- .substring(index + 1)));
- imageSize.width = Math.max(originalSize.width,
- imageSize.width + 50);
- imageSize.height = Math.max(originalSize.height,
- imageSize.height + 50);
- nativeComponent.setSize(imageSize);
- BufferedImage image = new BufferedImage(imageSize.width,
- imageSize.height, BufferedImage.TYPE_INT_RGB);
- nativeComponent.paintComponent(image);
- nativeComponent.setSize(originalSize);
-
- if (imageSize.width > maxWidth
- || imageSize.height > maxHeight) {
-
- image = image.getSubimage(0, 0, maxWidth, maxHeight);
-
-
-
-
-
-
-
-
-
-
- }
- try {
-
- ImageIO.write(image, "jpg", new File(fileName));
- } catch (IOException ex) {
- ex.printStackTrace();
- }
-
- System.exit(0);
- }
- }
- }
- );
- add(panel, BorderLayout.SOUTH);
- }
- public static void main(String[] args) {
- NativeInterface.open();
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
-
- JFrame frame = new JFrame("以DJ組件保存指定網(wǎng)頁(yè)截圖");
-
- frame.getContentPane().add(
- new Main("http://blog.csdn.net/cping1982", 640, 480),
- BorderLayout.CENTER);
- frame.setSize(800, 600);
-
- frame.invalidate();
- frame.pack();
- frame.setVisible(false);
- }
- });
- NativeInterface.runEventPump();
- }
- }
posted @
2015-01-21 12:00 ForMeBlog 閱讀(436) |
評(píng)論 (0) |
編輯 收藏

2015年1月4日
public HttpServletResponse download(String path, HttpServletResponse response) {
try {
// path是指欲下載的文件的路徑。
File file = new File(path);
// 取得文件名。
String filename = file.getName();
// 取得文件的后綴名。
String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
// 以流的形式下載文件。
InputStream fis = new BufferedInputStream(new FileInputStream(path));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 設(shè)置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
response.addHeader("Content-Length", "" + file.length());
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return response;
}
public void downloadLocal(HttpServletResponse response) throws FileNotFoundException {
// 下載本地文件
String fileName = "Operator.doc".toString(); // 文件的默認(rèn)保存名
// 讀到流中
InputStream inStream = new FileInputStream("c:/Operator.doc");// 文件的存放路徑
// 設(shè)置輸出的格式
response.reset();
response.setContentType("bin");
response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
// 循環(huán)取出流中的數(shù)據(jù)
byte[] b = new byte[100];
int len;
try {
while ((len = inStream.read(b)) > 0)
response.getOutputStream().write(b, 0, len);
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void downloadNet(HttpServletResponse response) throws MalformedURLException {
// 下載網(wǎng)絡(luò)文件
int bytesum = 0;
int byteread = 0;
URL url = new URL("windine.blogdriver.com/logo.gif");
try {
URLConnection conn = url.openConnection();
InputStream inStream = conn.getInputStream();
FileOutputStream fs = new FileOutputStream("c:/abc.gif");
byte[] buffer = new byte[1204];
int length;
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread;
System.out.println(bytesum);
fs.write(buffer, 0, byteread);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
posted @
2015-01-04 16:32 ForMeBlog 閱讀(190) |
評(píng)論 (0) |
編輯 收藏

2014年7月29日
原始的message.xml
<?xml version="1.0" encoding="UTF-8"?><users>
<Messages>
<sendName>sendUsers</sendName>
<receiveName>snake</receiveName>
<date>2007-12-04 12:20:00</date>
<status>1</status>
<message>this is Content</message>
</Messages>
</users>
java程序
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class UpdateXml {
public static boolean doc2XmlFile(Document document, String filename) {
boolean flag = true;
try {
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
// transformer.setOutputProperty(OutputKeys.ENCODING, "GB2312");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File(filename));
transformer.transform(source, result);
} catch (Exception ex) {
flag = false;
ex.printStackTrace();
}
return flag;
}
public static Document load(String filename) {
Document document = null;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(new File(filename));
document.normalize();
} catch (Exception ex) {
ex.printStackTrace();
}
return document;
}
public static void xmlUpdateDemo() {
Document document = load("message.xml");
Node root = document.getDocumentElement();
if (root.hasChildNodes()) {
NodeList ftpnodes = root.getChildNodes();
for (int i = 0; i < ftpnodes.getLength(); i++) {
NodeList ftplist = ftpnodes.item(i).getChildNodes();
for (int k = 0; k < ftplist.getLength(); k++) {
Node subnode = ftplist.item(k);
// if (subnode.getNodeType()==Node.ELEMENT_NODE&&subnode.
// getNodeName()=="ftp-chn")
// {
// ftpnodes.item(i).removeChild(subnode);
// }
if (subnode.getNodeType() == Node.ELEMENT_NODE
&& subnode.getNodeName() == "status") {
subnode.getFirstChild().setNodeValue("9");
}
}
}
}
doc2XmlFile(document, "message.xml");
}
public static void main(String args[]) throws Exception {
UpdateXml.xmlUpdateDemo();
}
}
修改后的message.xml
<?xml version="1.0" encoding="UTF-8"?><users>
<Messages>
<sendName>sendUsers</sendName>
<receiveName>snake</receiveName>
<date>2007-12-04 12:20:00</date>
<status>9</status>
<message>this is Content</message>
</Messages>
</users>
posted @
2014-07-29 17:05 ForMeBlog 閱讀(533) |
評(píng)論 (0) |
編輯 收藏
摘要: 一、概述
ant 是一個(gè)將軟件編譯、測(cè)試、部署等步驟聯(lián)系在一起加以自動(dòng)化的一個(gè)工具,大多用于Java環(huán)境中的軟件開發(fā)。在實(shí)際軟件開發(fā)中,有很多地方可以用到ant。
開發(fā)環(huán)境:
System:Windows
JDK:1.6+
IDE:eclipse
ant:1.9.1
Email:hoojo_@126.com
Blog:http://blog....
閱讀全文
posted @
2014-07-29 17:01 ForMeBlog 閱讀(279) |
評(píng)論 (0) |
編輯 收藏
摘要: Ant是一個(gè)Apache基金會(huì)下的跨平臺(tái)的構(gòu)件工具,它可以實(shí)現(xiàn)項(xiàng)目的自動(dòng)構(gòu)建和部署等功能。在本文中,主要讓讀者熟悉怎樣將Ant應(yīng)用到Java項(xiàng)目中,讓它簡(jiǎn)化構(gòu)建和部署操作。 一. 安裝與配置
下載地址:http://ant.apache.org...
閱讀全文
posted @
2014-07-29 16:49 ForMeBlog 閱讀(3223) |
評(píng)論 (0) |
編輯 收藏