随笔-23  评论-0  文章-5  trackbacks-0
  2015年1月21日

关于HTTP请求超时字段定义

一、ConnectionRequestTimeout 超时
HttpClient 使用连接池来管理连接,这个时间是从连接池获取连接的超时时间,可以联想从数据库连接池获取数据库连接。

二、ConnectTimeout 超时
建立连接超时,客户端和服务器间建立连接进行的三次握手完成的时间

三、SocketTimeout 超时
数据传输过程中数据包之间间隔的最大时间,Http响应报文可能有多个小报文组成,
如果传输报文的间隔时间超过设置这个时间,会报 java.net.SocketTimeoutException: Read timed out 异常的
posted @ 2018-04-20 14:36 冯威威 阅读(331) | 评论 (0)编辑 收藏
提示:编写Eclipse常用快捷键写成文档,主要是为了自己熟悉一下这些快捷键,方便以后查找和编程中使用!
一、编辑类快捷键
1、Ctrl + 1 快速修复,可以解决很多问题,例如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 + / 内容辅助
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 正向增量查找,按下这个快捷键后,你所输入的每个字母编辑器都提供快速匹配到某个单词,如果没有在状态栏中显示没有找到,退出这个模式按ESC键。
4、Ctrl + Shift + J 反向增量查找
5、Ctrl + Shift + U 列出所有包含字符串的行
6、Ctrl + G 工作区中的声明
7、Ctrl + Shift + G 工作区中的引用
 
五、导航快捷键
1、Ctrl + Shift + T 搜索类
2、Ctrl + Shift + R 搜索工程中的文件
3、Ctrl + E 快速显示当前编辑区的下拉列表
4、F4 打开类型层次结构
5、F3 跳转到声明处
6、Alt + Left 前一个编辑页面
7、Alt + Right 下一个编辑页面
8、Ctrl + PageUp/PageDown在编辑器中,切换已经打开的文件
 
六、调试快捷键
1、F5 单步跳入
2、F6 单步跳过
3、F7 单步还回
4、F8 继续
5、Ctrl + Shift + D 显示变量的值
6、Ctrl + shift + B 在当前行设置或者去掉断点
7、Ctrl + R 运行至行,比较好用可以省好多的断点
 
七、重构快捷键
1、Alt + Shift + R 重命名类名、方法名、属性(变量)名。
2、Alt + Shift + M 把一段函数内的代码抽取成方法,这是重构里面最常用的方法之一,特别是对于一大坨代码很有用。
3、Alt + Shift + C 修改函数结构,比较实用有N个函数调用了这个方法修改一次就行了。
4、Alt + Shift + L 抽取本地变量,可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多出调用的时候。
5、Alt + Shift + F 把Class中的局部变量变为全局变量
6、Alt + Shift + I 合并变量,将创建简化
7、Alt + Shift + Z 撤销重构
 
八、其他快捷键
1、Alt + Enter 显示当前选择资源的属性,在windows下查看文件的属性就是这个快捷键,通常可以用来查看文件在windows中的实际路径。
2、Ctrl + Up文本编辑器向上滚行
3、Ctrl + Down 文本编辑器向下滚行
4、Ctrl + M 最大化当前的Edit或者View,再按则缩小
5、Ctrl + O 快速显示Outline
6、Ctrl + T 快速显示当前类的继承结构,选中接口方法按下这快捷可以跳转到实现类,在项目DAO中经常用。
7、Ctrl + W 关闭当前Editer
8、Ctrl + L 文本编辑器转至行
9、F2 显示工具提示描述,选择类或者变量按下该键会有提示出来
posted @ 2015-11-20 16:36 冯威威 阅读(410) | 评论 (0)编辑 收藏

今天遇到调用encodeURL调用二次的疑问,虽然之前知道要调用二次,但是具体不是太清楚里面具体的运行过程,这是转载的这个写的比较详细,把整个运行过程详细解读了一下,非常不错所以转载过了供其他人分享。
.encodeURL函数主要是来对URI来做转码,它默认是采用的UTF-8的编码.

. UTF-8编码的格式:一个汉字来三个字节构成,每一个字节会转换成16进制的编码,同时添加上%号.

假设页面端输入的中文是一个“中”,按照下面步骤进行解码

1.第一次encodeURI,按照utf-8方式获取字节数组变成[-28,-72-83],对字节码数组进行遍历,把每个字节转化成对应的16进制数,这样就变成了[E4,B8,AD],最后变成[%E4,%B8,%AD]  此时已经没有了多字节字符,全部是单字节字符。

