小菜毛毛技术分享

与大家共同成长

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks

#

前不久做的一个笔记本BIOS相关的项目,操作对BOIS文件里面的内容时进行较多的位运算,于是顺手整理了一份位运算相关的内容。
   Java 定义的位运算(bitwise operators )直接对整数类型的位进行操作,这些整数类型包括long,int,short,char,and byte 。
   所有的整数类型(除了char 类型之外)都是有符号的整数。这意味着他们既能表示正数,又能表示负数。Java 使用采用补码来表示负数。
   为什么采用补码吗?这是考虑到零的交叉(zero crossing )问题。
   原码:
   将最高位作为符号位(以0代表正,1代表负),其余各位代表数值本身的绝对值(以二进制表示)。这个时候有一个问题:表示0的时候正0和负0表示并不一 样,所以在计算机中没有采用原码的表示形式。
   反码:
   一个数如果为正,则它的反码与原码相同;一个数如果为负,则符号位为1,其余各位是对原码取反。问题和上面一样的。所以,计算机中也没有采用反码来表示数 字。
   补码:
   一个数如果为正,则它的原码、反码、补码相同;一个数如果为负,则符号位为1,其余各位是对原码取反,然后再加1。也就是通过将与其对应的正数的二进制代 码取反(即将1变成0,将0变成1),然后对其结果加1。例如,-42就是通过将42的二进制代码的各个位取反,即对00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。要对一个负数解码,首先对其所有的位取反,然后加1。例如-42,或11010110 取反后为00101001 ,或41,然后加1,这样就得到了42。
   在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为:1 00000000。进位1被丢弃。这种情况,我们叫溢出。在计算机中,假定byte 类型的值零为0000 0000,反码为1111 1111 补码为1 0000 0000,在计算-0的补码的时候因为溢出,导致-0和+0是一样的表示,所以计算机中采用补码的形式表示数字。
数的最大值和最小值:由于最高位为符号位,所以最大值和最小值时要去掉最高位。如一个byte为8位.最大值为0111 1111 ,即 (2的7次方) -1 = 127.最小值为1000 0000,即-( 2的7次方) =-128。char为无符号数,没有符号位,所以最小值为0,最大值为1111 1111 1111 1111 ,即(2的16次方) -1。

移位运算符
包括:
“>> 右移,高位补符号位”;
“>>> 无符号右移,高位补0”;
“<< 左移”;

例子:
-5>>3=-1
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111
其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。

-5<<3=-40
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1101 1000
其结果与 -5*2*2*2 完全相同。

5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其结果与 5/(2*2*2) 完全相同。

5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其结果与 5*2*2*2 完全相同。

-5>>>3=536870911
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111

无论正数、负数,它们的右移、左移、无符号右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -1。
0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111

位逻辑运算符
包括:
& 与;
| 或;
~ 非(也叫做求反);
^ 异或

“& 与”、“| 或”、“~ 非”是基本逻辑运算,由此可以演变出“与非”、“或非”、“与或非”复合逻辑运算。“^ 异或”是一种特殊的逻辑运算,对它求反可以得到“同或”,所以“同或”逻辑也叫“异或非”逻辑。

例子:
5&3=1
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0001

-5&3=1
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0011

5|3=7
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0111

-5|3=-5
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1011

~5=-6
0000 0000 0000 0000 0000 0000 0000 0101
1111 1111 1111 1111 1111 1111 1111 1010

~-5=4
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0100

5^3=6
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0110

-5^3=-8
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1000

参考:
http://blog.csdn.net/zdmilan/archive/2005/10/30/519634.aspx
posted @ 2010-05-18 12:02 小菜毛毛 阅读(342) | 评论 (0)编辑 收藏

应用程序服务器通过各种协议,可以包括HTTP,把商业逻辑暴露给客户端应用程序。Web服务器主要是处理向浏览器发送HTML以供浏览,而应用程序服务 器提供访问商业逻辑的途径以供客户端应用程序使用。应用程序使用此商业逻辑就象你调用对象的一个方法一样。
通俗的讲,Web服务器传送(serves)页面使浏览器可以浏览,然而应用程序服务器提供的是客户端应用程序可以调用(call)的方法 (methods)。确切一点,你可以说:Web服务器专门处理HTTP请求(request),但是应用程序服务器是通过很多协议来为应用程序提供 (serves)商业逻辑(business logic)。

下面让我们来细细道来:

Web服务器 (Web Server)

Web服务器可以解析(handles)HTTP协议。当Web服务器接收到一个HTTP请求(request),会返回一个HTTP响应 (response),例如送回一个HTML页面。为了处理一个请求(request),Web服务器可以响应(response)一个静态页面或图片, 进行页面跳转(redirect),或者把动态响应(dynamic response)的产生委托(delegate)给一些其它的程序例如CGI脚本,JSP(JavaServer Pages)脚本,servlets,ASP(Active Server Pages)脚本,服务器端(server-side)JavaScript,或者一些其它的服务器端(server-side)技术。无论它们(译者 注:脚本)的目的如何,这些服务器端(server-side)的程序通常产生一个HTML的响应(response)来让浏览器可以浏览。

要知道,Web服务器的代理模型(delegation model)非常简单。当一个请求(request)被送到Web服务器里来时,它只单纯的把请求(request)传递给可以很好的处理请求 (request)的程序(译者注:服务器端脚本)。Web服务器仅仅提供一个可以执行服务器端(server-side)程序和返回(程序所产生的)响 应(response)的环境,而不会超出职能范围。服务器端(server-side)程序通常具有事务处理(transaction processing),数据库连接(database connectivity)和消息(messaging)等功能。

虽然 Web服务器不支持事务处理或数据库连接池,但它可以配置(employ)各种策略(strategies)来实现容错性(fault tolerance)和可扩展性(scalability),例如负载平衡(load balancing),缓冲(caching)。集群特征(clustering—features)经常被误认为仅仅是应用程序服务器专有的特征。

应用程序服务器(The Application Server)
根据我们的定义,作为应用程序服务器, 它通过各种协议,可以包括HTTP,把商业逻辑暴露给(expose)客户端应用程序。Web服务器主要是处理向浏览器发送HTML以供浏览,而应用程序 服务器提供访问商业逻辑的途径以供客户端应用程序使用。应用程序使用此商业逻辑就象你调用对象的一个方法(或过程语言中的一个函数)一样。

应用程序服务器的客户端(包含有图形用户界面(GUI)的)可能会运行在一台PC、一个Web服务器或者甚至是其它的应用程序服务器上。在应用程序服务 器与其客户端之间来回穿梭(traveling)的信息不仅仅局限于简单的显示标记。相反,这种信息就是程序逻辑(program logic)。 正是由于这种逻辑取得了(takes)数据和方法调用(calls)的形式而不是静态HTML,所以客户端才可以随心所欲的使用这种被暴露的商业逻辑。

在大多数情形下,应用程序服务器是通过组件(component)的应用程序接口(API)把商业逻辑暴露(expose)(给客户端应用程序)的,例 如基于J2EE(Java 2 Platform, Enterprise Edition)应用程序服务器的EJB(Enterprise JavaBean)组件模型。此外,应用程序服务器可以管理自己的资源,例如看大门的工作(gate-keeping duties)包括安全(security),事务处理(transaction processing),资源池(resource pooling), 和消息(messaging)。就象Web服务器一样,应用程序服务器配置了多种可扩展(scalability)和容错(fault tolerance)技术。

一个例子
例如,设想一个在线商店(网站)提供实时定价(real-time pricing)和有效性(availability)信息。这个站点(site)很可能会提供一个表单(form)让你来选择产品。当你提交查询 (query)后,网站会进行查找(lookup)并把结果内嵌在HTML页面中返回。网站可以有很多种方式来实现这种功能。我要介绍一个不使用应用程序 服务器的情景和一个使用应用程序服务器的情景。观察一下这两中情景的不同会有助于你了解应用程序服务器的功能。

情景 1:不带应用程序服务器的Web服务器

在此种情景下,一个Web服务器独立提供在线商店的功能。Web服务器获 得你的请求(request),然后发送给服务器端(server-side)可以处理请求(request)的程序。此程序从数据库或文本文件 (flat file,译者注:flat file是指没有特殊格式的非二进制的文件,如properties和XML文件等)中查找定价信息。一旦找到,服务器端(server-side)程序 把结果信息表示成(formulate)HTML形式,最后Web服务器把会它发送到你的Web浏览器。

简而言之,Web服务器只是简 单的通过响应(response)HTML页面来处理HTTP请求(request)。

情景2:带应用程序服务器的 Web服务器

情景2和情景1相同的是Web服务器还是把响应(response)的产生委托 (delegates)给脚本(译者注:服务器端(server-side)程序)。然而,你可以把查找定价的商业逻辑(business logic)放到应用程序服务器上。由于这种变化,此脚本只是简单的调用应用程序服务器的查找服务(lookup service),而不是已经知道如何查找数据然后表示为(formulate)一个响应(response)。 这时当该脚本程序产生HTML响应(response)时就可以使用该服务的返回结果了。

在此情景中,应用程序服务器提供 (serves)了用于查询产品的定价信息的商业逻辑。(服务器的)这种功能(functionality)没有指出有关显示和客户端如何使用此信息的细 节,相反客户端和应用程序服务器只是来回传送数据。当有客户端调用应用程序服务器的查找服务(lookup service)时,此服务只是简单的查找并返回结果给客户端。

