符合中小企业对网站设计、功能常规化式的企业展示型网站建设
本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...
商城网站建设因基本功能的需求不同费用上面也有很大的差别...
手机微信网站开发、微信官网、微信商城网站...
涂料是装修过程中都会用到的材料之一,也是在装修中占据很重要地位的。涂料的功能很强大,所以很多时候都会用到。那么 js防水涂料是什么 大家了解吗?js防水涂料为新型绿色 环保 材料,优点诸多,下面就一同去看看这个 js防水涂料是什么 以及相关资料和介绍,让大家都能够对其了解更多。
成都创新互联公司是专业的保德网站建设公司,保德接单;提供网站建设、成都做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行保德网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
js防水涂料是什么
Js防水涂料其实就是一中复合有机液料,它以聚丙烯酸酯乳液、乙烯-醋酸乙烯酯共聚乳液等为主要原料,和石英砂、水泥等无机填料所组成的无机粉料通过合理配比、复合制成的一种建筑防水涂料。
怎样挑选JS防水涂料
1.从外观上看js防水涂料的表现都是呈现均匀白色乳液,在加入[按1:0.8~1]普通水泥成膜后颜色呈黑色,表面应平整结实.光滑,没有裂痕。js防水乳液在不加入 其它 东西时,干后是透明的,白色或者有其它颜色都不属合格品!
2.一般涂料都是会有沉淀的现象,在购买的时候先不要去摇动产品,先打来盖子看一下,如果防水乳液上面浮有一层透质或似水的物体,如存放较久,有轻微沉淀的属正常现象,出现严重沉淀分层的,那肯定是伪劣产品。
3.js防水涂料一般气味还是比较淡的,而一些伪劣产品含有很高的VOC化学助剂,都有刺鼻或有难闻的气味,尤其是甲醛等有害物质。
4.很多人都会认为JS防水涂料的粘度越高防水性能就越好,那是错误的认识,JS防水涂料粘度不会很高,如果您所购买的JS防水涂料用手捏很粘手的话,那就是用胶水、白乳胶充当JS防水涂料的假货。
5.防水涂膜弹性的好坏是决定JS防水涂料质量的因素之一。用您所购买的JS防水涂料按其说明上比例做个简单的小试验。就知道您所购买的防水涂料质量的好坏,防水乳液1份+普通水泥0.7然后搅拌均匀涂刷在玻璃或滑面的物品上,等待防水涂层干了以后,取下涂膜,用双手对拉,就大概可测出弹性,JS防水涂料弹性能拉到2倍以上的长度,劣质没有弹性。
6.防水涂料在常温湿度80%以下具有快干的特点[表干4钟头实干8钟头],给施工起到方便的作用。劣质防水涂料有时会出现慢干、不干,或者化白现象。
7.jS防水涂料在加入水泥时应该是搅拌起来不费力,很润滑,很快就能均匀和水泥融合为一体,水泥 不结粒,JS防水涂料涂刷在地 面或者墙壁时很容易涂刷或批荡,干了以后表面平整.光滑,不开裂。
以上就是给大家带来的 js防水涂料是什么 以及选购技巧介绍,上面的选购技巧还是很实用的,可以让您选择好的涂料,对装修施工上也有更好的效果,如果上面介绍有帮助到大家,想了解更多资讯,请继续关注本网站,更多精彩敬请期待!
1、flex
Apache基金会今天发布了Flex 4.8版本,这是Adobe将Flex捐献给Apache基金会后发布的第一个版本。
需要注意的是,Flex目前还在孵化阶段,还不是Apache的正式项目,Flex 4.8也不是一个正式的Apache版本。
Apache称,该版本标志着Flex新时代的开始,Flex的未来将由社区来驱动,而不是由一个公司驱动。开发者可以通过贡献代码,来帮助改进Flex,如修复bug、增加功能等。
从Macromedia卖给Adobe,然后又捐给apache,不知道搞什么名堂。不过还好没有经过大幅重构,否则就真的是悲哀了!
2、extjs
ExtJS是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端ajax框架。
功能丰富,无人能出其右。
无论是界面之美,还是功能之强,ext的表格控件都高居榜首。
华丽的界面,灵活的功能,还有开发工具都是配套的,但有个最大的问题,用就得花钱!
3、easyui
easyui帮助你构建你的web应用更加容易。
它是一个基于jquery的插件,开发出来的一套轻量级的ui框架,非常小巧而且功能丰富。
但是她有一个最大的问题就是代码只能找到以前的开源的版本,到了1.2以后的版本源代码都是经过混淆的,如果遇到问题修改起来会非常麻烦!不过一个比较大的优势是开源免费,并且界面做的还说的过去!
4、MiniUI
又一个基于jquery的框架,开发的界面功能都很丰富。
jQuery MiniUI - 快速开发WebUI。
它能缩短开发时间,减少代码量,使开发者更专注于业务和服务端,轻松实现界面开发,带来绝佳的用户体验。
使用MiniUI,开发者可以快速创建Ajax无刷新、B/S快速录入数据、CRUD、Master-Detail、菜单工具栏、弹出面板、布局导航、数据验证、分页表格、树、树形表格等典型WEB应用系统界面。
界面做的挺不错,功能也挺丰富,但是有两个比较大的问题,一个是收费,一个是没有源码,说白了,不开源!基于这个开发如果想对功能做扩展就需要找他们的团队进行升级!
5、jQuery UI
jQuery UI 是一套 jQuery 的页面 UI 插件,包含很多种常用的页面空间,例如 Tabs(如本站首页右上角部分) 、拉帘效果(本站首页左上角)、对话框、拖放效果、日期选择、颜色选择、数据排序、窗体大小调整等等非常多的内容。
功能非常全面,界面也挺漂亮的,可以整体使用,也可以分开使用其中的几个模块,免费开源!
6、DWZ
DWZ富客户端框架(jQuery RIA framework), 是中国人自己开发的基于jQuery实现的Ajax RIA开源框架.
设计目标是简单实用,快速开发,降低ajax开发成本。
欢迎大家提出建议,我们将在下一版本中进一步调整和完善功能.共同推进国内整体ajax开发水平。
毕竟是国产的,支持一下,而且源码完全公开,可以选择一下!不过性能怎么样不敢确定!
7、GWT
Google 网页工具包——GWT 提供了一组基于Java语言的开发包,这个开发包的设计参考Java AWT包设计,类命名规则、接口设计、事件监听等都和AWT非常类似。熟悉Java AWT的开发者不需要花费多大的力气就能够快速的理解GWT开发工具包,将更多地时间投入到GWT应用的开发过程中。
你不用去了解这样那样的javascript框架,通过java你就可以写出功能丰富的界面,可以做单元测试,毕竟是google的产品,严重支持一下!
8、YUI
Yahoo! UI Library (YUI) 是一个开放源代码的 JavaScript 函数库,为了能建立一个高互动的网页,它采用了AJAX, DHTML 和 DOM 等程式码技术。它也包含了许多 CSS 资源。使用授权为 BSD许可证,基本上没怎么研究过!
YUI Compressor倒是挺出名的,这套UI库不知道应用的情况怎么样!
9、Sencha
Sencha 是由 ExtJS、jQTouch 以及 Raphael 三个项目合并而成的一个新项目。
大公司的框架,并且是几样库的强强联合,值得推荐!
10、Dojo
在国内应用好像不是很广,不过性能上应该没问题。
Dojo是一个用javascript语言实现的开源DHTML工具包。
有多个基金会的支持,包括IBM和SUN,都是软件界的泰斗,值得信赖!
11、ZK
ZK是一套以 AJAX/XUL/Java 为基础的网页应用程式开发框架,用于丰富网页应用程式的使用接口。最大的好处是,在设计AJAX网络应用程式时,轻松简便的操作就像设计桌面程式一样。 ZK包含了一个以AJAX为基础、事件驱动(event-driven)、高互动性的引擎,同时还提供了多样丰富、可重复使用的XUL与HTML组件,以 及以 XML 为基础的使用接口设计语言 ZK User-interfaces Markup Language (ZUML)。
在线的demo
设计器的demo
日历组件
功能丰富,全面,文档齐全,而且升级了很多次,非常值得推荐!
12、OperaMasks-UI
OperaMasks-UI是OperaMasks团队 2011下半年打造的一款轻量级前端JS组件库,旨在提供一款学习曲线低、定制性灵活、样式统一,且多浏览器支持、覆盖企业业务场景的前端 JavaScript UI组件库。目前,该团队已将这一产品以LGPL 开源协议开放给社区。
文档丰富,功能齐全,而且很容易使用和开发!而且是国产的哟!
13、JavaFX
Sun公司(已于2009年被Oracle公司收购)在2008年12月05日发布了JavaFX技术的正式版,它使您能利用 JavaFX 编程语言开发富互联网应用程序(RIA)。JavaFX Script 编程语言(以下称为JavaFX)是Sun微系统公司开发的一种declarative, statically typed(声明性的、静态类型)脚本语言。JavaFX技术有着良好的前景,包括可以直接调用Java API的能力。因为 JavaFX Script是静态类型,它同样具有结构化代码、重用性和封装性,如包、类、继承和单独编译和发布单元,这些特性使得使用Java技术创建和管理大型程序 变为可能。
不管用的人多少,毕竟是从sun开始,现在是oracle,相信会有一个广阔的市场,但是确实不知道有哪个公司用这个框架开发!
转载
J2EE Java2平台企业版
string是引用数据类型
如何取得年月日,小时分秒
public static void main(String[] args)
{
ActionListener time = new ActionListener() { // 监听事件,不然实现不了动态改变时间
public void actionPerformed(ActionEvent e) {
//date对象代表当前的系统时间(毫秒)
Date date = new Date();
//format对象是用来以指定的时间格式格式化时间的
SimpleDateFormat from = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss"); //这里的格式可以自己设置
//format()方法是用来格式化时间的方法
String times = from.format(date);
System.out.println(times); }
};
Timer tim = new Timer(1000, time); //这里表示1000毫秒更新一下时间
tim.start(); //启动
}
我这个答案肯定正确啊
下面帮你解释你的答案吧
Date //是在java.util.Date;里面
SimpleDateForma //这个是java.text.SimpleDateFormat;用来输出问本格式的
DateFormat //应该是在java.util.*;里面吧..应该是的
你那个错误是编译就没通过啊
public class Test
那你那个编译写的因该是
javac Test.java 编译的应该是类啊而不是javac time.java 请问你的time什么意思呢,所以你报的异常是找不到time类啊
呵呵...你是初学java吧该答的我都答完了拉!还特地帮你每句都写
如何读写文件
StringBuffer sb = new StringBuffer();
//File file = new FileWindow().load();
File file;
file = new File("F:/jtest/from.txt");
TextReader tr = new TextReader(file);
sb.append(tr.readAll());
Out.println(sb.toString());
String [] tags = ;
String str;
str = sb.toString();
for(String reg: tags) {
Out.println(reg);
str = str.replaceAll(reg, "");
}
Out.println(str);
抽象类和接口的区别
声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。
主键是确定数据库中的表的记录的唯一标识字段,可以是表中的一个字段,也可以是表中的多个字段组成的。一旦确定为主键,则该字段不可为空也不可以重复。比如学生表中的学号就可以定义成该表的字段
外键的定义是相对于主键而言的,比如另有一张成绩表,表中也出现了学生表中的对应学号字段,则相对于学生表,学号就是成绩表的外键
String和StringBuffer的区别
STRING的长度是不可变的,STRINGBUFFER的长度是可变的。如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法
tryfinally内出现异常,try内的代码呢?finally{}后面的代码呢
执行 finally{}内的代码最后执行
排序算法
所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
分类
在计算机科学所使用的排序算法通常被分类为:
计算的复杂度(最差、平均、和最好表现),依据串列(list)的大小(n)。一般而言,好的表现是O。(n log n),且坏的行为是Ω(n2)。对於一个排序理想的表现是O(n)。仅使用一个抽象关键比较运算的排序算法总平均上总是至少需要Ω(n log n)。
记忆体使用量(以及其他电脑资源的使用)
稳定度:稳定排序算法会依照相等的关键(换言之就是值)维持纪录的相对次序。也就是一个排序算法是稳定的,就是当有两个有相等关键的纪录R和S,且在原本的串列中R出现在S之前,在排序过的串列中R也将会是在S之前。
一般的方法:插入、交换、选择、合并等等。交换排序包含冒泡排序(bubble sort)和快速排序(quicksort)。选择排序包含shaker排序和堆排序(heapsort)。
当相等的元素是无法分辨的,比如像是整数,稳定度并不是一个问题。然而,假设以下的数对将要以他们的第一个数字来排序。
(4, 1) (3, 1) (3, 7) (5, 6)
在这个状况下,有可能产生两种不同的结果,一个是依照相等的键值维持相对的次序,而另外一个则没有:
(3, 1) (3, 7) (4, 1) (5, 6) (维持次序)
(3, 7) (3, 1) (4, 1) (5, 6) (次序被改变)
不稳定排序算法可能会在相等的键值中改变纪录的相对次序,但是稳定排序算法从来不会如此。不稳定排序算法可以被特别地时作为稳定。作这件事情的一个方式是人工扩充键值的比较,如此在其他方面相同键值的两个物件间之比较,就会被决定使用在原先资料次序中的条目,当作一个同分决赛。然而,要记住这种次序通常牵涉到额外的空间负担。
排列算法列表
在这个表格中,n是要被排序的纪录数量以及k是不同键值的数量。
稳定的
冒泡排序(bubble sort) — O(n2)
鸡尾酒排序 (Cocktail sort, 双向的冒泡排序) — O(n2)
插入排序 (insertion sort)— O(n2)
桶排序 (bucket sort)— O(n); 需要 O(k) 额外 记忆体
计数排序 (counting sort) — O(n+k); 需要 O(n+k) 额外 记忆体
归并排序 (merge sort)— O(n log n); 需要 O(n) 额外记忆体
原地归并排序 — O(n2)
二叉树排序 (Binary tree sort) — O(n log n); 需要 O(n) 额外记忆体
鸽巢排序 (Pigeonhole sort) — O(n+k); 需要 O(k) 额外记忆体
基数排序 (radix sort)— O(n·k); 需要 O(n) 额外记忆体
Gnome sort — O(n2)
Library sort — O(n log n) with high probability, 需要 (1+ε)n 额外记忆体
不稳定
选择排序 (selection sort)— O(n2)
希尔排序 (shell sort)— O(n log n) 如果使用最佳的现在版本
Comb sort — O(n log n)
堆排序 (heapsort)— O(n log n)
Smoothsort — O(n log n)
快速排序 (quicksort)— O(n log n) 期望时间, O(n2) 最坏情况; 对於大的、乱数串列一般相信是最快的已知排序
Introsort — O(n log n)
Patience sorting — O(n log n + k) 最外情况时间, 需要 额外的 O(n + k) 空间, 也需要找到最长的递增子序列(longest increasing subsequence)
不实用的排序算法
Bogo排序 — O(n × n!) 期望时间, 无穷的最坏情况。
Stupid sort — O(n3); 递回版本需要 O(n2) 额外记忆体
Bead sort — O(n) or O(√n), 但需要特别的硬体
Pancake sorting — O(n), 但需要特别的硬体
排序的算法
排序的算法有很多,对空间的要求及其时间效率也不尽相同。下面列出了一些常见的排序算法。这里面插入排序和冒泡排序又被称作简单排序,他们对空间的要求不高,但是时间效率却不稳定;而后面三种排序相对于简单排序对空间的要求稍高一点,但时间效率却能稳定在很高的水平。基数排序是针对关键字在一个较小范围内的排序算法。
插入排序
冒泡排序
选择排序
快速排序
堆排序
归并排序
基数排序
希尔排序
插入排序
插入排序是这样实现的:
首先新建一个空列表,用于保存已排序的有序数列(我们称之为"有序列表")。
从原数列中取出一个数,将其插入"有序列表"中,使其仍旧保持有序状态。
重复2号步骤,直至原数列为空。
插入排序的平均时间复杂度为平方级的,效率不高,但是容易实现。它借助了"逐步扩大成果"的思想,使有序列表的长度逐渐增加,直至其长度等于原列表的长度。
冒泡排序
冒泡排序是这样实现的:
首先将所有待排序的数字放入工作列表中。
从列表的第一个数字到倒数第二个数字,逐个检查:若某一位上的数字大于他的下一位,则将它与它的下一位交换。
重复2号步骤,直至再也不能交换。
冒泡排序的平均时间复杂度与插入排序相同,也是平方级的,但也是非常容易实现的算法。
选择排序
选择排序是这样实现的:
设数组内存放了n个待排数字,数组下标从1开始,到n结束。
i=1
从数组的第i个元素开始到第n个元素,寻找最小的元素。
将上一步找到的最小元素和第i位元素交换。
如果i=n-1算法结束,否则回到第3步
选择排序的平均时间复杂度也是O(n²)的。
快速排序
现在开始,我们要接触高效排序算法了。实践证明,快速排序是所有排序算法中最高效的一种。它采用了分治的思想:先保证列表的前半部分都小于后半部分,然后分别对前半部分和后半部分排序,这样整个列表就有序了。这是一种先进的思想,也是它高效的原因。因为在排序算法中,算法的高效与否与列表中数字间的比较次数有直接的关系,而"保证列表的前半部分都小于后半部分"就使得前半部分的任何一个数从此以后都不再跟后半部分的数进行比较了,大大减少了数字间不必要的比较。但查找数据得另当别论了。
堆排序
堆排序与前面的算法都不同,它是这样的:
首先新建一个空列表,作用与插入排序中的"有序列表"相同。
找到数列中最大的数字,将其加在"有序列表"的末尾,并将其从原数列中删除。
重复2号步骤,直至原数列为空。
堆排序的平均时间复杂度为nlogn,效率高(因为有堆这种数据结构以及它奇妙的特征,使得"找到数列中最大的数字"这样的操作只需要O(1)的时间复杂度,维护需要logn的时间复杂度),但是实现相对复杂(可以说是这里7种算法中比较难实现的)。
看起来似乎堆排序与插入排序有些相像,但他们其实是本质不同的算法。至少,他们的时间复杂度差了一个数量级,一个是平方级的,一个是对数级的。
平均时间复杂度
插入排序 O(n2)
冒泡排序 O(n2)
选择排序 O(n2)
快速排序 O(n log n)
堆排序 O(n log n)
归并排序 O(n log n)
基数排序 O(n)
希尔排序 O(n1.25)
一、术语session
在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣的是transaction与session在某些语境下的含义是相同的。
session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。有时候我们可以看到这样的话“在一个浏览器会话期间,...”,这里的会话一词用的就是其本义,是指从一个浏览器窗口打开到关闭这个期间①。最混乱的是“用户(客户端)在一次会话期间”这样一句话,它可能指用户的一系列动作(一般情况下是同某个具体目的相关的一系列动作,比如从登录到选购商品到结账登出这样一个网上购物的过程,有时候也被称为一个transaction),然而有时候也可能仅仅是指一次连接,也有可能是指含义①,其中的差别只能靠上下文来推断②。
然而当session一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义,“面向连接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到对方接了电话通信才能开始,与此相对的是写信,在你把信发出去的时候你并不能确认对方的地址是否正确,通信渠道不一定能建立,但对发信人来说,通信已经开始了。“保持状态”则是指通信的一方能够把一系列的消息关联起来,使得消息之间可以互相依赖,比如一个服务员能够认出再次光临的老顾客并且记得上次这个顾客还欠店里一块钱。这一类的例子有“一个TCP session”或者“一个POP3 session”③。
而到了web服务器蓬勃发展的时代,session在web开发语境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器之间保持状态的解决方案④。有时候session也用来指这种解决方案的存储结构,如“把xxx保存在session里”⑤。由于各种用于web开发的语言在一定程度上都提供了对这种解决方案的支持,所以在某种特定语言的语境下,session也被用来指代该语言的解决方案,比如经常把Java里提供的javax.servlet.http.HttpSession简称为session⑥。
鉴于这种混乱已不可改变,本文中session一词的运用也会根据上下文有不同的含义,请大家注意分辨。
在本文中,使用中文“浏览器会话期间”来表达含义①,使用“session机制”来表达含义④,使用“session”表达含义⑤,使用具体的“HttpSession”来表达含义⑥
二、HTTP协议与状态保持
HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的,好比一个顾客和一个自动售货机或者一个普通的(非会员制)大卖场之间的关系一样。
然而聪明(或者贪心?)的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用,就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为,另一方面在服务器端则出现了CGI规范以响应客户端的动态请求,作为传输载体的HTTP协议也添加了文件上载、cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。
让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。
三、理解cookie机制
cookie机制的基本原理就如上面的例子一样简单,但是还有几个问题需要解决:“会员卡”如何分发;“会员卡”的内容;以及客户如何使用“会员卡”。
正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。
而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示,如果某家分店还发行了自己的会员卡,那么进这家店的时候除了要出示麦当劳的会员卡,还要出示这家店的会员卡。
cookie的内容主要包括:名字,值,过期时间,路径和域。
其中域可以指定某一个域比如.google.com,相当于总店招牌,比如宝洁公司,也可以指定一个域下的具体某台机器比如或者froogle.google.com,可以用飘柔来做比。
路径就是跟在域名后面的URL路径,比如/或者/foo等等,可以用某飘柔专柜做比。
路径与域合在一起就构成了cookie的作用范围。
如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。对于IE,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口可以与原窗口共享,而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie;对于Mozilla Firefox0.8,所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用session机制的web应用程序开发者造成很大的困扰。
下面就是一个goolge设置cookie的响应头的例子
HTTP/1.1 302 Found
Location:
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Content-Type: text/html
这是使用HTTPLook这个HTTP Sniffer软件来俘获的HTTP通讯纪录的一部分
浏览器在再次访问goolge的资源时自动向外发送cookie
使用Firefox可以很容易的观察现有的cookie的值
使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理。
IE也可以设置在接受cookie前询问
这是一个询问接受cookie的对话框。
四、理解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路径的附加信息,表现形式为;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一种是作为查询字符串附加在URL后面,表现形式为!-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。
恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。
五、理解javax.servlet.http.HttpSession
HttpSession是Java平台对session机制的实现规范,因为它仅仅是个接口,具体到每个web应用服务器的提供商,除了对规范支持之外,仍然会有一些规范里没有规定的细微差异。这里我们以BEA的Weblogic Server8.1作为例子来演示。
首先,Weblogic Server提供了一系列的参数来控制它的HttpSession的实现,包括使用cookie的开关选项,使用URL重写的开关选项,session持久化的设置,session失效时间的设置,以及针对cookie的各种设置,比如设置cookie的名字、路径、域,cookie的生存时间等。
一般情况下,session都是存储在内存里,当服务器进程被停止或者重启的时候,内存里的session也会被清空,如果设置了session的持久化特性,服务器就会把session保存到硬盘上,当服务器进程重新启动或这些信息将能够被再次使用,Weblogic Server支持的持久性方式包括文件、数据库、客户端cookie保存和复制。
复制严格说来不算持久化保存,因为session实际上还是保存在内存里,不过同样的信息被复制到各个cluster内的服务器进程中,这样即使某个服务器进程停止工作也仍然可以从其他进程中取得session。
cookie生存时间的设置则会影响浏览器生成的cookie是否是一个会话cookie。默认是使用会话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解。
cookie的路径对于web应用程序来说是一个非常重要的选项,Weblogic Server对这个选项的默认处理方式使得它与其他服务器有明显的区别。后面我们会专题讨论。
关于session的设置参考[5]
~~我要200分~~
JS防水涂料十大品牌有:科顺防水涂料品牌 、韦伯防水涂料品牌 、西卡防水涂料品牌 、波士胶防水涂料品牌、雨虹防水涂料品牌、固莱防水涂料品牌 、蒂贝贝尔防水涂料品牌 、西洛咖防水涂料品牌 、德高防水涂料品牌 、百得防水涂料品牌 。想要防水材料的你可以去了解一下科顺防水这个品牌,其高品质值得信赖,从研发到生产,多部门协同运作,从销售到施工,科顺严控每一个环节,全方位保证质量;并且售后服务优秀。
科顺防水科技股份有限公司成立于1996年,历经二十余年的稳健经营和高效发展,现已成长为以提供防水综合解决方案为主业,集工程建材、民用建材、建筑修缮业务板块于一体,业务范围涵盖海内外的综合建材公司。公司于北京、上海、深圳下设工程公司,拥有专业工程技术人员超过370人,年均为近3000个项目服务,在多个重大建筑项目的防水工程项目中,均采用了科顺标准化施工,为670多个施工现场提供技术咨询和施工指导 。其中最早成立于1998年的深圳市科顺防水工程有限公司,拥有国家建筑 防水一级防水保温资质 。