隨筆-23  評論-0  文章-5  trackbacks-0
            2015年1月4日

          關(guān)于HTTP請求超時字段定義

          一、ConnectionRequestTimeout 超時
          HttpClient 使用連接池來管理連接,這個時間是從連接池獲取連接的超時時間,可以聯(lián)想從數(shù)據(jù)庫連接池獲取數(shù)據(jù)庫連接。

          二、ConnectTimeout 超時
          建立連接超時,客戶端和服務(wù)器間建立連接進行的三次握手完成的時間

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

          今天遇到調(diào)用encodeURL調(diào)用二次的疑問,雖然之前知道要調(diào)用二次,但是具體不是太清楚里面具體的運行過程,這是轉(zhuǎn)載的這個寫的比較詳細,把整個運行過程詳細解讀了一下,非常不錯所以轉(zhuǎn)載過了供其他人分享。
          .encodeURL函數(shù)主要是來對URI來做轉(zhuǎn)碼,它默認是采用的UTF-8的編碼.

          . UTF-8編碼的格式:一個漢字來三個字節(jié)構(gòu)成,每一個字節(jié)會轉(zhuǎn)換成16進制的編碼,同時添加上%號.

          假設(shè)頁面端輸入的中文是一個“中”,按照下面步驟進行解碼

          1.第一次encodeURI,按照utf-8方式獲取字節(jié)數(shù)組變成[-28,-72-83],對字節(jié)碼數(shù)組進行遍歷,把每個字節(jié)轉(zhuǎn)化成對應(yīng)的16進制數(shù),這樣就變成了[E4,B8,AD],最后變成[%E4,%B8,%AD]  此時已經(jīng)沒有了多字節(jié)字符,全部是單字節(jié)字符。

          2、第二次encodeURI,進行編碼,會把%看成一個轉(zhuǎn)義字符,并不編碼%以后字符,會把%編碼成%25.把數(shù)組最后變成[%25E4,%25B8,%25AD]然后就把處理后的數(shù)據(jù)[%25E4,%25B8,%25AD]發(fā)往服務(wù)器端,
          當應(yīng)用服務(wù)器調(diào)用getParameter方法,getParameter方法會去向應(yīng)用服務(wù)器請求參數(shù)
          應(yīng)用服務(wù)器最初獲得的就是發(fā)送來的
          [%25E4,%25B8,%25AD],應(yīng)用服務(wù)器會對這個數(shù)據(jù)進行URLdecode操作,應(yīng)用服務(wù)器進行解碼的這一次,不管是按照UTF-8,還是GBK,還是ISO-8859,,都能得到[%E4,%B8,%AD],因為都會把%25解析成%.并把這個值返回給getParameter方法

          3\、再用UTF-8解碼一次,就得到"中"了。

          想想看,如果不編碼兩次,當服務(wù)器自動解碼的時候,假如是按照ISO-8859去解碼UTF-8編碼的東西,就是會出現(xiàn)亂碼。

          JS:

          1. document.authorityForm.action = basePath3+"User_viewUser.do?id="+id+"&roleName="+encodeURI(encodeURI(roleName))+"&roleType="+roleType;  


          JAVA后臺:
             

          1. roleName = java.net.URLDecoder.decode(getRequest().getParameter("roleName"),"UTF-8");  
          posted @ 2015-08-18 11:20 ForMeBlog 閱讀(425) | 評論 (0)編輯 收藏

           

          、概念

           

           

             AnnontationJava5開始引入的新特征。中文名稱一般叫注解。它提供了一種安全的類似注釋的機制,用來將任何的信息或元數(shù)據(jù)(metadata)與程序元素(類、方法、成員變量等)進行關(guān)聯(lián)。

           

            更通俗的意思是為程序的元素(類、方法、成員變量)加上更直觀更明了的說明,這些說明信息是與程序的業(yè)務(wù)邏輯無關(guān),并且是供指定的工具或框架使用的。

           

          Annontation像一種修飾符一樣,應(yīng)用于包、類型、構(gòu)造方法、方法、成員變量、參數(shù)及本地變量的聲明語句中。

           

          、原理

           

            Annotation其實是一種接口。通過Java的反射機制相關(guān)的API來訪問annotation信息。相關(guān)類(框架或工具中的類)根據(jù)這些信息來決定如何使用該程序元素或改變它們的行為。

           

            annotation是不會影響程序代碼的執(zhí)行,無論annotation怎么變化,代碼都始終如一地執(zhí)行。

           

            Java語言解釋器在工作時會忽略這些annotation,因此在JVM 中這些annotation是“不起作用”的,只能通過配套的工具才能對這些annontaion類型的信息進行訪問和處理。

           

            Annotationinterface的異同

           

              1)、Annotation類型使用關(guān)鍵字@interface而不是interface

           

            這個關(guān)鍵字聲明隱含了一個信息:它是繼承了java.lang.annotation.Annotation接口,并非聲明了一個interface

           

              2)、Annotation類型、方法定義是獨特的、受限制的。

           

            Annotation 類型的方法必須聲明為無參數(shù)、無異常拋出的。這些方法定義了annotation的成員:方法名成為了成員名,而方法返回值成為了成員的類型。而方法返回值類型必須為primitive類型、Class類型、枚舉類型、annotation類型或者由前面類型之一作為元素的一維數(shù)組。方法的后面可以使用 default和一個默認數(shù)值來聲明成員的默認值,null不能作為成員默認值,這與我們在非annotation類型中定義方法有很大不同。

           

            Annotation類型和它的方法不能使用annotation類型的參數(shù)、成員不能是generic。只有返回值類型是Class的方法可以在annotation類型中使用generic,因為此方法能夠用類轉(zhuǎn)換將各種類型轉(zhuǎn)換為Class

           

              3)、Annotation類型又與接口有著近似之處。

           

            它們可以定義常量、靜態(tài)成員類型(比如枚舉類型定義)。Annotation類型也可以如接口一般被實現(xiàn)或者繼承。

           

           

          、應(yīng)用場合

           

            annotation一般作為一種輔助途徑,應(yīng)用在軟件框架或工具中,在這些工具類中根據(jù)不同的 annontation注解信息采取不同的處理過程或改變相應(yīng)程序元素(類、方法及成員變量等)的行為。

           

            例如:JunitStrutsSpring等流行工具框架中均廣泛使用了annontion。使代碼的靈活性大提高。

           

           

           四、常見標準的Annotation

           

            從java5版本開始,自帶了三種標準annontation類型,

           

              (1)、Override

           

            java.lang.Override 是一個marker annotation類型,它被用作標注方法。它說明了被標注的方法重載了父類的方法,起到了斷言的作用。如果我們使用了這種annotation在一個沒有覆蓋父類方法的方法時,java編譯器將以一個編譯錯誤來警示。

           

            這個annotaton常常在我們試圖覆蓋父類方法而確又寫錯了方法名時加一個保障性的校驗過程。

           

              (2)、Deprecated

           

            Deprecated也是一種marker annotation。當一個類型或者類型成員使用@Deprecated修飾的話,編譯器將不鼓勵使用這個被標注的程序元素。所以使用這種修飾具有一定的 “延續(xù)性”:如果我們在代碼中通過繼承或者覆蓋的方式使用了這個過時的類型或者成員,雖然繼承或者覆蓋后的類型或者成員并不是被聲明為 @Deprecated,但編譯器仍然要報警。

           

            注意:@Deprecated這個annotation類型和javadoc中的 @deprecated這個tag是有區(qū)別的:前者是java編譯器識別的,而后者是被javadoc工具所識別用來生成文檔(包含程序成員為什么已經(jīng)過時、它應(yīng)當如何被禁止或者替代的描述)。

           

              (3)、SuppressWarnings

           

            此注解能告訴Java編譯器關(guān)閉對類、方法及成員變量的警告。

           

            有時編譯時會提出一些警告,對于這些警告有的隱藏著Bug,有的是無法避免的,對于某些不想看到的警告信息,可以通過這個注解來屏蔽。

           

            SuppressWarning不是一個marker annotation。它有一個類型為String[]的成員,這個成員的值為被禁止的警告名。對于javac編譯器來講,被-Xlint選項有效的警告名也同樣對@SuppressWarings有效,同時編譯器忽略掉無法識別的警告名。

           

            annotation語法允許在annotation名后跟括號,括號中是使用逗號分割的name=value對用于為annotation的成員賦值:

           

          代碼:

           

          @SuppressWarnings(value={"unchecked","fallthrough"})

          public void lintTrap() { /* sloppy method body omitted */ }

           

           

           

          在這個例子中SuppressWarnings annotation類型只定義了一個單一的成員,所以只有一個簡單的value={...}作為name=value對。又由于成員值是一個數(shù)組,故使用大括號來聲明數(shù)組值。

           

           

          注意:我們可以在下面的情況中縮寫annotation:當annotation只有單一成員,并成員命名為"value="。這時可以省去"value="。比如將上面的SuppressWarnings annotation進行縮寫:

           

          代碼:

           

          @SuppressWarnings({"unchecked","fallthrough"})

           

           

           

           

          如果SuppressWarnings所聲明的被禁止警告?zhèn)€數(shù)為一個時,可以省去大括號:

           

           

           

          @SuppressWarnings("unchecked")

           

           

           

          、自定義annontation示例

           

            示例共涉及四個類:

            清單1:Author.java

          復(fù)制代碼
          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();
          }
          復(fù)制代碼

            清單2:Description.java

          復(fù)制代碼
          /**
          *
          */
          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();
          }
          復(fù)制代碼

          清單3:Utility.java

          復(fù)制代碼
          package com.magc.annotation;

          @Description(value
          = "這是一個有用的工具類")
          public class Utility {

          @Author(name
          = "haoran_202",group="com.magc")
          public String work()
          {
          return "work over!";
          }



          }
          復(fù)制代碼

          注:這是個普通的Java類,運行了@Description和@Author注解。

          清單3:AnalysisAnnotation.java

          復(fù)制代碼
          package com.magc.annotation;

          import java.lang.reflect.Method;

          public class AnalysisAnnotation {
          /**
          * 在運行時分析處理annotation類型的信息
          *
          *
          */
          public static void main(String[] args) {
          try {
          //通過運行時反射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();
          }
          }

          }
          復(fù)制代碼

          注:這是個與自定義@Description和@Author配套的基礎(chǔ)框架或工具類,通過此類來獲得與普通Java類Utility.java關(guān)聯(lián)的信息,即描述和作者。

          運行AnalysisAnnotation,輸出結(jié)果為:

          Utility's Description--->這是一個有用的工具類
          Utility's Author--->haoran_202 from com.magc

          posted @ 2015-06-11 18:06 ForMeBlog 閱讀(260) | 評論 (0)編輯 收藏
          在ORACLE 數(shù)據(jù)庫中有一種方法可以實現(xiàn)級聯(lián)查詢
          select *                //要查詢的字段
          from table              //具有子接點ID與父接點ID的表 
          start with selfid=id      //給定一個startid(字段名為子接點ID,及開始的ID號)
          connect by prior selfid=parentid       //聯(lián)接條件為子接點等于父接點,不能反

          這個SQL主要用于菜單的級聯(lián)查詢,給一個父接點可以查出所有的子接點。及子接點的子接點,一查到底,很實用。不過呢這個程序只能在oracle里面用,我目前還不知道在其它數(shù)據(jù)庫里是怎么調(diào)用的。等我找到了,再貼出來與大家分享。
          這個程序,估計好多人看不明白,其實放了這么久我也一時沒看明白,重新測了一下,補充說明一下,不然我下次又看不懂了。
          以一個windows系統(tǒng)的菜單為例。我那一個這樣的表menu。
          說明:
          mid:菜單的ID號
          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  

           

          如果我想知道在“文件”菜單下有那些子菜單的話。我就可以這樣用這個SQL程序:
          select * from menu
          start with mid=1     
          connect by prior mid=mpid;
          這樣就可以把 “文件”里的子菜單全部列出來了。當然實際應(yīng)用不會這么簡單,如附加其實條件,尤其是權(quán)限管理,這時根據(jù)你的系統(tǒng)要求,是對個個驗證,還是對角色驗證,把這些人的ID放在validate這個字段里,組成一個字符串,N個ID用逗號隔開,(注意,在往數(shù)據(jù)庫保存時要注意對字符串處理一下,截取掉最后一個逗號這樣可以節(jié)省很多麻煩)
          select * from menu
          where validate in(……)
          and mid in(
             select mid from menu  //這里不能用*號了。
             start with mid=1     
             connect by prior mid=mpid;
          )
          最后再補充一點關(guān)于隨機查詢的代碼
          select * from user order by sys_guid()
          posted @ 2015-03-12 12:04 ForMeBlog 閱讀(1483) | 評論 (0)編輯 收藏

          今天看到某網(wǎng)友關(guān)于“如何以Java實現(xiàn)網(wǎng)頁截圖技術(shù)”的咨詢帖,由于出現(xiàn)該咨詢的地點非常不適合較長回復(fù),故以博文形式回答。

           

          事實上,如果您想以Java實現(xiàn)網(wǎng)頁截圖,也就是“輸入一段網(wǎng)址,幾秒鐘過后就能截取一張網(wǎng)頁縮略圖”的效果。那么,您至少有3種方式可以選擇。

           

          1、最直接的方式——使用Robot

           

          方法詳解:該方法利用Robat提供的強大桌面操作能力,硬性調(diào)用瀏覽器打開指定網(wǎng)頁,并將網(wǎng)頁信息保存到本地。

           

          優(yōu)勢:簡單易用,不需要任何第三方插件。

           

          缺點:不能同時處理大量數(shù)據(jù),技術(shù)含量過低,屬于應(yīng)急型技巧。

           

          實現(xiàn)方法:使用如下代碼即可


           

           

          1. public static void main(String[] args) throws MalformedURLException,  
          2.         IOException, URISyntaxException, AWTException {  
          3.     //此方法僅適用于JdK1.6及以上版本   
          4.     Desktop.getDesktop().browse(  
          5.             new URL("http://google.com/intl/en/").toURI());  
          6.     Robot robot = new Robot();  
          7.     robot.delay(10000);  
          8.     Dimension d = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());  
          9.     int width = (int) d.getWidth();  
          10.     int height = (int) d.getHeight();  
          11.     //最大化瀏覽器   
          12.     robot.keyRelease(KeyEvent.VK_F11);  
          13.     robot.delay(2000);  
          14.     Image image = robot.createScreenCapture(new Rectangle(00, width,  
          15.             height));  
          16.     BufferedImage bi = new BufferedImage(width, height,  
          17.             BufferedImage.TYPE_INT_RGB);  
          18.     Graphics g = bi.createGraphics();  
          19.     g.drawImage(image, 00, width, height, null);  
          20.     //保存圖片   
          21.     ImageIO.write(bi, "jpg"new File("google.jpg"));  
          22. }  

           

           

          2、最常規(guī)的方式——利用JNI,調(diào)用第三方C/C++組件

          方法詳解:目前來講,Java領(lǐng)域?qū)τ诰W(wǎng)頁截圖組件的開發(fā)明顯不足(商機?),當您需要完成此種操作時,算得上碰到了Java的軟肋。但是,眾所周知Java也擁有強大的JNI能力,可以輕易將C/C++開發(fā)的同類組件引為己用。

          優(yōu)勢:實現(xiàn)簡單,只需要封裝對應(yīng)的DLL文件,就可以讓Java實現(xiàn)同類功能。

           

          劣勢:同其他JNI實現(xiàn)一樣,在跨平臺時存在隱患,而且您的程序?qū)⒉辉賹儆诩僇ava應(yīng)用。

           

          實現(xiàn)方法:可參見此用例,具體封裝何種C/C++組件請自行選擇。

           

          PS:示例來源于ACA HTML to Image Converter項目(http://www.acasystems.com/en/web-thumb-activex/faq-convert-html-to-image-in-java.htm ),這是一個收費的HTML轉(zhuǎn)Image第三方組件,但封裝方式在Java中大同小異。

           

          引用JNI封裝:

           

           

           

          1. import sun.awt.*;  
          2. import java.awt.*;  
          3. import javax.swing.*;  
          4. import java.awt.event.*;  
          5. import java.awt.*;  
          6. import java.awt.peer.*;  
          7. public class Snap  
          8. {  
          9.   static  
          10.   {  
          11.     System.loadLibrary("Snap");  
          12.   }  
          13.   public static void main( String[] argv )  
          14.   {  
          15.     Snap t_xSnap = new Snap();  
          16.     t_xSnap.Start("http://www.google.com""snapshot-google.png");  
          17.   }  
          18.   public native void Start(String pi_strURL, String pi_strImageName);  
          19. }  

           

           

          CPP部分的實現(xiàn):

           

           

           

          1. #include <windows.h>  
          2. #include <atlbase.h>  
          3. #include "snap.h"  
          4. #pragma comment(lib,"atl.lib")  
          5. #import "./../../acawebthumb.dll" no_namespace  
          6. JNIEXPORT void JNICALL Java_Snap_Start(JNIEnv *pEnv, jobject, jstring pi_strUrl, jstring pi_strFileName)  
          7. {  
          8.   CoInitialize(0);  
          9.   _bstr_t t_strUrl = pEnv->GetStringUTFChars(pi_strUrl, 0);  
          10.   _bstr_t t_strFileName = pEnv->GetStringUTFChars(pi_strFileName, 0);      
          11.   IThumbMakerPtr HTML_Converter = NULL;  
          12.   HRESULT hr = HTML_Converter.CreateInstance(L"ACAWebThumb.ThumbMaker");      
          13.   if (SUCCEEDED(hr))  
          14.   {   
          15.     HTML_Converter->SetURL(t_strUrl);  
          16.     if ( 0 == HTML_Converter->StartSnap() )  
          17.       HTML_Converter->SaveImage(t_strFileName);  
          18.   }  
          19.   if (HTML_Converter)  
          20.     HTML_Converter.Release();  
          21.   CoUninitialize();           
          22. }  

           

           

          以該組件圖像化yahoo界面的效果圖:

           

          00


          3、最扎實的方法——自行解析HTML標記,并將其圖像化

           

          方法詳解:眾所周知,HTML之所以在瀏覽器中以具體的網(wǎng)頁格式出現(xiàn),并非服務(wù)器端傳了一整個應(yīng)用到客戶端,而是源自于瀏覽器對于客戶端自行解析的結(jié)果。因此,只要我們將對應(yīng)的解析一一實現(xiàn),那么將網(wǎng)頁圖形化,就將不是什么難事。


          優(yōu)勢:純Java實現(xiàn),一勞永逸,一旦開發(fā)完成則永遠通用,而且有一定的商用價值。

           

          劣勢:開發(fā)費時,且需要針對不同語法做精確分析,才能保證輸出的基本正確。尤其在涉及到JavaScript解析時,難度將尤其增大。

           

          實現(xiàn)方法:目前尚無具體案例可供參考。但是,由于Java有jdic之類的瀏覽器項目存在(https://jdic.dev.java.net/ ),而Java圖形界面又屬繪制生成。從理論上說,我們可以將所有具備Graphics的組件圖形化保存。

           

          而如果自行解析,那么您需要建立HTML解析器(或使用第三方的,萬幸Java在這方面的組件很多),了解Java2D機制,了解何時該使用drawString繪制文字,何時又該使用drawImage插入圖片等等。

           


          補充:

           

          這是一個利用內(nèi)置瀏覽器截圖的示例,使用了DJNativeSwing組件。

           

          示例工程下載地址(Eclipse工程,含lib):http://greenvm.googlecode.com/files/Screenshot.7z

           

           

           

           

          1. import java.awt.BorderLayout;  
          2. import java.awt.Dimension;  
          3. import java.awt.FlowLayout;  
          4. import java.awt.image.BufferedImage;  
          5. import java.io.File;  
          6. import java.io.IOException;  
          7. import javax.imageio.ImageIO;  
          8. import javax.swing.JFrame;  
          9. import javax.swing.JPanel;  
          10. import javax.swing.SwingUtilities;  
          11. import chrriis.dj.nativeswing.swtimpl.NativeComponent;  
          12. import chrriis.dj.nativeswing.swtimpl.NativeInterface;  
          13. import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;  
          14. import chrriis.dj.nativeswing.swtimpl.components.WebBrowserAdapter;  
          15. import chrriis.dj.nativeswing.swtimpl.components.WebBrowserEvent;  
          16. public class Main extends JPanel {  
          17.     /** 
          18.      *  
          19.      */  
          20.     private static final long serialVersionUID = 1L;  
          21.     // 行分隔符   
          22.     final static public String LS = System.getProperty("line.separator""/n");  
          23.     // 文件分割符   
          24.     final static public String FS = System.getProperty("file.separator""http://");  
          25.     //以javascript腳本獲得網(wǎng)頁全屏后大小   
          26.     final static StringBuffer jsDimension;  
          27.       
          28.     static {  
          29.         jsDimension = new StringBuffer();  
          30.         jsDimension.append("var width = 0;").append(LS);  
          31.         jsDimension.append("var height = 0;").append(LS);  
          32.         jsDimension.append("if(document.documentElement) {").append(LS);  
          33.         jsDimension.append(  
          34.                         "  width = Math.max(width, document.documentElement.scrollWidth);")  
          35.                 .append(LS);  
          36.         jsDimension.append(  
          37.                         "  height = Math.max(height, document.documentElement.scrollHeight);")  
          38.                 .append(LS);  
          39.         jsDimension.append("}").append(LS);  
          40.         jsDimension.append("if(self.innerWidth) {").append(LS);  
          41.         jsDimension.append("  width = Math.max(width, self.innerWidth);")  
          42.                 .append(LS);  
          43.         jsDimension.append("  height = Math.max(height, self.innerHeight);")  
          44.                 .append(LS);  
          45.         jsDimension.append("}").append(LS);  
          46.         jsDimension.append("if(document.body.scrollWidth) {").append(LS);  
          47.         jsDimension.append(  
          48.                 "  width = Math.max(width, document.body.scrollWidth);")  
          49.                 .append(LS);  
          50.         jsDimension.append(  
          51.                 "  height = Math.max(height, document.body.scrollHeight);")  
          52.                 .append(LS);  
          53.         jsDimension.append("}").append(LS);  
          54.         jsDimension.append("return width + ':' + height;");  
          55.     }  
          56.   //DJNativeSwing組件請于http://djproject.sourceforge.net/main/index.html下載   
          57.     public Main(final String url, final int maxWidth, final int maxHeight) {  
          58.         super(new BorderLayout());  
          59.         JPanel webBrowserPanel = new JPanel(new BorderLayout());  
          60.         final String fileName = System.currentTimeMillis() + ".jpg";  
          61.         final JWebBrowser webBrowser = new JWebBrowser(null);  
          62.         webBrowser.setBarsVisible(false);  
          63.         webBrowser.navigate(url);  
          64.         webBrowserPanel.add(webBrowser, BorderLayout.CENTER);  
          65.         add(webBrowserPanel, BorderLayout.CENTER);  
          66.         JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 44));  
          67.         webBrowser.addWebBrowserListener(new WebBrowserAdapter() {  
          68.             // 監(jiān)聽加載進度   
          69.             public void loadingProgressChanged(WebBrowserEvent e) {  
          70.                 // 當加載完畢時   
          71.                 if (e.getWebBrowser().getLoadingProgress() == 100) {  
          72.                     String result = (String) webBrowser  
          73.                             .executeJavascriptWithResult(jsDimension.toString());  
          74.                     int index = result == null ? -1 : result.indexOf(":");  
          75.                     NativeComponent nativeComponent = webBrowser  
          76.                             .getNativeComponent();  
          77.                     Dimension originalSize = nativeComponent.getSize();  
          78.                     Dimension imageSize = new Dimension(Integer.parseInt(result  
          79.                             .substring(0, index)), Integer.parseInt(result  
          80.                             .substring(index + 1)));  
          81.                     imageSize.width = Math.max(originalSize.width,  
          82.                             imageSize.width + 50);  
          83.                     imageSize.height = Math.max(originalSize.height,  
          84.                             imageSize.height + 50);  
          85.                     nativeComponent.setSize(imageSize);  
          86.                     BufferedImage image = new BufferedImage(imageSize.width,  
          87.                             imageSize.height, BufferedImage.TYPE_INT_RGB);  
          88.                     nativeComponent.paintComponent(image);  
          89.                     nativeComponent.setSize(originalSize);  
          90.                     // 當網(wǎng)頁超出目標大小時   
          91.                     if (imageSize.width > maxWidth  
          92.                             || imageSize.height > maxHeight) {  
          93.                         //截圖部分圖形   
          94.                         image = image.getSubimage(00, maxWidth, maxHeight);  
          95.                         /*此部分為使用縮略圖 
          96.                         int width = image.getWidth(), height = image 
          97.                             .getHeight(); 
          98.                          AffineTransform tx = new AffineTransform(); 
          99.                         tx.scale((double) maxWidth / width, (double) maxHeight 
          100.                                 / height); 
          101.                         AffineTransformOp op = new AffineTransformOp(tx, 
          102.                                 AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 
          103.                         //縮小 
          104.                         image = op.filter(image, null);*/  
          105.                     }  
          106.                     try {  
          107.                         // 輸出圖像   
          108.                         ImageIO.write(image, "jpg"new File(fileName));  
          109.                     } catch (IOException ex) {  
          110.                         ex.printStackTrace();  
          111.                     }  
          112.                     // 退出操作   
          113.                     System.exit(0);  
          114.                 }  
          115.             }  
          116.         }  
          117.         );  
          118.         add(panel, BorderLayout.SOUTH);  
          119.     }  
          120.     public static void main(String[] args) {  
          121.         NativeInterface.open();  
          122.         SwingUtilities.invokeLater(new Runnable() {  
          123.             public void run() {  
          124.                 // SWT組件轉(zhuǎn)Swing組件,不初始化父窗體將無法啟動webBrowser   
          125.                 JFrame frame = new JFrame("以DJ組件保存指定網(wǎng)頁截圖");  
          126.                 // 加載指定頁面,最大保存為640x480的截圖   
          127.                 frame.getContentPane().add(  
          128.                         new Main("http://blog.csdn.net/cping1982"640480),  
          129.                         BorderLayout.CENTER);  
          130.                 frame.setSize(800600);  
          131.                 // 僅初始化,但不顯示   
          132.                 frame.invalidate();  
          133.                 frame.pack();  
          134.                 frame.setVisible(false);  
          135.             }  
          136.         });  
          137.         NativeInterface.runEventPump();  
          138.     }  
          139. }  

           

           

           

          posted @ 2015-01-21 12:00 ForMeBlog 閱讀(438) | 評論 (0)編輯 收藏
          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(); // 文件的默認保存名
                  
          // 讀到流中
                  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();
                  }
              }
          //支持在線打開文件的一種
          public void downLoad(String filePath, HttpServletResponse response, boolean isOnLine) throws Exception {
                  File f 
          = new File(filePath);
                  
          if (!f.exists()) {
                      response.sendError(
          404"File not found!");
                      
          return;
                  }

                  BufferedInputStream br 
          = new BufferedInputStream(new FileInputStream(f));
                  
          byte[] buf = new byte[1024];
                  
          int len = 0;

                  response.reset(); 
          // 非常重要
                  if (isOnLine) // 在線打開方式
                      URL u = new URL("file:///" + filePath);
                      response.setContentType(u.openConnection().getContentType());
                      response.setHeader(
          "Content-Disposition""inline; filename=" + f.getName());
                      
          // 文件名應(yīng)該編碼成UTF-8
                  }
           else // 純下載方式
                      response.setContentType("application/x-msdownload");
                      response.setHeader(
          "Content-Disposition""attachment; filename=" + f.getName());
                  }

                  OutputStream out 
          = response.getOutputStream();
                  
          while ((len = br.read(buf)) > 0)
                      out.write(buf, 
          0, len);
                  br.close();
                  out.close();
              }
          方式

          posted @ 2015-01-04 16:32 ForMeBlog 閱讀(193) | 評論 (0)編輯 收藏
          主站蜘蛛池模板: 泾源县| 炉霍县| 尼玛县| 连城县| 保德县| 张家口市| 富川| 西峡县| 平罗县| 琼中| 容城县| 武陟县| 北流市| 中牟县| 岗巴县| 高雄市| 广西| 武胜县| 兖州市| 旬邑县| 罗定市| 汶上县| 凌海市| SHOW| 湘西| 来凤县| 罗定市| 原平市| 南溪县| 卢湾区| 蓬溪县| 车险| 当阳市| 特克斯县| 丰城市| 镇巴县| 香港| 永春县| 湘阴县| 聂荣县| 平昌县|