通过从响应产生(response-generating)HTML的 代码中分离出来,在应用程序之中该定价(查找)逻辑的可重用性更强了。其他的客户端,例如收款机,也可以调用同样的服务(service)来作为一个店员 给客户结帐。相反,在情景1中的定价查找服务是不可重用的因为信息内嵌在HTML页中了。

总而言之,在情景2的模型中,在Web服务器 通过回应HTML页面来处理HTTP请求(request),而应用程序服务器则是通过处理定价和有效性(availability)请求 (request)来提供应用程序逻辑的。

警告(Caveats)
现在,XML Web Services已经使应用程序服务器和Web服务器的界线混淆了。通过传送一个XML有效载荷(payload)给服务器,Web服务器现在可以处理数 据和响应(response)的能力与以前的应用程序服务器同样多了。

另外,现在大多数应用程序服务器也包含了Web服务器,这就意味 着可以把Web服务器当作是应用程序服务器的一个子集(subset)。虽然应用程序服务器包含了Web服务器的功能,但是开发者很少把应用程序服务器部 署(deploy)成这种功能(capacity)(译者注:这种功能是指既有应用程序服务器的功能又有Web服务器的功能)。相反,如果需要,他们通常 会把Web服务器独立配置,和应用程序服务器一前一后。这种功能的分离有助于提高性能(简单的Web请求(request)就不会影响应用程序服务器 了),分开配置(专门的Web服务器,集群(clustering)等等),而且给最佳产品的选取留有余地。


posted @ 2010-05-14 10:19 小菜毛毛 阅读(205) | 评论 (0)编辑 收藏

HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议
它是一个安全通信通道,它基于HTTP开发,用于在客户计算机和服务器之间交换信息。它使用安全套接字层(SSL)进行信息交换,简单来说它是HTTP的 安全版。
它是由Netscape开发并内置于其浏览器中,用于对数据进行压缩和解压操作,并返回网络上传送回的结果。HTTPS实际上应用了Netscape的安 全全套接字层(SSL)作为HTTP应用层的子层。(HTTPS使用端口443,而不是象HTTP那样使用端口80来和TCP/IP进行通信。)SSL使 用40 位关键字作为RC4流加密算法,这对于商业信息的加密是合适的。HTTPS和SSL支持使用X.509数字认证,如果需要的话用户可以确认发送者是谁。
HTTPS和HTTP的区别:
https协议需要到ca申请证书,一般免费证书很少,需要交费。
http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议
http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。
http的连接很简单,是无状态的
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全
HTTPS解决的问题:
1 . 信任主机的问题. 采用https 的server 必须从CA 申请一个用于证明服务器用途类型的证书. 改证书只有用于对应的server 的时候,客户度才信任次主机. 所以目前所有的银行系统网站,关键部分应用都是https 的. 客户通过信任该证书,从而信任了该主机. 其实这样做效率很低,但是银行更侧重安全. 这一点对我们没有任何意义,我们的server ,采用的证书不管自己issue 还是从公众的地方issue, 客户端都是自己人,所以我们也就肯定信任该server.
2 . 通讯过程中的数据的泄密和被窜改
1. 一般意义上的https, 就是 server 有一个证书.
a) 主要目的是保证server 就是他声称的server. 这个跟第一点一样.
b) 服务端和客户端之间的所有通讯,都是加密的.
i. 具体讲,是客户端产生一个对称的密钥,通过server 的证书来交换密钥. 一般意义上的握手过程.
ii. 加下来所有的信息往来就都是加密的. 第三方即使截获,也没有任何意义.因为他没有密钥. 当然窜改也就没有什么意义了.
2. 少许对客户端有要求的情况下,会要求客户端也必须有一个证书.
a) 这里客户端证书,其实就类似表示个人信息的时候,除了用户名/密码, 还有一个CA 认证过的身份. 应为个人证书一般来说上别人无法模拟的,所有这样能够更深的确认自己的身份.
b) 目前少数个人银行的专业版是这种做法,具体证书可能是拿U盘作为一个备份的载体.
HTTPS 一定是繁琐的.
a) 本来简单的http协议,一个get一个response. 由于https 要还密钥和确认加密算法的需要.单握手就需要6/7 个往返.
i. 任何应用中,过多的round trip 肯定影响性能.
b) 接下来才是具体的http协议,每一次响应或者请求, 都要求客户端和服务端对会话的内容做加密/解密.
i. 尽管对称加密/解密效率比较高,可是仍然要消耗过多的CPU,为此有专门的SSL 芯片. 如果CPU 信能比较低的话,肯定会降低性能,从而不能serve 更多的请求.
ii. 加密后数据量的影响. 所以,才会出现那么多的安全认证提示
posted @ 2010-05-13 09:37 小菜毛毛 阅读(268) | 评论 (0)编辑 收藏

早早就听说过开发方向的笔试面试都是以算法和数据结构这些基础为主,我自恃着那么一丁点项目经验,一直没放在心上。

连日下来的笔试彻底印证了师兄们的话,笔试基本不过。最可惜的是淘宝,笔试中发挥不错终于能进一面,一开始聊家常聊框架聊开源技术还聊得不错,突然 间,连续问了三个问题:

1.多线程访问hashtable和hashmap有什么不一样?我只答出线程安全不一样,具体怎么不一样就有一句每一句了(回来google一 下,这种java基础还真TM简单,枉称精通java了)

2.平衡二叉树查找算法的复杂度?再次雷响,随便蒙了个归并排序的复杂度给他。

3.对于100W条数据的排序和查找有什么效率高的方式?完了,结结巴巴的说一通,最后自认不会……

原本以为技术面会比笔试好过的,回学校的路上我泪流满面啊我。这些都不是RP问题了,铁了心恶补数据结构……

Java线 程安全同步解决方案 

1、 问题描述:

  如果一个资源或对象可能被多个线程同时访问,它就是一个共享资源;例如 类的成员变量,包括类变量和实例变量,再比如对一个文件进行写操作等。一般情况下,对共享资源的访问需要考虑线程安全的问题。

  如果一个对象的完整生命周期只在一个线程内,则不需要考虑线程安全,例 如一个局部变量。下面为一个示例代码:

  1. public class C1 {
  2. public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
  3. //其他代码
  4. }

  假如在一个JSP中这样的去调用:

  1. <a.jsp>:
  2. <%
  3. Java.util.Date date = C1.sdf.parse(“2003-4-15”);
  4. %>

  则这样的代码不是线程安全的。因为java.text.SimpleDateFormat 不是线程安全的,a.jsp中的代码将会有若干个线程同时执行,而都访问的是同一个线程不安全的对象,这样就不是一个线程安全的代码。正确的写法应该如 下:

  1. <a.jsp>:
  2. <%
  3. java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
  4. Java.util.Date date = sdf.parse(“2003-4-15”);
  5. %>

2、 原因分析:

  此时,sdf对象从创建到销毁都位于一个方法中,相当于一个局部变量,不是一个共享资源,因此则没有线程不安全的问题。

3、 解决方法或过程:

1) 如果对象是immutable,则是线程安全的,例如:String,可以放心使用。
2) 如果对象是线程安全的,则放心使用
3) 有 条件线程安全,对于Vector和Hashtable一般情况下是线程安全的,但是对于某些特殊情况,需要通过额外的synchronized保证线程安 全。
4) 使用synchronized关键字;

  对于上例中可以改写jsp代码,在sdf上进行同步,而不需要每次创建一个新的对象来保证线程安全,代码如下:

  1. <%
  2. synchronized(C1.sdf){
  3. Java.util.Date date = C1.sdf.parse(“2003-4-15”);
  4. }
  5. %>

  这种写法是在一个对象级别上进行同步,也就是说任何时候,对于这个对象,最多只能有一个线程在执行同步方法。

  另外一种写法是在Class级别上进行同步,写法如下:

  1. public class C1 {
  2. public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
  3. public void method(){
  4. synchronized(C1.class){
  5. //synchronized code
  6. }
  7. }
  8. }

  这种写法表示无论C1有多少个实例,在任何一个时间点,最多只能有一个线程和一个实例进入同步块中。这种同步会比较大的影响性能。

  5) 有些对象不能在多线程间共享,则只能在方法内部使用,或者只在一个线程内部使用。

synchronized详解

Java对多线程的支持与同步机制深受大家的喜爱,似乎看起来使用了synchronized关键字就可以轻松地解决多线程共享数据同步问题。到底如何?――还得对synchronized关键字的作用进行深入了解才可定论。

总的说来,synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。

在进一步阐述之前,我们需要明确几点:

A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。

B.每个对象只有一个锁(lock)与之相关联。

C.实现同步是要很大的系统开销作为代价的,甚至可能 造成死锁,所以尽量避免无谓的同步控制。

接着来讨论synchronized

用到不同地方对代码产生的影响:

假设P1P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1P2就都可以调用它们。

1. synchronized当作函数修饰符时,示例代码如下:

Public synchronized void methodAAA()

{

//….

}

这也就是同步方法,那这时synchronized锁定的是哪个对象呢?它锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不 同的线程中执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所 产生的另一对象P2却可以任意调用这个被加了synchronized关键字的方法。

上边的示例代码等同于如下代码:

public void methodAAA()