2、第二次encodeURI,进行编码,会把%看成一个转义字符,并不编码%以后字符,会把%编码成%25.把数组最后变成[%25E4,%25B8,%25AD]然后就把处理后的数据[%25E4,%25B8,%25AD]发往服务器端,
当应用服务器调用getParameter方法,getParameter方法会去向应用服务器请求参数
应用服务器最初获得的就是发送来的
[%25E4,%25B8,%25AD],应用服务器会对这个数据进行URLdecode操作,应用服务器进行解码的这一次,不管是按照UTF-8,还是GBK,还是ISO-8859,,都能得到[%E4,%B8,%AD],因为都会把%25解析成%.并把这个值返回给getParameter方法

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

想想看,如果不编码两次,当服务器自动解码的时候,假如是按照ISO-8859去解码UTF-8编码的东西,就是会出现乱码。

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 冯威威 阅读(396) | 评论 (0)编辑 收藏

 

、概念

 

 

   AnnontationJava5开始引入的新特征。中文名称一般叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。

 

  更通俗的意思是为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且是供指定的工具或框架使用的。

 

Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。

 

、原理

 

  Annotation其实是一种接口。通过Java的反射机制相关的API来访问annotation信息。相关类(框架或工具中的类)根据这些信息来决定如何使用该程序元素或改变它们的行为。

 

  annotation是不会影响程序代码的执行,无论annotation怎么变化,代码都始终如一地执行。

 

  Java语言解释器在工作时会忽略这些annotation,因此在JVM 中这些annotation是“不起作用”的,只能通过配套的工具才能对这些annontaion类型的信息进行访问和处理。

 

  Annotationinterface的异同

 

    1)、Annotation类型使用关键字@interface而不是interface

 

  这个关键字声明隐含了一个信息:它是继承了java.lang.annotation.Annotation接口,并非声明了一个interface

 

    2)、Annotation类型、方法定义是独特的、受限制的。

 

  Annotation 类型的方法必须声明为无参数、无异常抛出的。这些方法定义了annotation的成员:方法名成为了成员名,而方法返回值成为了成员的类型。而方法返回值类型必须为primitive类型、Class类型、枚举类型、annotation类型或者由前面类型之一作为元素的一维数组。方法的后面可以使用 default和一个默认数值来声明成员的默认值,null不能作为成员默认值,这与我们在非annotation类型中定义方法有很大不同。

 

  Annotation类型和它的方法不能使用annotation类型的参数、成员不能是generic。只有返回值类型是Class的方法可以在annotation类型中使用generic,因为此方法能够用类转换将各种类型转换为Class

 

    3)、Annotation类型又与接口有着近似之处。

 

  它们可以定义常量、静态成员类型(比如枚举类型定义)。Annotation类型也可以如接口一般被实现或者继承。

 

 

、应用场合

 

  annotation一般作为一种辅助途径,应用在软件框架或工具中,在这些工具类中根据不同的 annontation注解信息采取不同的处理过程或改变相应程序元素(类、方法及成员变量等)的行为。

 

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

 

 

 四、常见标准的Annotation

 

  从java5版本开始,自带了三种标准annontation类型,

 

    (1)、Override

 

  java.lang.Override 是一个marker annotation类型,它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断言的作用。如果我们使用了这种annotation在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。

 

  这个annotaton常常在我们试图覆盖父类方法而确又写错了方法名时加一个保障性的校验过程。

 

    (2)、Deprecated

 

  Deprecated也是一种marker annotation。当一个类型或者类型成员使用@Deprecated修饰的话,编译器将不鼓励使用这个被标注的程序元素。所以使用这种修饰具有一定的 “延续性”:如果我们在代码中通过继承或者覆盖的方式使用了这个过时的类型或者成员,虽然继承或者覆盖后的类型或者成员并不是被声明为 @Deprecated,但编译器仍然要报警。

 

  注意:@Deprecated这个annotation类型和javadoc中的 @deprecated这个tag是有区别的:前者是java编译器识别的,而后者是被javadoc工具所识别用来生成文档(包含程序成员为什么已经过时、它应当如何被禁止或者替代的描述)。

 

    (3)、SuppressWarnings

 

  此注解能告诉Java编译器关闭对类、方法及成员变量的警告。

 

  有时编译时会提出一些警告,对于这些警告有的隐藏着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对。又由于成员值是一个数组,故使用大括号来声明数组值。

 

 

注意:我们可以在下面的情况中缩写annotation:当annotation只有单一成员,并成员命名为"value="。这时可以省去"value="。比如将上面的SuppressWarnings annotation进行缩写:

 

代码:

 

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

 

 

 

 

如果SuppressWarnings所声明的被禁止警告个数为一个时,可以省去大括号:

 

 

 

@SuppressWarnings("unchecked")

 

 

 

、自定义annontation示例

 

  示例共涉及四个类:

  清单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
= "这是一个有用的工具类")
public class Utility {

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



}
复制代码

注:这是个普通的Java类,运行了@Description和@Author注解。

清单3:AnalysisAnnotation.java

复制代码
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();
}
}

}
复制代码

