java 静态变量/方法

java 静态变量/方法 有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static 成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main() ,所以它被声明为static。 声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量。声明为static的方法有以下几条限制: · 它们仅能调用其他的static 方法。 · 它们只能访问static数据。 · 它们不能以任何方式引用this 或super (关键字super 与继承有关,在下一章中描述) 。 如果你需要通过计算来初始化你的static变量,你可以声明一个static块,Static 块仅在该类被加载时执行一次。下面的例子显示的类有一个static方法,一些static变量,以及一个static 初始化块: // Demonstrate static variables,methods,and blocks. class UseStatic { static int a = 3; static int b; static void meth(int x) { System.out.println(“x = " + x); System.out.println(“a = " + a); System.out.println(“b = " + b); } static { System.out.println(“Static block initialized.”); b = a * 4; } public static void main(String args[]) { meth(42); } } 一旦UseStatic 类被装载,所有的static语句被运行。首先,a被设置为3,接着static 块执行(打印一条消息),最后,b被初始化为a*4 或12。然后调用main(),main() 调用meth() ,把值42传递给x。3个println ( ) 语句引用两个static变量a和b,以及局部变量x 。 ...

2012-06-28 · 2 min · 289 words · -

CAP, BASE

CAP, BASE CAP定理, CAP theorem 1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标。 C, Consistency, 一致性 A, Availability, 可用性 P, Partition tolerance, 分区容忍性 CAP理论是分布式架构中重要理论, 它指出对于一个分布式计算系统来说,不可能同时满足CAP三点 CAP理论主张任何基于网络的数据共享系统,都最多只能拥有以下三条中的两条: 一致性, Consistency, C 所有节点访问同一份最新的数据副本;一致性(Consistency) (所有节点在同一时间具有相同的数据) Consistency 中文叫做"一致性"。意思是,写操作之后的读操作,必须返回该值。 多个副本之间的一致性 在分布式系统中的所有数据备份,在同一时刻是否同样的值。 (等同于所有节点访问同一份最新的数据副本) 复制是导致出现数据一致性问题的唯一原因。 如果只用一台数据库来处理所有的写入和读取请求,就一定不存在数据一致性的问题。 但在中大型项目中,我们却经常需要将一份数据存储在超过一台数据库中 (即复制) ,原因有三: 即使一部分数据库出现故障,系统也能正常工作 (高可用) 使数据与用户在地理上接近 (降低延迟) 扩展可以处理读请求的机器数量 (可扩展性、提高读取吞吐量) 可用性, Availability, A 对数据更新具备高可用性 (A) ;(保证每个请求不管成功或者失败都有响应) 意思是只要收到用户的请求,服务器就必须给出回应。 每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据 在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。 (对数据更新具备高可用性) 分区容忍/分区容错性, Partition tolerance, P (系统中任意信息的丢失或失败不会影响系统的继续运作) 大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区 (partition) 。分区容错的意思是,区间通信可能失败。比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信。 一般来说,分区容错无法避免,因此可以认为 CAP 的 P 总是成立。CAP 定理告诉我们,剩下的 C 和 A 无法同时做到。 ...

2012-06-28 · 1 min · 162 words · -

事务, transaction