{

synchronized (this)      // (1)

{

       //…..

}

}

 (1)处 的this指的是什么呢?它指的就是调用这个方法的对象,如P1。可见 同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象 锁的线程,才可以调用P1的同步方法,而对P2而 言,P1这个锁与它毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造成数据混乱:(

2.同步块,示例代码如下:

           public void method3(SomeObject so)

              {

                     synchronized(so)

{

       //…..

}

}

这时,锁就是so这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明确的对象作为 锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁:

class Foo implements Runnable

{

       private byte[] lock = new byte[0]; // 特殊的instance变量

    Public void methodA()

{

       synchronized(lock) { //… }

}

//…..

}

注:零长度的byte数 组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对 象只需3条操作码,而Object lock = new Object()则 需要7行操作码。

3.将synchronized作用于static 函数,示例代码如下:

      Class Foo

{

public synchronized static void methodAAA()   // 同步的static 函数

{

//….

}

public void methodBBB()

{

       synchronized(Foo.class)   // class literal(类名称字面常量)

}

       }

   代码中的methodBBB()方法是把class literal作为锁的情况,它和同步的static函 数产生的效果是一样的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class, 而不再是由这个Class产生的某个具体对象了)。

记得在《Effective Java》一书中看到过将 Foo.class P1.getClass()用于作同步锁还不一样,不能用P1.getClass()来达到锁这个Class的目的。P1指的是由Foo类产生的对象。

可以推断:如果一个类中定义了一个synchronizedstatic函数A,也定 义了一个synchronized instance函数B,那么这个类的同一对象Obj在多线程中分别访问AB两个方法时,不会构成同步,因为它们的锁都不一样。A方法的锁 是Obj这个对象,而B的锁是Obj所属的那个Class

小结如下:

搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程序。

还有一些技巧可以让我们对共享资源的同步访问更加安全:

1. 定义private instance变量+它的 get方法,而不要定义public/protectedinstance变量。如果将变量定义为public,对象在外界可以绕过同步方法的控制而 直接取得它,并改动它。这也是JavaBean的标准实现方式之一。

2. 如果instance变量是一个对象,如数组或ArrayList什么的,那上述方法仍然不安全, 因为当外界对象通过get方法拿到这个instance对象的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。这个时候就需要将get方法 也加上synchronized同步,并且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了。



posted @ 2010-05-11 09:49 小菜毛毛 阅读(896) | 评论 (0)编辑 收藏

字符,字节和编码

转载自:http://www.regexlab.com/zh/encoding.htm

级别:中级

摘要:本文介绍了字符与编码的发展过程,相关概念的正确理解。举例说明了一些实际应用中,编码的实现方法。然后,本文 讲述了通常对字符与编码的几种误解,由于这些误解而导致乱码产生的原因,以及消除乱码的办法。本文的内容涵盖了“中文问题”,“乱码问题”。

掌握编码问题的关键是正确地理解相关概念,编码所涉及的技术其实是很简单的。因此,阅读本文时需要慢读多想,多思考。

引言

“字符与编码”是一个被经常讨论的话题。即使这样,时常出现的乱码仍然困扰着大家。虽然我们有很多的办法可以用来消除乱 码,但我们并不一定理解这些办法的内在原理。而有的乱码产生的原因,实际上由于底层代码本身有问题所导致的。因此,不仅是初学者会对字符编码感到模糊,有 的底层开发人员同样对字符编码缺乏准确的理解。

回页首

1. 编码问题的由来,相关概念的理解

1.1 字符与编码的发展

从计算机对多国语言的支持角度看,大致可以分为三个阶段:

系统内码 说明 系统
阶段一 ASCII 计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。 英文 DOS
阶段二 ANSI编码
(本地化)
为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。

不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。

不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
中文 DOS,中文 Windows 95/98,日文 Windows 95/98
阶段三 UNICODE
(国际化)
为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集, 为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 Windows NT/2000/XP,Linux,Java

字符串在内存中的存放方法:

在 ASCII 阶段,单字节字符串使用一个字节存放一个字符(SBCS)。比如,"Bob123" 在内存中为:

42 6F 62 31 32 33 00
B o b 1 2 3 "0

在使用 ANSI 编码支持多种语言阶段,每个字符使用一个字节或多个字节来表示(MBCS),因此,这种方式存放的字符也被称作多字节字符。比如,"中文 123" 在中文 Windows 95 内存中为7个字节,每个汉字占2个字节,每个英文和数字字符占1个字节:

D6 D0 CE C4 31 32 33 00
1 2 3 "0

在 UNICODE 被采用之后,计算机存放字符串时,改为存放每个字符在 UNICODE 字符集中的序号。目前计算机一般使用 2 个字节(16 位)来存放一个序号(DBCS),因此,这种方式存放的字符也被称作宽字节字符。 比如,字符串 "中文123" 在 Windows 2000 下,内存中实际存放的是 5 个序号:

2D 4E 87 65 31 00 32 00 33 00 00 00      ← 在 x86 CPU 中,低字节在前
1 2 3 "0

一共占 10 个字节。

回页首

1.2 字符,字节,字符串

理解编码的关键,是要把字符的概念和字节的概念理解准确。这两个概念容易混淆,我们在此做一下区分:

概念描述 举例
字符 人们使用的记号,抽象意义上的一个符号。 '1', '中', 'a', '$', '¥', ……
字节 计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间。 0x01, 0x45, 0xFA, ……
ANSI
字符串
在内存中,如果“字符”是以 ANSI 编码形式存在的,一个字符 可能使用一个字节或多个字节来表示,那么我们称这种字符串为 ANSI 字符串或者多字节字符串 "中文123"
(占7字节)
UNICODE
字符串
在内存中,如果“字符”是以在 UNICODE 中的序号存在的,那么我们称这种字符串为 UNICODE 字符串或者宽字节字符串 L"中文123"
(占10字节)

由于不同 ANSI 编码所规定的标准是不相同的,因此,对于一个给定的多字节字符串,我们必须知道它采用 的是哪一种编码规则,才能够知道它包含了哪些“字符”。而对于 UNICODE 字符串来说,不管在什么环境下,它所代表的“字符”内容总 是不变的。

回页首

1.3 字符集与编码

各个国家和地区所制定的不同 ANSI 编码标准中,都只规定了各自语言所需的“字符”。比如:汉字标准(GB2312)中没有规定韩国语字符怎样存储。这些 ANSI 编码标准所规定的内容包含两层含义:

  1. 使用哪些字符。也就是说哪些汉字,字母和符号会被收入标准中。所包含“字符”的集合就叫做“字符集”。
  2. 规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,这个规定就叫做“编码”。

各个国家和地区在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,比 如:GB2312, GBK, JIS 等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。

UNICODE 字符集”包含了各种语言中使用到的所有“字符”。用来给 UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

回页首

1.4 常用的编码简介

简单介绍一下常用的编码规则,为后边的章节做一个准备。在这里,我们根据编码规则的特点,把所有的编码分成三类:

分类 编码标准 说明
单字节字符编码 ISO-8859-1 最简单的编码规则,每一个字节直接作为一个 UNICODE 字符。比如,[0xD6, 0xD0] 这两个字节,通过 iso-8859-1 转化为字符串时,将直接得到 [0x00D6, 0x00D0] 两个 UNICODE 字符,即 "ÖÐ"。

反之,将 UNICODE 字符串通过 iso-8859-1 转化为字节串时,只能正常转化 0~255 范围的字符。
ANSI 编码 GB2312,
BIG5,
Shift_JIS,
ISO-8859-2 ……
把 UNICODE 字符串通过 ANSI 编码转化为“字节串”时,根据各自编码的规定,一个 UNICODE 字符可能转化成一个字节或多个字节。

反之,将字节串转化成字符串时,也可能多个字节转化成一个字符。比如,[0xD6, 0xD0] 这两个字节,通过 GB2312 转化为字符串时,将得到 [0x4E2D] 一个字符,即 '中' 字。

“ANSI 编码”的特点:
1. 这些“ANSI 编码标准”都只能处理各自语言范围之内的 UNICODE 字符。
2. “UNICODE 字符”与“转换出来的字节”之间的关系是人为规定的。
UNICODE 编码 UTF-8,
UTF-16, UnicodeBig ……
与“ANSI 编码”类似的,把字符串通过 UNICODE 编码转化成“字节串”时,一个 UNICODE 字符可能转化成一个字节或多个字节。

与“ANSI 编码”不同的是:
1. 这些“UNICODE 编码”能够处理所有的 UNICODE 字符。
2. “UNICODE 字符”与“转换出来的字节”之间是可以通过计算得到的。

我们实际上没有必要去深究每一种编码具体把某一个字符编码成了哪几个字节,我们只需要知道“编码”的概念就是把“字符”转 化成“字节”就可以了。对于“UNICODE 编码”,由于它们是可以通过计算得到的,因此,在特殊的场合,我们可以去了解某一种“UNICODE 编码”是怎样的规则。

回页首

2. 字符与编码在程序中的实现

2.1 程序中的字符与字节

在 C++ 和 Java 中,用来代表“字符”和“字节”的数据类型,以及进行编码的方法:

类型或操作 C++ Java
字符 wchar_t char
字节 char byte
ANSI 字符串 char[] byte[]
UNICODE 字符串 wchar_t[] String
字节串→字符串 mbstowcs(), MultiByteToWideChar() string = new String(bytes, "encoding")
字符串→字节串 wcstombs(), WideCharToMultiByte() bytes = string.getBytes("encoding")

以上需要注意几点:

  1. Java 中的 char 代表一个“UNICODE 字符(宽字节字符)”,而 C++ 中的 char 代表一个字节。
  2. MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函数。

回页首

2.2 C++ 中相关实现方法

声明一段字符串常量:

// ANSI 字符串,内容长度 7 字节
char
     sz[20] = "中文123";

// UNICODE 字符串,内容长度 5 个 wchar_t(10 字节)
wchar_t wsz[20] = L""x4E2D"x6587"x0031"x0032"x0033";

UNICODE 字符串的 I/O 操作,字符与字节的转换操作:

// 运行时设定当前 ANSI 编码,VC 格式
setlocale(LC_ALL, ".936");

// GCC 中格式
setlocale(LC_ALL, "zh_CN.GBK");

// Visual C++ 中使用小写 %s,按照 setlocale 指定编码输出到文件
// GCC 中使用大写 %S

fwprintf(fp, L"%s"n", wsz);

// 把 UNICODE 字符串按照 setlocale 指定的编码转换成字节
wcstombs(sz, wsz, 20);
// 把字节串按照 setlocale 指定的编码转换成 UNICODE 字符串
mbstowcs(wsz, sz, 20);

在 Visual C++ 中,UNICODE 字符串常量有更简单的表示方法。如果源程序的编码与当前默认 ANSI 编码不符,则需要使用 #pragma setlocale,告诉编译器源程序使用的编码:

// 如果源程序的编码与当前默认 ANSI 编码不一致,
// 则需要此行,编译时用来指明当前源程序使用的编码

#pragma setlocale
(".936")

// UNICODE 字符串常量,内容长度 10 字节
wchar_t wsz[20] = L"中文123";

以上需要注意 #pragma setlocale 与 setlocale(LC_ALL, "") 的作用是不同的,#pragma setlocale 在编译时起作用,setlocale() 在运行时起作用。

回页首

2.3 Java 中相关实现方法

字符串类 String 中的内容是 UNICODE 字符串:

// Java 代码,直接写中文
String
string = "中文123";

// 得到长度为 5,因为是 5 个字符
System.out.println(string.length());

字符串 I/O 操作,字符与字节转换操作。在 Java 包 java.io.* 中,以“Stream”结尾的类一般是用来操作“字节串”的类,以“Reader”,“Writer”结尾的类一般是用来操作“字符串”的类。

// 字符串与字节串间相互转化

// 按照 GB2312 得到字节(得到多字节字符串)

byte
[] bytes = string.getBytes("GB2312");

// 从字节按照 GB2312 得到 UNICODE 字符串
string = new String(bytes, "GB2312");

// 要将 String 按照某种编码写入文本文件,有两种方法:

// 第一种办法:用 Stream 类写入已经按照指定编码转化好的字节串

OutputStream os = new FileOutputStream("1.txt");
os.write(bytes);
os.close();

// 第二种办法:构造指定编码的 Writer 来写入字符串
Writer ow = new OutputStreamWriter(new FileOutputStream("2.txt"), "GB2312");
ow.write(string);
ow.close();

/* 最后得到的 1.txt 和 2.txt 都是 7 个字节 */

如果 java 的源程序编码与当前默认 ANSI 编码不符,则在编译的时候,需要指明一下源程序的编码。比如:

E:">javac -encoding BIG5 Hello.java

以上需要注意区分源程序的编码与 I/O 操作的编码,前者是在编译时起作用,后者是在运行时起作用。

回页首

3. 几种误解,以及乱码产生的原因和解决办法

3.1 容易产生的误解
对编码的误解
误解一 在将“字节串”转化成“UNICODE 字符串”时,比如在读取文本文件时,或者通过网络传输文本时,容易将“字节串”简单地作为单字节字符串,采用每“一个字节”就是“一个字 符”的方法进行转化。

而实际上,在非英文的环境中,应该将“字节串”作为 ANSI 字符串,采用适当的编码来得到 UNICODE 字符串,有可能“多个字节”才能得到“一个字符”。

通常,一直在英文环境下做开发的程序员们,容易有这种误解。
误解二 在 DOS,Windows 98 等非 UNICODE 环境下,字符串都是以 ANSI 编码的字节形式存在的。这种以字节形式存在的字符串,必须知道是哪种编码才能被正确地使用。这使我们形成了一个惯性思维:“字符串的编码”。

当 UNICODE 被支持后,Java 中的 String 是以字符的“序号”来存储的,不是以“某种编码的字节”来存储的,因此已经不存在“字符串的编码”这个概念了。只有在“字符串”与“字节串”转化时,或 者,将一个“字节串”当成一个 ANSI 字符串时,才有编码的概念。

不少的人都有这个误解。

第一种误解,往往是导致乱码产生的原因。第二种误解,往往导致本来容易纠正的乱码问题变得更复杂。

在这里,我们可以看到,其中所讲的“误解一”,即采用每“一个字节”就是“一个字符”的转化方法,实际上也就等同于采用 iso-8859-1 进行转化。因此,我们常常使用 bytes = string.getBytes("iso-8859-1") 来进行逆向操作,得到原始的“字节串”。然后再使用正确的 ANSI 编码,比如 string = new String(bytes, "GB2312"),来得到正确的“UNICODE 字符串”。

回页首

3.2 非 UNICODE 程序在不同语言环境间移植时的乱码

非 UNICODE 程序中的字符串,都是以某种 ANSI 编码形式存在的。如果程序运行时的语言环境与开发时的语言环境不同,将会导致 ANSI 字符串的显示失败。

比如,在日文环境下开发的非 UNICODE 的日文程序界面,拿到中文环境下运行时,界面上将显示乱码。如果这个日文程序界面改为采用 UNICODE 来记录字符串,那么当在中文环境下运行时,界面上将可以显示正常的日文。

由于客观原因,有时候我们必须在中文操作系统下运行非 UNICODE 的日文软件,这时我们可以采用一些工具,比如,南极星,AppLocale 等,暂时的模拟不同的语言环境。

回页首

3.3 网页提交字符串

当页面中的表单提交字符串时,首先把字符串按照当前页面的编码,转化成字节串。然后再将每个字节转化成 "%XX" 的格式提交到 Web 服务器。比如,一个编码为 GB2312 的页面,提交 "中" 这个字符串时,提交给服务器的内容为 "%D6%D0"。

在服务器端,Web 服务器把收到的 "%D6%D0" 转化成 [0xD6, 0xD0] 两个字节,然后再根据 GB2312 编码规则得到 "中" 字。

在 Tomcat 服务器中,request.getParameter() 得到乱码时,常常是因为前面提到的“误解一”造成的。默认情况下,当提交 "%D6%D0" 给 Tomcat 服务器时,request.getParameter() 将返回 [0x00D6, 0x00D0] 两个 UNICODE 字符,而不是返回一个 "中" 字符。因此,我们需要使用 bytes = string.getBytes("iso-8859-1") 得到原始的字节串,再用 string = new String(bytes, "GB2312") 重新得到正确的字符串 "中"。

回页首

3.4 从数据库读取字符串

通过数据库客户端(比如 ODBC 或 JDBC)从数据库服务器中读取字符串时,客户端需要从服务器获知所使用的 ANSI 编码。当数据库服务器发送字节流给客户端时,客户端负责将字节流按照正确的编码转化成 UNICODE 字符串。

如果从数据库读取字符串时得到乱码,而数据库中存放的数据又是正确的,那么往往还是因为前面提到的“误解一”造成的。解决 的办法还是通过 string = new String( string.getBytes("iso-8859-1"), "GB2312") 的方法,重新得到原始的字节串,再重新使用正确的编码转化成字符串。

回页首

3.5 电子邮件中的字符串

当一段 Text 或者 HTML 通过电子邮件传送时,发送的内容首先通过一种指定的字符编码转化成“字 节串”,然后再把“字节串”通过一种指定的传输编码(Content-Transfer-Encoding)进行转化得到另一串“字节 串”。比如,打开一封电子邮件源代码,可以看到类似的内容:

Content-Type: text/plain;
        charset="gb2312"
Content-Transfer-Encoding: base64

sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg==

最常用的 Content-Transfer-Encoding 有 Base64 和 Quoted-Printable 两种。在对二进制文件或者中文文本进行转化时,Base64 得到的“字节串”比 Quoted-Printable 更短。在对英文文本进行转化时,Quoted-Printable 得到的“字节串”比 Base64 更短。

邮件的标题,用了一种更简短的格式来标注“字符编码”和“传输编码”。比如,标题内容为 "中",则在邮件源代码中表示为:

// 正确的标题格式
Subject: =?GB2312?B?1tA=?=

其中,

  • 第一个“=?”与“?”中间的部分指定了字符编码,在这个例子中指定的是 GB2312。
  • “?”与“?”中间的“B”代表 Base64。如果是“Q”则代表 Quoted-Printable。
  • 最后“?”与“?=”之间的部分,就是经过 GB2312 转化成字节串,再经过 Base64 转化后的标题内容。

如果“传输编码”改为 Quoted-Printable,同样,如果标题内容为 "中":

// 正确的标题格式
Subject: =?GB2312?Q?=D6=D0?=

如果阅读邮件时出现乱码,一般是因为“字符编码”或“传输编码”指定有误,或者是没有指定。比如,有的发邮件组件在发送邮 件时,标题 "中":

// 错误的标题格式
Subject: =?ISO-8859-1?Q?=D6=D0?=

这样的表示,实际上是明确指明了标题为 [0x00D6, 0x00D0],即 "ÖÐ",而不是 "中"。

回页首

4. 几种错误理解的纠正

误解:“ISO-8859-1 是国际编码?”

非也。iso-8859-1 只是单字节字符集中最简单的一种,也就是“字节编号”与“UNICODE 字符编号”一致的那种编码规则。当我们要把一个“字节串”转化成“字符串”,而又不知道它是哪一种 ANSI 编码时,先暂时地把“每一个字节”作为“一个字符”进行转化,不会造成信息丢失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢复到原始的字节串。

误解:“Java 中,怎样知道某个字符串的内码?”

Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符串,不是 ANSI 字符串。我们只需要把字符串作为“抽象的符号的串”来看待。因此不存在字符串的内码的问题。

posted @ 2010-04-30 11:15 小菜毛毛 阅读(333) | 评论 (0)编辑 收藏

想写个struts 2.0+tiles模版玩玩,没有想到找资料还麻烦,于是自己把通宵弄好的过程记下来,以供大家有急需,不足的地方欢迎交流。

1.在WEB-INF/lib下加入所需的jar包 

    commons-digester-1.6.jar,

    tiles-core-2.0-20070207.130156-4.jar,
    tiles-api-2.0-20070207.130156-4.jar,
    struts2-tiles-plugin-2.0.6.jar,
struts2-core-2.0.6.jar
xwork-2.0.1.jar,
2. 以下内容添加到web.xml
 <context-param>
       <param-name>org.apache.tiles.CONTAINER_FACTORY</param-name>
       <param-value>
           org.apache.struts2.tiles.StrutsTilesContainerFactory
       </param-value>
    </context-param>
   
    <context-param>
       <param-name>   org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
       </param-name>
       <param-value>/WEB-INF/tiles.xml</param-value>
    </context-param>
 
    <listener>
       <listener-class>
           org.apache.struts2.tiles.StrutsTilesListener
       </listener-class>
    </listener>
3.在WEB-INF下添加和tiles.tld和tiles.xml文件,其中tiles.tld内容为tiles-core- 2.0-20070207.130156-4.jar包中META_INF/tiles-core.tld的内容。
tiles.xml内容:
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
       "http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
<tiles-definitions>
    <definition name="myapp.homepage" template="layout.jsp">
       <put name="title" value="Tiles tutorial homepage" />
       <put name="header" value="/tiles/header.jsp" />
       <put name="menu" value="/tiles/menu.jsp" />
       <put name="body" value="/tiles/cBody.jsp" />
       <put name="footer" value="/tiles/footer.jsp" />
    </definition>
</tiles-definitions>
   
4.struts.xml 为:
<!DOCTYPE struts PUBLIC  
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="default" extends="tiles-default">
       <action name="go" class="com.action.MyAction">
           <!--result name="success">/next.jsp</result-->
           <result name="success" type="tiles">myapp.homepage</result>
       </action>
       </package>
</struts>
红色部分根据自己项目 定。注意extends="tiles-default"
5创建layout.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="WEB-INF/tiles.tld " prefix="tiles"%>
<html>
    <head>
       <title></title>
    </head>
    <body>
       <table width="768px" height="800px" border="2" align="center">
      
           <tr>
              <td colspan="2" align="center" valign="top" width="768px" height="100px" bgcolor="#80ff80">
                  <tiles:insertAttribute name="header" />
              </td>
           </tr>
           <tr>
              <td align="center" width="150px" height="800px" bgcolor="#00ff00">
                  <tiles:insertAttribute name="menu" />
              </td>
              <td align="right" width="618px" height="800px" bgcolor="#ff80c0">
                  <tiles:insertAttribute name="body" />
              </td>
           </tr>
           <tr>
              <td colspan="2" bgcolor="#00ff40" height="100px">
                  <tiles:insertAttribute name="footer" />
              </td>
           </tr>
       </table>
    </body>
</html>
 
6.根据
<put name="title" value="Tiles tutorial homepage" />
       <put name="header" value="/tiles/header.jsp" />
       <put name="menu" value="/tiles/menu.jsp" />
       <put name="body" value="/tiles/cBody.jsp" />
       <put name="footer" value="/tiles/footer.jsp" />
WebRoot下创 建tiles目录和相应jsp文件
7.OK了!下载源代码到我的CSDN资源http://download.csdn.net/user/haoxing272
null
posted @ 2010-04-26 15:12 小菜毛毛 阅读(4685) | 评论 (1)编辑 收藏

获取 MIME:HttpContext.Current.Request.Files[fileKey].ContentLength

MIME类型就是设定某种扩展名 的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

下面列出常用的文件对应的MIME类型:

Mime- Types(mime类型) Dateiendung(扩 展名) Bedeutung
application/msexcel *.xls *.xla Microsoft Excel Dateien
application/mshelp *.hlp *.chm Microsoft Windows Hilfe Dateien
application/mspowerpoint *.ppt *.ppz *.pps *.pot Microsoft Powerpoint Dateien
application/msword *.doc *.dot Microsoft Word Dateien

application/octet-stream

*.exe exe
application/pdf *.pdf Adobe PDF-Dateien
application/post****** *.ai *.eps *.ps Adobe Post******-Dateien
application/rtf *.rtf Microsoft RTF-Dateien
application/x-httpd-php *.php *.phtml PHP-Dateien
     
application/x-java****** *.js serverseitige Java******-Dateien
application/x-shockwave-flash *.swf *.cab Flash Shockwave-Dateien
application/zip *.zip ZIP-Archivdateien
audio/basic *.au *.snd Sound-Dateien
audio/mpeg *.mp3 MPEG-Dateien
audio/x-midi *.mid *.midi MIDI-Dateien
audio/x-mpeg *.mp2 MPEG-Dateien
audio/x-wav *.wav Wav-Dateien
image/gif *.gif GIF-Dateien
image/jpeg *.jpeg *.jpg *.jpe JPEG-Dateien
image/x-windowdump *.xwd X-Windows Dump
text/css *.css CSS Stylesheet-Dateien
text/html *.htm *.html *.shtml -Dateien
text/java****** *.js Java******-Dateien
text/plain *.txt reine Textdateien
video/mpeg *.mpeg *.mpg *.mpe MPEG-Dateien
video/vnd.rn-realvideo *.rmvb realplay-Dateien
video/quicktime *.qt *.mov Quicktime-Dateien
video/vnd.vivo *viv *.vivo Vivo-Dateien

更多....查找请用ctrl+F

MIME类型大全
application/vnd.lotus-1-2-3
3gp video/3gpp
aab application/x-authoware-bin
aam application/x-authoware-map
aas application/x-authoware-seg
ai application/post******
aif audio/x-aiff
aifc audio/x-aiff
aiff audio/x-aiff
als audio/X-Alpha5
amc application/x-mpeg
ani application/octet-stream
asc text/plain
asd application/astound
asf video/x-ms-asf
asn application/astound
asp application/x-asap
asx video/x-ms-asf
au audio/basic
avb application/octet-stream
avi video/x-msvideo
awb audio/amr-wb
bcpio application/x-bcpio
bin application/octet-stream
bld application/bld
bld2 application/bld2
bmp application/x-MS-bmp
bpk application/octet-stream
bz2 application/x-bzip2
cal image/x-cals
ccn application/x-cnc
cco application/x-cocoa
cdf application/x-netcdf
cgi magnus-internal/cgi
chat application/x-chat
class application/octet-stream
clp application/x-msclip
cmx application/x-cmx
co application/x-cult3d-object
cod image/cis-cod
cpio application/x-cpio
cpt application/mac-compactpro
crd application/x-mscardfile
csh application/x-csh
csm chemical/x-csml
csml chemical/x-csml
css text/css
cur application/octet-stream
dcm x-lml/x-evm
dcr application/x-director
dcx image/x-dcx
dhtml text/html
dir application/x-director
dll application/octet-stream
dmg application/octet-stream
dms application/octet-stream
doc application/msword
dot application/x-dot
dvi application/x-dvi
dwf drawing/x-dwf
dwg application/x-autocad
dxf application/x-autocad
dxr application/x-director
ebk application/x-expandedbook
emb chemical/x-embl-dl-nucleotide
embl chemical/x-embl-dl-nucleotide
eps application/post******
eri image/x-eri
es audio/echospeech
esl audio/echospeech
etc application/x-earthtime
etx text/x-setext
evm x-lml/x-evm
evy application/x-envoy
exe application/octet-stream
fh4 image/x-freehand
fh5 image/x-freehand
fhc image/x-freehand
fif image/fif
fm application/x-maker
fpx image/x-fpx
fvi video/isivideo
gau chemical/x-gaussian-input
gca application/x-gca-compressed
gdb x-lml/x-gdb
gif image/gif
gps application/x-gps
gtar application/x-gtar
gz application/x-gzip
hdf application/x-hdf
hdm text/x-hdml
hdml text/x-hdml
hlp application/winhlp
hqx application/mac-binhex40
htm text/html
html text/html
hts text/html
ice x-conference/x-cooltalk
ico application/octet-stream
ief image/ief
ifm image/gif
ifs image/ifs
imy audio/melody
ins application/x-NET-Install
ips application/x-ip******
ipx application/x-ipix
it audio/x-mod
itz audio/x-mod
ivr i-world/i-vrml
j2k image/j2k
jad text/vnd.sun.j2me.app-de******or
jam application/x-jam
jar application/java-archive
jnlp application/x-java-jnlp-file
jpe image/jpeg
jpeg image/jpeg
jpg image/jpeg
jpz image/jpeg
js application/x-java******
jwc application/jwc
kjx application/x-kjx
lak x-lml/x-lak
latex application/x-latex
lcc application/fastman
lcl application/x-digitalloca
lcr application/x-digitalloca
lgh application/lgh
lha application/octet-stream
lml x-lml/x-lml
lmlpack x-lml/x-lmlpack
lsf video/x-ms-asf
lsx video/x-ms-asf
lzh application/x-lzh
m13 application/x-msmediaview
m14 application/x-msmediaview
m15 audio/x-mod
m3u audio/x-mpegurl
m3url audio/x-mpegurl
ma1 audio/ma1
ma2 audio/ma2
ma3 audio/ma3
ma5 audio/ma5
man application/x-troff-man
map magnus-internal/imagemap
mbd application/mbedlet
mct application/x-mascot
mdb application/x-msaccess
mdz audio/x-mod
me application/x-troff-me
mel text/x-vmel
mi application/x-mif
mid audio/midi
midi audio/midi
mif application/x-mif
mil image/x-cals
mio audio/x-mio
mmf application/x-skt-lbs
mng video/x-mng
mny application/x-msmoney
moc application/x-mocha
mocha application/x-mocha
mod audio/x-mod
mof application/x-yumekara
mol chemical/x-mdl-molfile
mop chemical/x-mopac-input
mov video/quicktime
movie video/x-sgi-movie
mp2 audio/x-mpeg
mp3 audio/x-mpeg
mp4 video/mp4
mpc application/vnd.mpohun.certificate
mpe video/mpeg
mpeg video/mpeg
mpg video/mpeg
mpg4 video/mp4
mpga audio/mpeg
mpn application/vnd.mophun.application
mpp application/vnd.ms-project
mps application/x-mapserver
mrl text/x-mrml
mrm application/x-mrm
ms application/x-troff-ms
mts application/metastream
mtx application/metastream
mtz application/metastream
mzv application/metastream
nar application/zip
nbmp image/nbmp
nc application/x-netcdf
ndb x-lml/x-ndb
ndwn application/ndwn
nif application/x-nif
nmz application/x-scream
nokia-op-logo image/vnd.nok-oplogo-color
npx application/x-netfpx
nsnd audio/nsnd
nva application/x-neva1
oda application/oda
oom application/x-AtlasMate-Plugin
pac audio/x-pac
pae audio/x-epac
pan application/x-pan
pbm image/x-portable-bitmap
pcx image/x-pcx
pda image/x-pda
pdb chemical/x-pdb
pdf application/pdf
pfr application/font-tdpfr
pgm image/x-portable-graymap
pict image/x-pict
pm application/x-perl
pmd application/x-pmd
png image/png
pnm image/x-portable-anymap
pnz image/png
pot application/vnd.ms-powerpoint
ppm image/x-portable-pixmap
pps application/vnd.ms-powerpoint
ppt application/vnd.ms-powerpoint
pqf application/x-cprplayer
pqi application/cprplayer
prc application/x-prc
proxy application/x-ns-proxy-autoconfig
ps application/post******
ptlk application/listenup
pub application/x-mspublisher
pvx video/x-pv-pvx
qcp audio/vnd.qcelp
qt video/quicktime
qti image/x-quicktime
qtif image/x-quicktime
r3t text/vnd.rn-realtext3d
ra audio/x-pn-realaudio
ram audio/x-pn-realaudio
rar application/x-rar-compressed
ras image/x-cmu-raster
rdf application/rdf+xml
rf image/vnd.rn-realflash
rgb image/x-rgb
rlf application/x-richlink
rm audio/x-pn-realaudio
rmf audio/x-rmf
rmm audio/x-pn-realaudio
rmvb audio/x-pn-realaudio
rnx application/vnd.rn-realplayer
roff application/x-troff
rp image/vnd.rn-realpix
rpm audio/x-pn-realaudio-plugin
rt text/vnd.rn-realtext
rte x-lml/x-gps
rtf application/rtf
rtg application/metastream
rtx text/richtext
rv video/vnd.rn-realvideo
rwc application/x-rogerwilco
s3m audio/x-mod
s3z audio/x-mod
sca application/x-supercard
scd application/x-msschedule
sdf application/e-score
sea application/x-stuffit
sgm text/x-sgml
sgml text/x-sgml
sh application/x-sh
shar application/x-shar
shtml magnus-internal/parsed-html
shw application/presentations
si6 image/si6
si7 image/vnd.stiwap.sis
si9 image/vnd.lgtwap.sis
sis application/vnd.symbian.install
sit application/x-stuffit
skd application/x-Koan
skm application/x-Koan
skp application/x-Koan
skt application/x-Koan
slc application/x-salsa
smd audio/x-smd
smi application/smil
smil application/smil
smp application/studiom
smz audio/x-smd
snd audio/basic
spc text/x-speech
spl application/futuresplash
spr application/x-sprite
sprite application/x-sprite
spt application/x-spt
src application/x-wais-source
stk application/hyperstudio
stm audio/x-mod
sv4cpio application/x-sv4cpio
sv4crc application/x-sv4crc
svf image/vnd
svg image/svg-xml
svh image/svh
svr x-world/x-svr
swf application/x-shockwave-flash
swfl application/x-shockwave-flash
t application/x-troff
tad application/octet-stream
talk text/x-speech
tar application/x-tar
taz application/x-tar
tbp application/x-timbuktu
tbt application/x-timbuktu
tcl application/x-tcl
tex application/x-tex
texi application/x-texinfo
texinfo application/x-texinfo
tgz application/x-tar
thm application/vnd.eri.thm
tif image/tiff
tiff image/tiff
tki application/x-tkined
tkined application/x-tkined
toc application/toc
toy image/toy
tr application/x-troff
trk x-lml/x-gps
trm application/x-msterminal
tsi audio/tsplayer
tsp application/dsptype
tsv text/tab-separated-values
tsv text/tab-separated-values
ttf application/octet-stream
ttz application/t-time
txt text/plain
ult audio/x-mod
ustar application/x-ustar
uu application/x-uuencode
uue application/x-uuencode
vcd application/x-cdlink
vcf text/x-vcard
vdo video/vdo
vib audio/vib
viv video/vivo
vivo video/vivo
vmd application/vocaltec-media-desc
vmf application/vocaltec-media-file
vmi application/x-dreamcast-vms-info
vms application/x-dreamcast-vms
vox audio/voxware
vqe audio/x-twinvq-plugin
vqf audio/x-twinvq
vql audio/x-twinvq
vre x-world/x-vream
vrml x-world/x-vrml
vrt x-world/x-vrt
vrw x-world/x-vream
vts workbook/formulaone
wav audio/x-wav
wax audio/x-ms-wax
wbmp image/vnd.wap.wbmp
web application/vnd.xara
wi image/wavelet
wis application/x-InstallShield
wm video/x-ms-wm
wma audio/x-ms-wma
wmd application/x-ms-wmd
wmf application/x-msmetafile
wml text/vnd.wap.wml
wmlc application/vnd.wap.wmlc
wmls text/vnd.wap.wml******
wmlsc application/vnd.wap.wml******c
wml****** text/vnd.wap.wml******
wmv audio/x-ms-wmv
wmx video/x-ms-wmx
wmz application/x-ms-wmz
wpng image/x-up-wpng
wpt x-lml/x-gps
wri application/x-mswrite
wrl x-world/x-vrml
wrz x-world/x-vrml
ws text/vnd.wap.wml******
wsc application/vnd.wap.wml******c
wv video/wavelet
wvx video/x-ms-wvx
wxl application/x-wxl
x-gzip application/x-gzip
xar application/vnd.xara
xbm image/x-xbitmap
xdm application/x-xdma
xdma application/x-xdma
xdw application/vnd.fujixerox.docuworks
xht application/xhtml+xml
xhtm application/xhtml+xml
xhtml application/xhtml+xml
xla application/vnd.ms-excel
xlc application/vnd.ms-excel
xll application/x-excel
xlm application/vnd.ms-excel
xls application/vnd.ms-excel
xlt application/vnd.ms-excel
xlw application/vnd.ms-excel
xm audio/x-mod
xml text/xml
xmz audio/x-mod
xpi application/x-xpinstall
xpm image/x-xpixmap
xsit text/xml
xsl text/xml
xul text/xul
xwd image/x-xwindowdump
xyz chemical/x-pdb
yz1 application/x-yz1
z application/x-compress
zac application/x-zaurus-zac
zip application/zip

posted @ 2010-04-15 10:59 小菜毛毛 阅读(267) | 评论 (0)编辑 收藏

HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。本文首先介绍 HTTPClient,然后根据作者实际工作经验给出了一些常见问题的解决方法。

HttpClient简介

HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的应用可以参见http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 项目非常活跃,使用的人还是非常多的。目前 HttpClient 版本是在 2005.10.11 发布的 3.0 RC4 。





回页首


HttpClient 功能介绍

以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。

  • 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
  • 支持自动转向
  • 支持 HTTPS 协议
  • 支持代理服务器等

下面将逐一介绍怎样使用这些功能。首先,我们必须安装好 HttpClient。





回页首


HttpClient 基本功能的使用

GET 方法

使用 HttpClient 需要以下 6 个步骤:

1. 创建 HttpClient 的实例

2. 创建某种连接方法的实例,在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址

3. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例

4. 读 response

5. 释放连接。无论执行方法是否成功,都必须释放连接

6. 对得到后的内容进行处理

根据以上步骤,我们来编写用GET方法来取得某网页内容的代码。

  • 大部分情况下 HttpClient 默认的构造函数已经足够使用。
    HttpClient httpClient = new HttpClient();


  • 创建GET方法的实例。在GET方法的构造函数中传入待连接的地址即可。用GetMethod将会自动处理转发过程,如果想要把自动处理 转发过程去掉的话,可以调用方法setFollowRedirects(false)。
    GetMethod getMethod = new GetMethod("http://www.ibm.com/");


  • 调用实例httpClient的executeMethod方法来执行getMethod。由于是执行在网络上的程序,在运行 executeMethod方法的时候,需要处理两个异常,分别是HttpException和IOException。引起第一种异常的原因主要可能是 在构造getMethod的时候传入的协议不对,比如不小心将"http"写成"htp",或者服务器端返回的内容不正常等,并且该异常发生是不可恢复 的;第二种异常一般是由于网络原因引起的异常,对于这种异常 (IOException),HttpClient会根据你指定的恢复策略自动试着重新执行executeMethod方法。HttpClient的恢复 策略可以自定义(通过实现接口HttpMethodRetryHandler来实现)。通过httpClient的方法setParameter设置你实 现的恢复策略,本文中使用的是系统提供的默认恢复策略,该策略在碰到第二类异常的时候将自动重试3次。executeMethod返回值是一个整数,表示 了执行该方法后服务器返回的状态码,该状态码能表示出该方法执行是否成功、需要认证或者页面发生了跳转(默认状态下GetMethod的实例是自动处理跳 转的)等。
    //设置成了默认的恢复策略,在发生异常时候将自动重试3次,在这里你也可以设置成自定义的恢复策略

    getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,

    new DefaultHttpMethodRetryHandler());

    //执行getMethod

    int statusCode = client.executeMethod(getMethod);

    if (statusCode != HttpStatus.SC_OK) {

    System.err.println("Method failed: " + getMethod.getStatusLine());

    }


  • 在返回的状态码正确后,即可取得内容。取得目标地址的内容有三种方法:第一种,getResponseBody,该方法返回的是目标的二进制的byte 流;第二种,getResponseBodyAsString,这个方法返回的是String类型,值得注意的是该方法返回的String的编码是根据系 统默认的编码方式,所以返回的String值可能编码类型有误,在本文的"字符编码"部分中将对此做详细介绍;第三 种,getResponseBodyAsStream,这个方法对于目标地址中有大量数据需要传输是最佳的。在这里我们使用了最简单的 getResponseBody方法。
    byte[] responseBody = method.getResponseBody();


  • 释放连接。无论执行方法是否成功,都必须释放连接。
    method.releaseConnection();


  • 处理内容。在这一步中根据你的需要处理内容,在例子中只是简单的将内容打印到控制台。
    System.out.println(new String(responseBody));


下面是程序的完整代码,这些代码也可在附件中的test.GetSample中找到。


package test;

import java.io.IOException;

import org.apache.commons.httpclient.*;

import org.apache.commons.httpclient.methods.GetMethod;

import org.apache.commons.httpclient.params.HttpMethodParams;

public class GetSample{

public static void main(String[] args) {

//构造HttpClient的实例

HttpClient httpClient = new HttpClient();

//创建GET方法的实例

GetMethod getMethod = new GetMethod("http://www.ibm.com");

//使用系统提供的默认的恢复策略

getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,

new DefaultHttpMethodRetryHandler());

try {

//执行getMethod

int statusCode = httpClient.executeMethod(getMethod);

if (statusCode != HttpStatus.SC_OK) {

System.err.println("Method failed: "

+ getMethod.getStatusLine());

}

//读取内容

byte[] responseBody = getMethod.getResponseBody();

//处理内容

System.out.println(new String(responseBody));

} catch (HttpException e) {

//发生致命的异常,可能是协议不对或者返回的内容有问题

System.out.println("Please check your provided http address!");

e.printStackTrace();

} catch (IOException e) {

//发生网络异常

e.printStackTrace();

} finally {

//释放连接

getMethod.releaseConnection();

}

}

}