注:这是个与自定义@Description和@Author配套的基础框架或工具类,通过此类来获得与普通Java类Utility.java关联的信息,即描述和作者。

运行AnalysisAnnotation,输出结果为:

Utility's Description--->这是一个有用的工具类
Utility's Author--->haoran_202 from com.magc

posted @ 2015-06-11 18:06 冯威威 阅读(235) | 评论 (0)编辑 收藏
在ORACLE 数据库中有一种方法可以实现级联查询
select *                //要查询的字段
from table              //具有子接点ID与父接点ID的表 
start with selfid=id      //给定一个startid(字段名为子接点ID,及开始的ID号)
connect by prior selfid=parentid       //联接条件为子接点等于父接点,不能反

这个SQL主要用于菜单的级联查询,给一个父接点可以查出所有的子接点。及子接点的子接点,一查到底,很实用。不过呢这个程序只能在oracle里面用,我目前还不知道在其它数据库里是怎么调用的。等我找到了,再贴出来与大家分享。
这个程序,估计好多人看不明白,其实放了这么久我也一时没看明白,重新测了一下,补充说明一下,不然我下次又看不懂了。
以一个windows系统的菜单为例。我那一个这样的表menu。
说明:
mid:菜单的ID号
mname:菜单名称
mpid:菜单的
quickey:快捷键
validate:权限表(存放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;
这样就可以把 “文件”里的子菜单全部列出来了。当然实际应用不会这么简单,如附加其实条件,尤其是权限管理,这时根据你的系统要求,是对个个验证,还是对角色验证,把这些人的ID放在validate这个字段里,组成一个字符串,N个ID用逗号隔开,(注意,在往数据库保存时要注意对字符串处理一下,截取掉最后一个逗号这样可以节省很多麻烦)
select * from menu
where validate in(……)
and mid in(
   select mid from menu  //这里不能用*号了。
   start with mid=1     
   connect by prior mid=mpid;
)
最后再补充一点关于随机查询的代码
select * from user order by sys_guid()
posted @ 2015-03-12 12:04 冯威威 阅读(1446) | 评论 (0)编辑 收藏

今天看到某网友关于“如何以Java实现网页截图技术”的咨询帖,由于出现该咨询的地点非常不适合较长回复,故以博文形式回答。

 

事实上,如果您想以Java实现网页截图,也就是“输入一段网址,几秒钟过后就能截取一张网页缩略图”的效果。那么,您至少有3种方式可以选择。

 

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

 

方法详解:该方法利用Robat提供的强大桌面操作能力,硬性调用浏览器打开指定网页,并将网页信息保存到本地。

 

优势:简单易用,不需要任何第三方插件。

 

缺点:不能同时处理大量数据,技术含量过低,属于应急型技巧。

 

实现方法:使用如下代码即可


 

 

  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、最常规的方式——利用JNI,调用第三方C/C++组件

方法详解:目前来讲,Java领域对于网页截图组件的开发明显不足(商机?),当您需要完成此种操作时,算得上碰到了Java的软肋。但是,众所周知Java也拥有强大的JNI能力,可以轻易将C/C++开发的同类组件引为己用。

优势:实现简单,只需要封装对应的DLL文件,就可以让Java实现同类功能。

 

劣势:同其他JNI实现一样,在跨平台时存在隐患,而且您的程序将不再属于纯Java应用。

 

实现方法:可参见此用例,具体封装何种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转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部分的实现:

 

 

 

  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之所以在浏览器中以具体的网页格式出现,并非服务器端传了一整个应用到客户端,而是源自于浏览器对于客户端自行解析的结果。因此,只要我们将对应的解析一一实现,那么将网页图形化,就将不是什么难事。


优势:纯Java实现,一劳永逸,一旦开发完成则永远通用,而且有一定的商用价值。

 

劣势:开发费时,且需要针对不同语法做精确分析,才能保证输出的基本正确。尤其在涉及到JavaScript解析时,难度将尤其增大。

 

实现方法:目前尚无具体案例可供参考。但是,由于Java有jdic之类的浏览器项目存在(https://jdic.dev.java.net/ ),而Java图形界面又属绘制生成。从理论上说,我们可以将所有具备Graphics的组件图形化保存。

 

而如果自行解析,那么您需要建立HTML解析器(或使用第三方的,万幸Java在这方面的组件很多),了解Java2D机制,了解何时该使用drawString绘制文字,何时又该使用drawImage插入图片等等。

 


补充:

 

这是一个利用内置浏览器截图的示例,使用了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""//");  
  25.     //以javascript脚本获得网页全屏后大小   
  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.             // 监听加载进度   
  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.                     // 当网页超出目标大小时   
  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组件转Swing组件,不初始化父窗体将无法启动webBrowser   
  125.                 JFrame frame = new JFrame("以DJ组件保存指定网页截图");  
  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 冯威威 阅读(406) | 评论 (0)编辑 收藏