事务, transaction TRANSACTION(事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。 数据库事务通常包含了一个序列的对数据库的读/写操作。包含有以下两个目的: 为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。 事务的属性: 原子性, 一致性, 隔离性, 持久性, ACID 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。 事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。事务应该具有 4 个属性: 原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。 分布式事务 分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。例如在大型电商系统中,下单接口通常会扣减库存、减去优惠、生成订单 id, 而订单服务与库存、优惠、订单 id 都是不同的服务,下单接口的成功与否,不仅取决于本地的 db 操作,而且依赖第三方系统的结果,这时候分布式事务就保证这些操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。 一致性 Consistency 其实只有两类数据一致性,强一致性与弱一致性。强一致性也叫做线性一致性,除此以外,所有其他的一致性都是弱一致性的特殊情况。所谓强一致性,即复制是同步的,弱一致性,即复制是异步的。 强一致性 任何一次读都能读到某个数据的最近一次写的数据。系统中的所有进程,看到的操作顺序,都和全局时钟下的顺序一致。简言之,在任意时刻,所有节点中的数据是一样的。 弱一致性 数据更新后,如果能容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。 最终一致性 不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化。简单说,就是在一段时间后,节点间的数据会最终达到一致状态 事务处理过程中,会有短暂不一致的情况,但通过恢复系统,可以让事务的数据达到最终一致的目标。 最终一致性要求系统中数据副本最终能够一致,而不需要实时保证数据副本一致。例如,银行系统中的非实时转账操作,允许 24 小时内用户账户的状态在转账前后是不一致的,但 24 小时后账户数据必须正确。 最终一致性是 BASE 原理的核心,也是 NoSQL 数据库的主要特点,通过弱化一致性,提高系统的可伸缩性、可靠性和可用性。而且对于大多数 Web 应用,其实并不需要强一致性,因此牺牲一致性而换取高可用性,是多数分布式数据库产品的方向。 重试 重试机制可以使分布式不一致数据自动恢复,前提是重试接口要提供幂等保证。重试机制是达成分布式最终一致性的重要手段。例如,超时重传是TCP协议保证数据可靠性的一个重要机制,核心思想其实就是重试。 同步重试 : 在上次请求失败或超时,程序再次发起同步调用请求。后端程序不推荐同步重试,其一因为同步等待占用系统线程资源,其二因为重试引起的流量放大,可能导致系统雪崩。 异步重试 : 通过异步系统(消息队列或调度中间件)对失败或超时请求再次发起调用。推荐这种方式的重试,重试的时间间隔可以设置为根据重试次数指数增长,超过重试阈值仍未成功,可以报警通知并由人工订正。 重试也是提高系统可用性的一种有效手段。如果一个服务的可用性为98%(有1个9),1次重试之后其可用性可达到99.96%(3个9),2次重试可以达到99.9992%(5个9)。 幂等 幂等的数学定义为 f(f(x)) = f(x) 用通俗的话来说就是 : 相同的操作执行多次 和 执行一次产生的效果是一样的。有的操作是天然幂等的,如查询、删除操作。有的操作是人为使其幂等,例如TCP的超时重传操作就是幂等的,无论客户端将一个seq字节传送多少次,服务端窗口只会用一次该字节。 ...

2012-06-28 · 1 min · 123 words · -

java 数字格式化 补0

java 数字格式化 补0 DecimalFormat df = new DecimalFormat(“0000000”); System.out.println(df.format(1)); output: 0000001

2012-06-26 · 1 min · 11 words · -

Linux网络协议分析工具tcpdump和tshark用法

Linux网络协议分析工具tcpdump和tshark用法 Tcpdump是网络协议分析的基本工具。tshark是大名鼎鼎的开源网络协议分析工具wireshark (原名叫ethereal) 的命令行版本,wireshark可对多达千余种网络协议进行解码分析。Wireshark 和 tcpdump 均使用libpcap 库 (参见 libpcap 编程教程) 进行网络截包。 TCPDUMP 详细manpage参见tcpdump网站。 基本用法 Tcpdump的参数基本分为两块:选项 (options) 和过滤器表达式 (filter_expression) 。 # tcpdump [options] [filter_expression] 例如 # tcpdump -c 100 -i eth0 -w log tcp dst port 50000 其中 options部分参数: -c 100 指定截取的包的数量 -i eth0 指定监听哪个网络端口 -w log 输出到名为log的文件中 (libpcap格式) filter_expression参数为 tcp dst port 50000,即只监听目标端口为50000的tcp包。 更多的例子: /* 监视目标地址为除内网地址(192.168.3.1-192.168.3.254)之外的流量 */ tcpdump dst net not 192.168.3.0/24 /* 监视除HTTP浏览 (端口80/8080) 、SSH(22)、 POP3 (110)之外的流量,注意在括号(之前添加转义符, -n和-nn的解释见随后 */ ...

2012-06-25 · 3 min · 566 words · -

二分法, binary search algorithm

二分法, binary search algorithm 二分法 一,学习别人的总结与讲解 本部分的参考见末尾,本部分文字是在其基础上的二度总结 (节约时间和精力)。 典型的二分法 算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。 基本思想:假设数据是按升序排序的,对于给定值key,从序列的中间位置k开始比较, 如果当前位置arr[k]值等于key,则查找成功; 若key小于当前位置值arr[k],则在数列的前半段中查找,arr[low,mid-1]; 若key大于当前位置值arr[k],则在数列的后半段中继续查找arr[mid+1,high], 直到找到为止,时间复杂度:O(log(n))。 上面的思想就是最最简单的二分法,即从一个排好序的数组之查找一个key值。 如下面的程序: int search(int *arr, int n, int key) { int left = 0, right = n-1; while(left<=right) { //慎重截止条件,根据指针移动条件来看,这里需要将数组判断到空为止 int mid = left + ((right - left) >> 1); //防止溢出 if (arr[mid] == key) //找到了 return mid; else if(arr[mid] > key) right = mid - 1; //给定值key一定在左边,并且不包括当前这个中间值 else left = mid + 1; //给定值key一定在右边,并且不包括当前这个中间值 } return -1; } 证明二分算法正确性 循环不变式: 如果key存在于数组中,始终只可能存在于当前的array[left,right]数组段中。 初始化: 第一轮循环开始之前,array[left,right]就是原始数组,这时循环不变式显然成立。 迭代保持: 每次循环开始前,如果key存在,则只可能在待处理数组array[left, ..., right]中。 对于array[mid]<key,array[left, ..., mid]均小于key,key只可能存在于array[mid+1, ..., right]中; 对于array[mid]>key,array[mid, ..., right]均大于key,key只可能存在于array[left, ..., mid-1]中; 对于array[mid]==key,查找到了key对应的下标,直接返回结果。 显然如果没找到key,下一次继续查找时我们设定的循环不变式依然正确。 死循环否?在前两种情况中,数组长度每次至少减少1 (实际减少的长度分别是mid-left+1和right-mid+1),直到由left==right变为left>right (数组段长度由1-0)—>截止了,所以一定不会死循环。 终止: 结束时发生了什么?left>right,被压缩的数组段为空,表示key不存在于所有步骤的待处理数组,再结合每一步排除的部分数组中也不可能有key,因此key不存在于原数组。因此我们得到了符合要求的解,此算法正确。 如果条件稍微变化一下,还会写吗?其实,二分法真的不那么简单,尤其是二分法的各个变种。 二分法的变种1 数组之中的数据可能可以重复,要求返回匹配的数据的最小 (或最大)的下标;更近一步,需要找出数组中第一个大于key的元素 (也就是最小的大于key的元素的)下标,等等。 这些,虽然只有一点点的变化,实现的时候确实要更加的细心。 下面列出了这些二分检索变种的实现 a. 找出第一个与key相等的元素的位置 快速思考四个问题: 1)通过什么条件来移动两个指针?与中间位置进行大小比较。 当arr[mid]<key时,当前位置一定不是解,解一定只可能在arr[mid+1,high],即右边 当arr[mid]>key时,当前位置一定不是解,解一定只可能在arr[low,mid-1],即左边 ...

2012-06-25 · 5 min · 867 words · -

X.509

X.509 X.509是ITU-T标准化部门基于他们之前的ASN.1定义的一套证书标准。 它是为了解决X.500目录中的身份鉴别和访问控制问题而设计的。在X.509标准的早期版本中,除了最基本的组件——CA、证书持有者和依赖方外,只涉及了资料库。由于X.509标准是为X.500目录服务的,所以,资料库的形式就是X.500目录。在后来的X.509标准版本中,又增加了CRL Issuer组件。在X.509标准中,使用大量的篇幅来定义证书和CRL的数据格式。目前,使用最广泛、最成功的证书和CRL格式,都是X.509标准定义的格式。 原文连接: http://www.cnblogs.com/bjrmt/archive/2006/08/17/479728.html 在和CA进行一些接触时,我们常常会听到一个名词: X.509。它是一种行业标准或者行业解决方案,在X.509方案中,默认的加密体制是公钥密码体制。为进行身份认证,X.509标准及公共密钥加密系统提供了数字签名的方案。用户可生成一段信息及其摘要(亦称作信息"指纹")。用户用专用密钥对摘要加密以形成签名,接收者用发送者的公共密钥对签名解密,并将之与收到的信息"指纹"进行比较,以确定其真实性。 此问题的解决方案即X.509标准与公共密钥证书。本质上,证书由公共密钥加密钥拥有者的用户标识组成,整个字块有可信赖的第三方签名。典型的第三方即大型用户群体(如政府机关或金融机构)所信赖的CA。 此外,X.509标准还提供了一种标准格式CRL,下面我们就来看一看 X.509标准下的证书格式极其扩展。 目前X.509有不同的版本,例如 X.509 V2和x.509 v3都是目前比较新的版本,但是都在原有版本 (X.509 V1) 的基础上进行功能的扩充,其中每一版本必须包含下列信息: (1) 版本号 (2) 序列号; (3) 签名算法标识符 (4) 认证机构 (5) 有效期限 (6) 主题信息 (7) 认证机构的数字签名 (8) 公钥信息 版本号: 用来区分X.509的不同版本号 序列号; 由CA给予每一个证书的分配唯一的数字型编号,当证书被取消时,实际上是将此证书的序列号放入由CA签发的CRL中;这也是序列号唯一的原因。 签名算法标识符: 用来指定用CA签发证书时所使用的签名算法。算法标识符用来指定CA签发证书时所使用的公开密钥算法和HASH算法,须向国际指明标准组织 (如ISO) 注册。 认证机构: 即发出该证书的机构唯一的CA的x.500名字; 有效期限: 证书有效的时间包括两个日期: 证书开始生效期和证书失效的日期和时间。在所指定的这两个时间之间有效; 主题信息: 证书持有人的姓名、服务处所等信息; 认证机构的数字签名: 以确保这个证书在发放之后没有被撰改过; 公钥信息: 包括被证明有效的公钥值和加上使用这个公钥的方法名称; X.509的扩展 (V3) X.509标准第三版在V2的基础上进行了扩展,V3引进一种机制。这种机制允许通过标准化和类的方式将证书进行扩展包括额外的信息,从而适应下面的一些要求一: (1) 一个证书主体可以有多个证书; (2) 证书主体可以被多个组织或社团的其他用户识别; (3) 可按特定的应用名 (不是X.500名) 识别用户,如将公钥同EMAIL地址联系起来; (4) 在不同证书政策和实用下会发放不同的证书,这就要求公钥用户要信赖证书;证书并不限于这些标准扩展,任何人都可以向适当的权利机构注册一种扩展。将来会有更多的适于应用的扩展列入标准扩展集中。值得注意的是这种扩展机制应该是完全可以继承的。 每一种扩展包括三个域: 类型、可否缺省、值 类型字段定义了扩展值字段中的数据类型。这个类型可以是简单的字符串,数值,日期,图片或一个复杂的数据类型。为便于交互,所有的数据类型都应该在国际知名组织进行注册。 是否可缺省字段是一比特标识位。当一扩展标识为不可缺省时,说明相应的扩展值非常重要,应用程序不能忽略这个信息。如果使用一特殊证书的应用程序不能处理该字段的内容,就应该拒绝此证书。 扩展值字段包含了这个扩展实际的数据。 ...

2012-06-24 · 1 min · 212 words · -

公钥基础设施/PKI

公钥基础设施/PKI https://zhuanlan.zhihu.com/p/30136885 前言 Public Key Infrastructure (PKI),中文叫做公开密钥基础设施,也就是利用公开密钥机制建立起来的基础设施。但是如果这么解释起来,到底是个什么东西,大家想必是没办法理解的。 现在大家的很多重要活动都是通过网络进行的,那么与之俱来的安全问题就显得非常重要。同时很多安全保障机制都是基于PKI的,如果你因为各种原因 (考试?提案?好奇?)想知道各种PKI是什么。那么通过这篇文章,绝对让你5分钟知道什么是PKI。 PKI不好理解的原因是,这个概念包括了很多不同的技术和知识,同时又因为这个概念很庞大,让人感觉无从下手。但是,这个概念其实没有看起来那么复杂,让我们开始说明吧! 第1分钟 - PKI的核心是身份证明书的发行 PKI的主要目的是用来发行“身份证明书”,网络上因为大家不能见面,所以伪造身份是非常容易的事情。因为要在网络上验明正身,所以这个网络身份证明书就变得很重要了。 相互通信的时候,如果能相互确认身份证明书,那么我们就知道自己是在跟对的人通信。 但是,自己做的身份证明书是不能拿来作为证明的,就像生活中,如果公民身份证可以私人合法制作的话,那么身份证也就没啥可信度了。网络世界中,我们需要一个信得过的发证机关来发行身份证明书,同时自己要好好保管自己的身份证明书,就像派出所给你发了公民身份证,自己要好好保管一样。 PKI的世界里,这个身份证明书,被叫做“证明书”。发行“证明书”的机关叫做“认证机关”。还有一个就是统一管理证明书的证书“档案库”。这三个东西加起来,就是PKI的主要构成要素。 第2分钟 - 构成PKI的要素只有三个 就像之前提到的,一般来说,构成PKI的主要要素就是下面三个概念 证明书 认证机关 证书库 说到底,PKI指的是证明书的制作和分发的一种机制。在这个机制的保障前提下,进行可信赖的网络通信。即安全的网路通信保障机制。 实际上,证明书是被存放在硬盘或者IC卡里面的。证明书的文件构造是一种叫做 X.509 的协议规定的。另一方面,认证机关也其实就是一个网络应用程序。 证书库因为某些原因,其实也就是文件系统而已,在网络上将证书存放在一起。这些东西,可以通过下载来获取。或者,因为某些原因,证书直接分发,从而省去了证书库这个环节。 第3分钟 - 证明书里面的密钥 一旦利用了证明书确认了身份的同时,通信的加密也就可以实现了。为什么呢?证明书里面包含了用来加密的密钥。 比如说,你要和一个自称比尔的男人通信。这个自称比尔的男人,会在通信的最开始,通过网络将证明书发给你,那么通过这个证明书,就证实了他就是比尔。 然后,你用这个“证明书中的密钥”,将你要发送给比尔的内容进行加密,然后发送给比尔。 用“证明书中的密钥”加密过的内容,只能用比尔自己才有的另一个“私人的密钥”才能解密。这样的话,如果你发送给比尔的内容被他人窃取的话,他人也无法解密。 只要比尔自己好好保管好自己才有的“私人的密钥”,那么如果有人拿着比尔的“证明书中的密钥”想要胡作非为的话,那就是不可能的。因为用“证明书中的密钥”加密过的内容,只有比尔自己才有的“私人的密钥”才能解密。 所以这么一来,PKI提供的证明书可以用来 身份确认 和 通信加密。同时实现了这两个重要的功能。 第4分钟 - 什么是“公开密钥”,什么是“私有密钥” 对于比尔来说,只要保证本人的那个“私人的密钥”不被盗走,包含在“证明书里的密钥”给多少人都没有关系。也就是说,想跟比尔通信的人,必须要有比尔的证明书,要用比尔“证明书里的密钥”对通信内容进行加密。为了能让其他人可以方便的获取比尔的证明书,证书库就显得有必要了。 在PKI机制中,放在“证明书里面的密钥”可以被任意自由分发,这里的“证明书里的密钥”被叫做“公开密钥 (Public Key)”。与此相对,本人保管的那个“私人的密钥”就要做“私有密钥 (Private Key)”。 就像前文提到的,公开密钥是放在证明书里面的,所有用什么样的方式去分发证明书都没有关系。放到U盘里给别人,或者放到网上让人任意下载,或者用邮件发送,都是可以的。 第5分钟 - “拿什么去信任你?我的证明书” 先前说到,用包含在证明书里的公开密钥去给通信内容加密,这个过程大家已经知道。但是PKI提供的证明书真的可以被信任吗?说到底,证明书也就是普通的文件而已。不像货币那样,本身有着特殊的材质或者物理上的防伪措施。 这么想是完全对的,因为实际上,认证机关所用的证书生成器说到底也就是一个软件而已,如果搞到这个软件,谁都可以发行证明书。所以说,在技术上,伪造证明书是非常简单的。所谓假的证明书,比如说有一个所谓的“比尔的证明书”,但是里面含有的公开密钥是史提芬的公开密钥。那么,别人发给比尔的信息,史蒂芬可以解密,反而比尔自己不能解密。 这样看来,这个认证机关就至关重要了,认证机关的可信度,直接与证书的可信度挂钩,也就是与整个PKI机制的可信度息息相关。 关于认证机关的权威性和可信度的问题,其实是一个社会基础设施建设的话题了。 在很多国家认证机关都是由政府在主导建设,常常被视作一个社会性基础设施的一个环节。如同建设各种社会机构,比如医院,银行,学校等等。 (译者案:日本关于这些基础概念的文章都写的非常通俗易懂,如何去让小白都可以去理解一个非常复杂的概念,这是日本人写技术文章特别专注的,很值得大家学习) https://nicholaslee119.github.io/ https://atmarkit.itmedia.co.jp/ait/articles/0102/17/news003.html

2012-06-24 · 1 min · 62 words · -

OAuth2.0

OAuth2.0 http://baike.baidu.com/view/6619164.htm OAuth 1.0已经在IETF尘埃落定,编号是RFC5894 这也标志这OAuth已经正式成为互联网标准协议。 OAuth 2.0早已经开始讨论和建立的草案。OAuth2.0 很可能是下一代的"用户验证和授权"标准。现在百度开放平台,腾讯开放平台等大部分的开放平台都是使用的OAuth 2.0协议作为支撑。 OAuth (开放授权) 是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源 (如照片,视频,联系人列表) ,而无需将用户名和密码提供给第三方应用。 OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站 (例如,视频编辑网站)在特定的时段 (例如,接下来的2小时内) 内访问特定的资源 (例如仅仅是某一相册中的视频) 。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。 OAuth是OpenID的一个补充,但是完全不同的服务。 OAuth 2.0 是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。规范还在IETF OAuth工作组的开发中,按照Eran Hammer-Lahav的说法,OAuth将于2010年末完成。 Facebook的新的Graph API只支持OAuth 2.0,Google在2011年3月亦宣布Google API对OAuth 2.0的支援。 认证和授权过程 在认证和授权的过程中涉及的三方包括: 1、服务提供方,用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。 2、用户,存放在服务提供方的受保护的资源的拥有者。 3、客户端,要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站。在认证过程之前,客户端要向服务提供者申请客户端标识。 使用OAuth进行认证和授权的过程如下所示: 用户访问客户端的网站,想操作用户存放在服务提供方的资源。 客户端向服务提供方请求一个临时令牌。 服务提供方验证客户端的身份后,授予一个临时令牌。 客户端获得临时令牌后,将用户引导至服务提供方的授权页面请求用户授权。在这个过程中将临时令牌和客户端的回调连接发送给服务提供方。 用户在服务提供方的网页上输入用户名和密码,然后授权该客户端访问所请求的资源。 授权成功后,服务提供方引导用户返回客户端的网页。 客户端根据临时令牌从服务提供方那里获取访问令牌。 服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌。 客户端使用获取的访问令牌访问存放在服务提供方上的受保护的资源。 简单历史回顾 OAuth 1.0在2007年的12月底发布并迅速成为工业标准。 2008年6月,发布了OAuth 1.0 Revision A,这是个稍作修改的修订版本,主要修正一个安全方面的漏洞。 2010年四月,OAuth 1.0的终于在IETF发布了,协议编号RFC 5849。 OAuth 2.0的草案是在今年5月初在IETF发布的。 OAuth is a security protocol that enables users to grant third-party access to their web resources without sharing their passwords. OAuth是个安全相关的协议,作用在于,使用户授权第三方的应用程序访问用户的web资源,并且不需要向第三方应用程序透露自己的密码。 OAuth 2.0是个全新的协议,并且不对之前的版本做向后兼容,然而,OAuth 2.0保留了与之前版本OAuth相同的整体架构。 这个草案是围绕着 OAuth2.0的需求和目标,历经了长达一年的讨论,讨论的参与者来自业界的各个知名公司,包括Yahoo!, Facebook, Salesforce, Microsoft, Twitter, Deutsche Telekom, Intuit, Mozilla, and Google。 OAuth 2.0的新特性: 6种全新的流程: User-Agent Flow – 客户端运行于用户代理内 (典型如web浏览器) 。 Web Server Flow – 客户端是web服务器程序的一部分,通过http request接入,这是OAuth 1.0提供的流程的简化版本。 Device Flow – 适用于客户端在受限设备上执行操作,但是终端用户单独接入另一台电脑或者设备的浏览器 Username and Password Flow – 这个流程的应用场景是,用户信任客户端处理身份凭据,但是仍然不希望客户端储存他们的用户名和密码,这个流程仅在用户高度信任客户端时才适用。 Client Credentials Flow – 客户端适用它的身份凭据去获取access token,这个流程支持2-legged OAuth的场景。 Assertion Flow – 客户端用assertion去换取access token,比如SAML assertion。 可以通过使用以上的多种流程实现Native应用程序对OAuth的支持 (程序运行于桌面操作系统或移动折本) application support (applications running on a desktop or mobile device) can be implemented using many of the flows above. 持信人token OAuth 2.0 提供一种无需加密的认证方式,此方式是基于现存的cookie验证架构,token本身将自己作为secret,通过HTTPS发送,从而替换了通过 HMAC 和token secret加密并发送的方式,这将允许使用cURL发起APIcall和其他简单的脚本工具而不需遵循原先的request方式并进行签名。 ...

2012-06-24 · 1 min · 182 words · -

su, sudo

su, sudo sudo 免密码 # change visudo editor sudo update-alternatives --config editor sudo visudo # 或 sudo vim /etc/sudoers.d/00_wiloon wiloon ALL=(ALL) NOPASSWD: ALL 注意: 有的时候你的将用户设了 nopasswd, 但是不起作用,原因是被后面的 group 的设置覆盖了,需要把 group 的设置也改为 nopasswd joe ALL=(ALL) NOPASSWD: ALL %admin ALL=(ALL) NOPASSWD: ALL https://www.cnblogs.com/itech/archive/2009/08/07/1541017.html https://askubuntu.com/questions/70534/what-are-the-differences-between-su-sudo-s-sudo-i-sudo-su sudo 提供密码 echo 'password' | sudo -S command #!/bin/bash sudo -S apt-get update << EOF 你的密码 EOF -S 参数的作用 使用 man 命令查询 sudo,对参数 -S 的说明如下: Write the prompt to the standard error and read the password from the standard input instead of using the terminal device. The password must be followed by a newline character. ...

2012-06-23 · 3 min · 583 words · -

adb, no permission

adb, no permission http://www.blogjava.net/brian/articles/316019.html 在ubuntu(9.10)下执行adb devices命令, 返回的结果是: List of devices attached ???????????? no permissions 这意味着,USB连接的设备是能够被识别的。Google之后,得知adb server需要以root的权限启动,于是有了如下命令: brian@brian-laptop:~/Dev/Java/Android/android-sdk-linux_86/tools$ ./adb kill-server brian@brian-laptop:~/Dev/Java/Android/android-sdk-linux_86/tools$ sudo ./adb start-server * daemon not running. starting it now * * daemon started successfully * 第一条命令用来杀死当前正在运行的server, 第二条命令则以root的权限启动了新的server. 我们可以再次查看devices: brian@brian-laptop:~/Dev/Java/Android/android-sdk-linux_86/tools$ ./adb devices List of devices attached HT848KV04386 device 这次设备就被正确识别了。自然地, 像ddms之类的工具也能派上用场了。 如果你的机器不能识别,或不是Ubuntu环境,请参考官方文档:http://developer.android.com/guide/developing/device.html。 insufficient permissions for device If you’re developing on Ubuntu Linux, you need to add a rules file that contains a USB configuration for each type of device you want to use for development. Each device manufacturer uses a different vendor ID. The example rules files below show how to add an entry for a single vendor ID (the HTC vendor ID). In order to support more devices, you will need additional lines of the same format that provide a different value for the SYSFS{idVendor} property. For other IDs, see the table of USB Vendor IDs, below. ...

2012-06-23 · 1 min · 180 words · -

android adb

android adb macos install adb brew install --cask android-platform-tools http://blog.sina.com.cn/s/blog_51335a000101j59n.html 启动adb服务, 该服务用来为模拟器或通过 USB 数据线连接的真机服务, 需要以 root 权限启动, 否则 adb devices 会提示 no permissions. adb kill-server adb start-server 列出已连接的android设备 adb devices 安装apk adb install xxx/xxx.apk adb shell 在SDK的Tools文件夹下包含着Android模拟器操作的重要命令ADB,ADB的全称为Android Debug Bridge,就是调试桥的作用,借助这个工具,我们可以管理设备或手机模拟器的状态 ,还可以进行以下的操作: (1) 快速更新设备或手机模拟器中的代码,如应用或Android系统升级; (2) 在设备上运行Shell命令; (3) 管理设备或手机模拟器上的预定端口; (4) 在设备或手机模拟器上复制或粘贴文件。 ADB的工作方式比较特殊采用监听Socket TCP 5554等端口的方式让IDE和Qemu通信,默认情况下ADB会daemon相关的网络端口,所以当我们运行Eclipse时ADB进程就会自动运行,在Eclipse中通过DDMS来调试Android程序;也可以通过手动方式调用,以下为一些常用的操作供参考。 1.版本信息 D:\unsetup\android-sdk-windows-1.0_r1\tools>adb version Android Debug Bridge version 1.0.20 2.安装应用到模拟器 adb install [-l] [-r] <file> 其中file是需要安装的apk文件的决定路径。 3.卸载已经安装的应用 (1) 方法1: ...

2012-06-23 · 4 min · 680 words · -

java thread id, name

java thread id, name Thread.currendThread().getName() 这个可以返回线程对象的ID 设置线程名 public class Thread3 { public static void main(String[] args){ RunnableTest rt = new RunnableTest(); //定义两个线程,他们引用相同的数据 Thread t1 = new Thread(rt); Thread t2 = new Thread(rt); //设置线程的名字 t1.setName("线程1"); t2.setName("线程2"); //运行后,线程1 和线程2会交替运行 t1.start(); t2.start(); } }

2012-06-22 · 1 min · 41 words · -

HttpSessionBindingListener

HttpSessionBindingListener 捕获Session事件的意义: 记录网站的客户登录日志 (登录,退出信息等) 统计在线人数 等等还有很多,呵呵,自己想吧……总之挺重要的。 Session代表客户的会话过程,客户登录时,往Session中传入一个对象,即可跟踪客户的会话。在Servlet中,传入Session的对象如果是一个实现HttpSessionBindingListener接口的对象 (方便起见,此对象称为监听器) ,则在传入的时候 (即调用HttpSession对象的setAttribute方法的时候) 和移去的时候 (即调用HttpSession对象的removeAttribute方法的时候或Session Time out的时候) Session对象会自动调用监听器的valueBound和valueUnbound方法 (这是HttpSessionBindingListener接口中的方法) 。 由此可知,登录日志也就不难实现了。 另外一个问题是,如何统计在线人数,这个问题跟实现登录日志稍微有点不同,统计在线人数 (及其信息) ,就是统计现在有多少个Session实例存在,我们可以增加一个计数器 (如果想存储更多的信息,可以用一个对象来做计数器,随后给出的实例中,简单起见,用一个整数变量作为计数器) ,通过在valueBound方法中给计数器加1,valueUnbound方法中计数器减1,即可实现在线人数的统计。当然,这里面要利用到ServletContext的全局特性。(有关ServletContext的叙述请参考Servlet规范),新建一个监听器,并将其实例存入ServletContext的属性中,以保证此监听器实例的唯一性,当客户登录时,先判断ServletContext的这个属性是否为空,如果不为空,证明已经创建,直接将此属性取出放入Session中,计数器加1;如果为空则创建一个新的监听器,并存入ServletContext的属性中。 举例说明: 实现一个监听器: // SessionListener.java import java.io.*; import java.util.*; import javax.servlet.http.*; //监听登录的整个过程 public class SessionListener implements HttpSessionBindingListener { public String privateInfo= " “; //生成监听器的初始化参数字符串 private String logString= " “; //日志记录字符串 private int count=0; //登录人数计数器 public SessionListener(String info){ this.privateInfo=info; } public int getCount(){ return count; } public void valueBound(HttpSessionBindingEvent event) ...

2012-06-22 · 2 min · 241 words · -

HttpSessionActivationListener

HttpSessionActivationListener HttpSessionActivationListener jsp/servlet 标准不要求一个web容器支持分布式应用, 但是他一定要支持HttpSessionActivationListener借口,以使代码可以支持分布式环境。 一般免费的web容器都不支持分布式,weblogic websphere是支持的。 为了负载均衡或者fail-over,web容器可以迁移一个session到其他的jvm. session的passivation是指非活动的session被写入持久设备 (比如硬盘) 。 activate自然就是相反的过程。在分布式环境中切换的属性必须实现serializable接口。 一般情况下他和HttpSessionBindingListener一起使用。 比如一个属性类,

2012-06-22 · 1 min · 14 words · -

cookie, session

cookie, session 具体来说cookie机制采用的是在客户端保持状态的方案。它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持。cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力. 而session机制采用的是一种在客户端与服务器之间保持状态的解决方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的。而session提供了方便管理全局变量的方式 session是针对每一个用户的,变量的值保存在服务器上,用一个sessionID来区分是哪个用户session变量,这个值是通过用户的浏览器在访问的时候返回给服务器,当客户禁用cookie时,这个值也可能设置为由get来返回给服务器。 就安全性来说: 当你访问一个使用session 的站点,同时在自己机子上建立一个cookie,建议在服务器端的SESSION机制更安全些.因为它不会任意读取客户存储的信息。 正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie 从网络服务器观点看所有HTTP请求都独立于先前请求。就是说每一个HTTP响应完全依赖于相应请求中包含的信息 状态管理机制克服了HTTP的一些限制并允许网络客户端及服务器端维护请求间的关系。在这种关系维持的期间叫做会话(session)。 Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie规范。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将同一服务器的任何请求缚上这些cookies 理解session机制 session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构 (也可能就是使用散列表) 来保存信息。 当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 – 称为 session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个 session检索出来使用 (如果检索不到,可能会新建一个) ,如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个 session id将被在本次响应中返回给客户端保存。 保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID,而。比如weblogic对于web应用程序生成的cookie,JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是 JSESSIONID。 由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://…../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 另一种是作为查询字符串附加在URL后面,表现形式为http://…../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。 为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。 另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如下面的表单 <form name="testform" action="/xxx"> <input type="text"> </form> 在被传递给客户端之前将被改写成 <form name="testform" action="/xxx"> <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764″> <input type="text"> </form> 这种技术现在已较少应用,笔者接触过的很古老的iPlanet6(SunONE应用服务器的前身)就使用了这种技术。 实际上这种技术可以简单的用对action应用URL重写来代替。 在谈论session机制的时候,常常听到这样一种误解"只要关闭浏览器,session就消失了"。其实可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个 session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。 ...

2012-06-22 · 1 min · 176 words · -

Servlet Session

Servlet Session http://developer.51cto.com/art/200907/134673.htm 本文向您介绍Servlet Session机制,包括会话管理机制、事件监听等,并结合具体的示例讲解了一个基于Servlet Session登陆系统的实现。 一、 Servlet的会话管理机制 HttpSession接口提供了存储和返回标准会话属性的方法。标准会话属性如会话标识符、应用数据等,都以"键-值"对的形式保存。简而言之,HttpSession接口提供了一种把对象保存到内存、在同一用户的后继请求中提取这些对象的标准办法。在会话中保存数据的方法是setAttribute(String s, Object o),从会话提取原来所保存对象的方法是getAttribute(String s)。 每当新用户请求一个使用了HttpSession对象的JSP页面,JSP容器除了发回应答页面之外,它还要向浏览器发送一个特殊的数字。这个特殊的数字称为"会话标识符",它是一个唯一的用户标识符。此后,HttpSession对象就驻留在内存之中,等待同一用户返回时再次调用它的方法。 在客户端,浏览器保存会话标识符,并在每一个后继请求中把这个会话标识符发送给服务器。会话标识符告诉JSP容器当前请求不是用户发出的第一个请求,服务器以前已经为该用户创建了HttpSession对象。此时,JSP容器不再为用户创建新的HttpSession对象,而是寻找具有相同会话标识符的HttpSession对象,然后建立该HttpSession对象和当前请求的关联。 会话标识符以Cookie的形式在服务器和浏览器之间传送。如果客户端不支持cookie,运用url改写机制来保证会话标识符传回服务器。 二、 Servlet Session事件侦听 HttpSessionBindingEvent类 定义 public class HttpSessionBindingEvent extends EventObject 这个事件是在监听到HttpSession发生绑定和取消绑定的情况时连通HttpSessionBindingListener的。这可能是一个session被终止或被认定无效的结果。 事件源是HttpSession.putValue或HttpSession.removeValue。 构造函数 public HttpSessionBindingEvent(HttpSession session, String name); 通过引起这个事件的Session和发生绑定或取消绑定的对象名构造一个新的HttpSessionBindingEvent。 方法 1、getName public String getName(); 返回发生绑定和取消绑定的对象的名字。 2、getSession public HttpSession getSession(); 返回发生绑定和取消绑定的session的名字。 HttpSessionBindingListener接口 定义 public interface HttpSessionBindingListener 这个对象被加入到HTTP的session中,执行这个接口会通告有没有什么对象被绑定到这个HTTP session中或被从这个HTTP session中取消绑定。 方法 1、valueBound public void valueBound(HttpSessionBindingEvent event); 当一个对象被绑定到session中,调用此方法。HttpSession.putValue方法被调用时,Servlet引擎应该调用此方法。 2、valueUnbound public void valueUnbound(HttpSessionBindingEvent event); 当一个对象被从session中取消绑定,调用此方法。HttpSession.removeValue方法被调用时,Servlet引擎应该调用此方法。 Session的事件处理机制与swing事件处理机制不同。Swing采用注册机制,而session没有;当任一session发生绑定或其他事件时,都会触发HttpSessionBindingEvent ,如果servlet容器中存在HttpSessionBindingListener的实现类,则会将事件作为参数传送给session侦听器的实现类。在HttpSessionBindingEvent 中可以通过getsession得到发生绑定和取消绑定的session的名字,而侦听器可以据此做更多处理。 因此,对session的事件侦听,只需实现HttpSessionBindingListener即可。 从servlet2.3增加了 HttpSessionEvent (This is the class representing event notifications for changes to sessions within a web application) HttpSessionActivationListener (Objects that are bound to a session may listen to container events notifying them that sessions will be passivated and that session will be activated.) HttpSessionAttributeListener (This listener interface can be implemented in order to get notifications of changes to the attribute lists of sessions within this web application.) 分别执行不同的任务,处理基本相同。 三、 例子 (zz) 捕获Servlet Session事件的意义: 1、 记录网站的客户登录日志 (登录,退出信息等) 2、 统计在线人数 3、 等等还有很多,呵呵,自己想吧……总之挺重要的。 Session代表客户的会话过程,客户登录时,往Session中传入一个对象,即可跟踪客户的会话。在Servlet中,传入Session的对象如果是一个实现HttpSessionBindingListener接口的对象 (方便起见,此对象称为监听器) ,则在传入的时候 (即调用HttpSession对象的setAttribute方法的时候) 和移去的时候 (即调用HttpSession对象的removeAttribute方法的时候或Session Time out的时候) Session对象会自动调用监听器的valueBound和valueUnbound方法 (这是HttpSessionBindingListener接口中的方法) 。由此可知,登录日志也就不难实现了。 另外一个问题是,如何统计在线人数,这个问题跟实现登录日志稍微有点不同,统计在线人数 (及其信息) ,就是统计现在有多少个Session实例存在,我们可以增加一个计数器 (如果想存储更多的信息,可以用一个对象来做计数器,随后给出的实例中,简单起见,用一个整数变量作为计数器) ,通过在valueBound方法中给计数器加1,valueUnbound方法中计数器减1,即可实现在线人数的统计。当然,这里面要利用到ServletContext的全局特性。(有关ServletContext的叙述请参考Servlet规范),新建一个监听器,并将其实例存入ServletContext的属性中,以保证此监听器实例的唯一性,当客户登录时,先判断ServletContext的这个属性是否为空,如果不为空,证明已经创建,直接将此属性取出放入Session中,计数器加1;如果为空则创建一个新的监听器,并存入ServletContext的属性中。 举例说明: 实现一个监听器: ...

2012-06-22 · 2 min · 343 words · -

HttpSessionListener

HttpSessionListener Session创建事件发生在每次一个新的session创建的时候,类似地Session失效事件发生在每次一个Session失效的时候。 这个接口也只包含两个方法,分别对应于Session的创建和失效: public void sessionCreated(HttpSessionEvent se); public void sessionDestroyed(HttpSessionEvent se); 我的web应用上想知道到底有多少用户在使用? 在网站中经常需要进行在线人数的统计。过去的一般做法是结合登录和退出功能,即当用户输入用户名密码进行登录的时候计数器加1,然后当用户点击退出按钮退出系统的时候计数器减1。这种处理方式存在一些缺点,例如: 用户正常登录后,可能会忘记点击退出按钮,而直接关闭浏览器,导致计数器减1的操作没有及时执行;网站上还经常有一些内容是不需要登录就可以访问的,在这种情况下也无法使用上面的方法进行在线人数统计。 我们可以利用Servlet规范中定义的事件监听器 (Listener) 来解决这个问题,实现更准确的在线人数统计功能。对每一个正在访问的用户,J2EE应用服务器会为其建立一个对应的HttpSession对象。当一个浏览器第一次访问网站的时候,J2EE应用服务器会新建一个HttpSession对象 ,并触发 HttpSession创建事件 ,如果注册了HttpSessionListener事件监听器,则会调用HttpSessionListener事件监听器的sessionCreated方法。相反,当这个浏览器访问结束超时的时候,J2EE应用服务器会销毁相应的HttpSession对象,触发 HttpSession销毁事件,同时调用所注册HttpSessionListener事件监听器的sessionDestroyed方法。 import javax.servlet.http.HttpSessionListener; import javax.servlet.http.HttpSessionEvent; public class SessionCounter implements HttpSessionListener { private static int activeSessions =0; /* Session创建事件 */ public void sessionCreated(HttpSessionEvent se) { ServletContext ctx = event.getSession( ).getServletContext( ); Integer numSessions = (Integer) ctx.getAttribute("numSessions"); if (numSessions == null) { numSessions = new Integer(1); } else { int count = numSessions.intValue( ); numSessions = new Integer(count + 1); } ctx.setAttribute("numSessions", numSessions); } /* Session失效事件 */ public void sessionDestroyed(HttpSessionEvent se) { ServletContext ctx=se.getSession().getServletContext(); Integer numSessions = (Integer)ctx.getAttribute("numSessions"); if(numSessions == null) numSessions = new Integer(0); } else { int count = numSessions.intValue( ); numSessions = new Integer(count - 1); } ctx.setAttribute("numSessions", numSessions); } } 在这个解决方案中,任何一个Session被创建或者销毁时,都会通知SessionCounter 这个类,当然通知的原因是必须在web.xml文件中做相关的配置工作。如下面的配置代码: demo.listener.SessionCounter</listener-class> </listener> 以下两种情况下就会发生sessionDestoryed (会话销毁) 事件: 1.执行session.invalidate()方法时 。 既然LogoutServlet.java中执行session.invalidate()时,会触发sessionDestory()从在线用户 列表中清除当前用户,我们就不必在LogoutServlet.java中对在线列表进行操作了,所以LogoutServlet.java的内容现在是 这样。 ...

2012-06-22 · 1 min · 208 words · -

ServletContextAttributeListener

ServletContextAttributeListener ServletContext context = getServletContext(); context.setAttribute(“attrName”, “attrValue”); import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; public class HelloWorld extends HttpServlet { private static final long serialVersionUID = -9037964452251358377L; public HelloWorld() { System.out.println("servlet.helloWorld.constructor"); } public void init() { System.out.println("servlet.helloWorld.init."); } public void destroy() { System.out.println("servlet.helloWorld.destroy."); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("servlet.helloWorld.doGet.start"); // get, query string String queryString = request.getQueryString(); // header name printHeaderName(request); // get parameter System.out.println("parameter.foo= " + request.getParameter("foo")); // query string System.out.println("query string: " + queryString); // character encoding System.out.println("encoding: " + request.getCharacterEncoding()); //init param System.out.println("init param: " + getInitParameter("ipn")); //set context attribute ServletContext context = getServletContext(); context.setAttribute("attrName", "attrValue"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><head><title>"); out.println("This is my first Servlet"); out.println("</title></head><body>"); out.println("Hello,World!, Servlet!"); out.println("</body></html>"); System.out.println("servlet.helloWorld.doGet.end"); } private void printHeaderName(HttpServletRequest request) { Enumeration enumstr = request.getHeaderNames(); while (enumstr.hasMoreElements()) { String name = (String) enumstr.nextElement(); System.out.println("header: " + name + " = " + request.getHeader(name)); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // post, request form // String form = request.get; } }

2012-06-22 · 1 min · 181 words · -

ServletContextListener

ServletContextListener http://www.cnblogs.com/kentyshang/archive/2007/06/26/795878.html ServletContextListener处理Web应用的 servlet上下文(context)的变化的通知。这可以解释为,好像有个人在服务器旁不断地通知我们服务器在发生什么事件。那当然需要监听者了。因 此,在通知上下文(context)初始化和销毁的时候,ServletContextListner非常有用。 import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import javax.servlet.*; public class MyListener implements ServletContextListener { private ServletContext context = null; /* 这个方法在Web应用服务被移除,没有能力再接受请求的时候被调用。 */ public void contextDestroyed(ServletContextEvent event){ //Output a simple message to the server's console System.out.println("The Simple Web App. Has Been Removed"); this.context = null; } // 这个方法在Web应用服务做好接受请求的时候被调用。 public void contextInitialized(ServletContextEvent event){ this.context = event.getServletContext(); //Output a simple message to the server's console System.out.println("The Simple Web App. Is Ready"); } } ...

2012-06-22 · 1 min · 189 words · -