POST方法

根据RFC2616,对POST的解释如下:POST方法用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它当作请求队列 (Request-Line)中请求URI所指定资源的附加新子项。POST被设计成用统一的方法实现下列功能:

  • 对现有资源的注释(Annotation of existing resources)
  • 向电子公告栏、新闻组,邮件列表或类似讨论组发送消息
  • 提交数据块,如将表单的结果提交给数据处理过程
  • 通过附加操作来扩展数据库

调用HttpClient中的PostMethod与GetMethod类似,除了设置PostMethod的实例与GetMethod有些 不同之外,剩下的步骤都差不多。在下面的例子中,省去了与GetMethod相同的步骤,只说明与上面不同的地方,并以登录清华大学BBS为例子进行说 明。

  • 构造PostMethod之前的步骤都相同,与GetMethod一样,构造PostMethod也需要一个URI参数,在本例中,登录 的地址是http://www.newsmth.net/bbslogin2.php。在创建了PostMethod的实例之后,需要给method实例 填充表单的值,在BBS的登录表单中需要有两个域,第一个是用户名(域名叫id),第二个是密码(域名叫passwd)。表单中的域用类 NameValuePair来表示,该类的构造函数第一个参数是域名,第二参数是该域的值;将表单所有的值设置到PostMethod中用方法 setRequestBody。另外由于BBS登录成功后会转向另外一个页面,但是HttpClient对于要求接受后继服务的请求,比如POST和 PUT,不支持自动转发,因此需要自己对页面转向做处理。具体的页面转向处理请参见下面的"自动转向"部分。代码如下:
    String url = "http://www.newsmth.net/bbslogin2.php";

    PostMethod postMethod = new PostMethod(url);

    // 填入各个表单域的值

    NameValuePair[] data = { new NameValuePair("id", "youUserName"),

    new NameValuePair("passwd", "yourPwd") };

    // 将表单的值放入postMethod中

    postMethod.setRequestBody(data);

    // 执行postMethod

    int statusCode = httpClient.executeMethod(postMethod);

    // HttpClient对于要求接受后继服务的请求,象POST和PUT等不能自动处理转发

    // 301或者302

    if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||

    statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {

    // 从头中取出转向的地址

    Header locationHeader = postMethod.getResponseHeader("location");

    String location = null;

    if (locationHeader != null) {

    location = locationHeader.getValue();

    System.out.println("The page was redirected to:" + location);

    } else {

    System.err.println("Location field value is null.");

    }

    return;

    }


完整的程序代码请参见附件中的test.PostSample





回页首


使用HttpClient过程中常见的一些问题

下面介绍在使用HttpClient过程中常见的一些问题。

字符编码

某目标页的编码可能出现在两个地方,第一个地方是服务器返回的http头中,另外一个地方是得到的html/xml页面中。

  • 在http头的Content-Type字段可能会包含字符编码信息。例如可能返回的头会包含这样子的信息:Content-Type: text/html; charset=UTF-8。这个头信息表明该页的编码是UTF-8,但是服务器返回的头信息未必与内容能匹配上。比如对于一些双字节语言国家,可能服务 器返回的编码类型是UTF-8,但真正的内容却不是UTF-8编码的,因此需要在另外的地方去得到页面的编码信息;但是如果服务器返回的编码不是UTF- 8,而是具体的一些编码,比如gb2312等,那服务器返回的可能是正确的编码信息。通过method对象的getResponseCharSet()方 法就可以得到http头中的编码信息。
  • 对于象xml或者html这样的文件,允许作者在页面中直接指定编码类型。比如在html中会有<meta http-equiv="Content-Type" content="text/html; charset=gb2312"/>这样的标签;或者在xml中会有<?xml version="1.0" encoding="gb2312"?>这样的标签,在这些情况下,可能与http头中返回的编码信息冲突,需要用户自己判断到底那种编码类型应该 是真正的编码。

自动转向

根据RFC2616中对自动转向的定义,主要有两种:301和302。301表示永久的移走(Moved Permanently),当返回的是301,则表示请求的资源已经被移到一个固定的新地方,任何向该地址发起请求都会被转到新的地址上。302表示暂时 的转向,比如在服务器端的servlet程序调用了sendRedirect方法,则在客户端就会得到一个302的代码,这时服务器返回的头信息中 location的值就是sendRedirect转向的目标地址。

HttpClient支持自动转向处理,但是象POST和PUT方式这种要求接受后继服务的请求方式,暂时不支持自动转向,因此如果碰到 POST方式提交后返回的是301或者302的话需要自己处理。就像刚才在POSTMethod中举的例子:如果想进入登录BBS后的页面,必须重新发起 登录的请求,请求的地址可以在头字段location中得到。不过需要注意的是,有时候location返回的可能是相对路径,因此需要对 location返回的值做一些处理才可以发起向新地址的请求。

另外除了在头中包含的信息可能使页面发生重定向外,在页面中也有可能会发生页面的重定向。引起页面自动转发的标签是:<meta http-equiv="refresh" content="5; url=http://www.ibm.com/us">。如果你想在程序中也处理这种情况的话得自己分析页面来实现转向。需要注意的是,在上面那 个标签中url的值也可以是一个相对地址,如果是这样的话,需要对它做一些处理后才可以转发。

处理HTTPS协议

HttpClient提供了对SSL的支持,在使用SSL之前必须安装JSSE。在Sun提供的1.4以后的版本中,JSSE已经集成到 JDK中,如果你使用的是JDK1.4以前的版本则必须安装JSSE。JSSE不同的厂家有不同的实现。下面介绍怎么使用HttpClient来打开 Https连接。这里有两种方法可以打开https连接,第一种就是得到服务器颁发的证书,然后导入到本地的keystore中;另外一种办法就是通过扩 展HttpClient的类来实现自动接受证书。

方法1,取得证书,并导入本地的keystore:

  • 安装JSSE (如果你使用的JDK版本是1.4或者1.4以上就可以跳过这一步)。本文以IBM的JSSE为例子说明。先到IBM网站上下载JSSE的安装包。然后解 压开之后将ibmjsse.jar包拷贝到<java-home>"lib"ext"目录下。
  • 取得并且导入证书。证书可以通过IE来获得:

    1. 用IE打开需要连接的https网址,会弹出如下对话框:



    2. 单击"View Certificate",在弹出的对话框中选择"Details",然后再单击"Copy to File",根据提供的向导生成待访问网页的证书文件



    3. 向导第一步,欢迎界面,直接单击"Next",



    4. 向导第二步,选择导出的文件格式,默认,单击"Next",



    5. 向导第三步,输入导出的文件名,输入后,单击"Next",



    6. 向导第四步,单击"Finish",完成向导



    7. 最后弹出一个对话框,显示导出成功



  • 用keytool工具把刚才导出的证书倒入本地keystore。Keytool命令在<java-home>"bin "下,打开命令行窗口,并到<java-home>"lib"security"目录下,运行下面的命令:

    keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer


    其中参数alias后跟的值是当前证书在keystore中的唯一标识符,但是大小写不区分;参数file后跟的是刚才通过IE导出的证 书所在的路径和文件名;如果你想删除刚才导入到keystore的证书,可以用命令:

    keytool -delete -keystore cacerts -storepass changeit -alias yourEntry1


  • 写程序访问https地址。如果想测试是否能连上https,只需要稍改一下GetSample例子,把请求的目标变成一个https地 址。
    GetMethod getMethod = new GetMethod("https://www.yourdomain.com");


    运行该程序可能出现的问题:

    1. 抛出异常java.net.SocketException: Algorithm SSL not available。出现这个异常可能是因为没有加JSSEProvider,如果用的是IBM的JSSE Provider,在程序中加入这样的一行:

     if(Security.getProvider("com.ibm.jsse.IBMJSSEProvider") == null)

    Security.addProvider(new IBMJSSEProvider());


    或者也可以打开<java-home>"lib"security"java.security,在行

    security.provider.1=sun.security.provider.Sun

    security.provider.2=com.ibm.crypto.provider.IBMJCE


    后面加入security.provider.3=com.ibm.jsse.IBMJSSEProvider

    2. 抛出异常java.net.SocketException: SSL implementation not available。出现这个异常可能是你没有把ibmjsse.jar拷贝到<java-home>"lib"ext"目录下。

    3. 抛出异常javax.net.ssl.SSLHandshakeException: unknown certificate。出现这个异常表明你的JSSE应该已经安装正确,但是可能因为你没有把证书导入到当前运行JRE的keystore中,请按照前 面介绍的步骤来导入你的证书。

方法2,扩展HttpClient类实现自动接受证书

因为这种方法自动接收所有证书,因此存在一定的安全问题,所以在使用这种方法前请仔细考虑您的系统的安全需求。具体的步骤如下:

  • 提供一个自定义的socket factory(test.MySecureProtocolSocketFactory)。这个自定义的类必须实现接口 org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory,在实现接口 的类中调用自定义的X509TrustManager(test.MyX509TrustManager),这两个类可以在随本文带的附件中得到
  • 创建一个org.apache.commons.httpclient.protocol.Protocol的实例,指定协议名称和默认 的端口号
    Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);


  • 注册刚才创建的https协议对象
    Protocol.registerProtocol("https ", myhttps);


  • 然后按照普通编程方式打开https的目标地址,代码请参见test.NoCertificationHttpsGetSample

处理代理服务器

HttpClient中使用代理服务器非常简单,调用HttpClient中setProxy方法就可以,方法的第一个参数是代理服务器地 址,第二个参数是端口号。另外HttpClient也支持SOCKS代理。


httpClient.getHostConfiguration().setProxy(hostName,port);






回页首


结论

从上面的介绍中,可以知道HttpClient对http协议支持非常好,使用起来很简单,版本更新快,功能也很强大,具有足够的灵活性和扩 展性。对于想在Java应用中直接访问http资源的编程人员来说,HttpClient是一个不可多得的好工具。



参考资料

  • Commons logging包含了各种各样的日志API的实现,读者可以通过站点http://jakarta.apache.org/commons /logging/得到详细的内容

  • Commons codec包含了一些一般的解码/编码算法。包含了语音编码、十六进制、Base64和URL编码等,通过http: //jakarta.apache.org/commons/codec/可以得到详细的内容

  • rfc2616是关于 HTTP/1.1的文档,可以在http://www.faqs.org/rfcs/rfc2616.html上得到详细的内容,另外rfc1945是关 于HTTP/1.0的文档,通过http://www.faqs.org/rfcs/rfc1945.html可以得到详细内容

  • SSL――SSL 是由 Netscape Communications Corporation 于 1994 年开发的,而 TLS V1.0 是由 Internet Engineering Task Force(IETF)定义的标准,它基于 SSL V3.0,并且在使用的加密算法上与其有些许的不同。例如,SSL 使用 Message Authentication Code(MAC)算法来生成完整性校验值,而 TLS 应用密钥的 Hashing for Message Authentication Code(HMAC)算法。

  • IBM JSSE提供了SSL(Secure Sockets Layer)和TLS(Transport Layer Security)的java实现,在http://www-03.ibm.com/servers/eserver/zseries/software /java/jsse.html中可以得到详细的信息

  • Keytool是一个管理密钥和证书的工具。关于它详细的使用信 息可以在http://www.doc.ic.ac.uk/csg/java/1.3.1docs/tooldocs/solaris /keytool.html上得到

  • HTTPClient的主页是http://jakarta.apache.org /commons/httpclient/,你可以在这里得到关于HttpClient更加详细的信息
posted @ 2010-04-09 14:38 小菜毛毛 阅读(805) | 评论 (0)编辑 收藏

http://update1.aptana.org/studio/3.2/024747/index.html
在以上网址中可以下载插件或者在线安装插件:

End of Life Aptana Studio 1.2

This update site is for Aptana Studio 1.2 users. There is already a newer version of Aptana Studio available. Please check it out at http://aptana.org/studio/download

Aptana Studio 3.2 and 3.3 Update Site

This site is designed to be used inside Eclipse 3.2 or manually update an old version of Aptana Studio. If you have Aptana Studio installed, it is recommended you use the internal update mechanism available via the Help menu => Check for Aptana Updates...

Install Aptana Studio as a Plugin

For Eclipse 3.2 or Eclipse 3.3

If you're already familiar with installing plugins from Eclipse, you can use this URL for the update site:
http://update.aptana.com/update/studio/3.2
For detailed instructions click here.

For Eclipse 3.4

For Eclipse 3.4 installation instructions click here

From a Local File

  1. Save the above file to an easy to find location.
  2. Open Eclipse, and go to Help > Software Updates > Find and Install
  3. Search for new features to install, then click "Next" then choose "New Archived Site". Choose the file you saved in step 1.
  4. Select the appropriate plugins to install, then click "Next", accept the license agreements, and click "Next" again.
  5. Click "Change location". If no appropriate location is already available, click "Add Location" and choose something like "D:"dev"extensions"pluginname" or "extesnions"aptana".
  6. Click "Finish".

Update Aptana Studio Standalone from a Local File

  1. Save the above file to an easy-to-find location, preferably in the root of your drive.
  2. Unzip the file into a folder.
  3. Make sure fix_policy.sh (OS X and Linux) or fix_policy.vbs (Windows) is executable
  4. Run fix_policy.sh (OS X and Linux) or fix_policy.vbs (Windows)
  5. Open policy_url.txt and copy the URL into your clipboard.
  6. Open Aptana Studio, and go to Window > Preferences > Install/Update
  7. Paste the URL from policy_url.txt (something similar to file:///path/to/policy.xml) into the Policy URL field
  8. Click "OK".
  9. Go to Help > Check for Aptana Studio Updates now...
  10. In the "Updates" window, check the box next to the name of the plug-in, and click the "Next" button.
  11. Choose the option to accept the terms of the license agreement, and click the "Next" button.
  12. Click the "Finish" button.
  13. Click the "Install All" button.
如果按照以上方法安装有冲突,即可将其下载的插件解压(比如我解压到D:/myeclipse6.0.1/eclipse/aptana_update_3.3),并把对应的文件复制features和plugins,并在D:/myeclipse6.0.1/eclipse/links目录下新建aptana.link文件,并编辑:path=D:\\myeclipse6.0.1\\eclipse\\aptana_update_3.3
解决开启后报错java.lang.NullPointerException的问题
      开启后弹出对话框报错java.lang.NullPointerException,点击details,他报错:

java.lang.NullPointerException
at com.aptana.ide.xul.FirefoxBrowser.createControl(FirefoxBrowser.java:314)
at com.aptana.ide.server.portal.ui.MyAptanaEditor.createPartControl(MyAptanaEditor.java:261)
at org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:596)
........... 省略.............

      这时,虽我已经安装了firefox,但还是要选择windows->Preferences->My Aptana/Message Center-> "Use Firefox as the Aptana Home Page Browser",去掉勾子就解决了,My Aptana的庐山真面目就欣赏到了

posted @ 2010-04-08 10:40 小菜毛毛 阅读(2773) | 评论 (0)编辑 收藏

   * struts1.2和webwork的区别
    * hibernate和ibatis的区别
    * spring工作机制,IOC容器
    * servlet的一些相关问题
    * webservice相关
    * java基础:jvm,HashSet等等
    * 考察学习新技术的能力
posted @ 2010-04-08 09:37 小菜毛毛 阅读(602) | 评论 (0)编辑 收藏

仅列出标题
共17页: First 上一页 3 4 5 6 7 8 9 10 11 下一页 Last