2009年4月19日星期日
简单说说JAVA的String和byte[]的关系 (转)
做JAVA经常会碰到中文乱码问题,还有各种编码的问题,特别是String类的内容需要重新编码的问题。要解决这些问题,必须了解清楚JAVA对于字符串是怎么处理的。
1,“字符”是由数字来表示的 先来重新了解一下计算机是如何处理“字符”的,这个原理是大家必须记住的,特别是在用JAVA写程序的时 候,万万不可模糊。我们知道,计算机把任何东西都用数字来表示,“字符”也不例外。比如我们要显示一个阿拉伯数字“3”,在我们的PC里,其实并不是仅仅 用一个数字3来代表我们要写的“3”,而是以十六进制的0x33来代表,包括放在内存或者是写到文件里,其实都是写着0x33的,不信你可以编辑一个文本 文件,写一个“3”,然后用ultraEdit看他的原始码。
2,一切“字符”都必定用数字+编码表表示。
这时候,有一个问题:为什么一定要用0x33来代表“3”呢?而不用0x43来代表呢?或者是直接用0x03来代替?其实用什么来代表都 可以,只不过大家都习惯了用ASCII编码表(是美国国家信息交换表)来确定各字符应该是用什么数字代表的。同样,为了表示中国字,我国也指定了中文的编 码表,其中最广泛使用的是GB2312。比如中文的“当”字,就是用0xB5, 0xB1这两个八位的数字来表示的。所以如果显示字符的程序不知道一列数 字到底是按什么编码表编码的,他也无法去判断到底这些是什么文字。如果随便用一个不对的编码表来处理这些数字,处理出来的字符很可能完全是错的。比如在英 文系统上,没有GB2312编码表,送给他一个0xB5,0xB1,他就傻傻的当作ASCII来处理(操作系统通常都有自己默认的编码表),结果显示出来 就是两个奇怪的符号,因为这两个字在ASCII表里就是那两个符号。同样在繁体中文系统里,他的编码表是BIG5,显示出来也是一个奇怪的中文,不是“当 ”字。
3,UNICODE让全世界都说一种语言
看完上面的文字,是否觉得,世界有那么多语言,每个都有自己的一套编码表,很麻烦呢?就算是中文,也有两套流行的编码表,一个是 GB2312,一个是BIG5。要使用不同中文的编码的字符时,还要转来转去,的确很麻烦。不光这个,如果想要写一篇包含很多过国文字的文章,就麻烦了, 必须要让处理这个文章的程序知道,哪个字是什么编码标准的。如果你想要在文章里找一个字,也必须指定你要找的是哪种编码的哪个字。否则,你要找一个 0xB5,0xB1的中文“当”字,很可能把同样数字表示的日文、波兰文这些不相干的字一起给你找出来,够麻烦的吧!
所以人们想,不如大家都用同一个编码标准吧,各种文字都在编码表里有一席之地,处理文字的程序只需要都按这个编码表来处理就可以了。不 过要一个编码表里包含所有的文字,这张表就大了,本来英文字+数字一共只有128个以内。但加上中文后,忽然就多了数万个,所以存放一个字符需要的大小也 大了很多。现在UNICODE规定了一个字符必须由2个8位数字来表示,想想,8x8x8x8x = 65536 ,是多大的一个数字啊!所以全世界的文 字才能都包含进去。当然拉,也有人说中国字可能都不止6万个拉,还要包括别的文字,但人家外国人觉得你们中国人常用的也没那么多,所以就这么定了,我们也 没办法。需要注意的是GB2312和UNICODE虽然都是用两个8位数来代表一个中文字,但具体的规格可不一样,比如0xB5,0xB1在 UNICODE里面可不是“当”字,而是另外一国的文字来的。
4,C是如何简洁的处理字符的
我们来谈谈C的字符串。C语言诞生在JAVA之前,C语言的基本数据类型是没有字符串这个类型的,它只有char[]。也就是C把字符顺 序放入一个字节数组就完了。而且C也不管放在数组里的是什么文字,也不管那些字是按什么编码标准的。而且他的char的大小也不一定是8位数字,有时候是 16位也可能,这要看具体的机器和操作系统。所以写程序的人必须要知道正在处理的char[]的内容到底是按什么编码表表示的字符串,要知道如果比较两国 文字是否相同,可是没任何意义的哦!
5,JAVA是是如何处理字符的。
世界总会进步的,JAVA就是一个例子。JAVA终于有了String类了,它是解决字符问题的最好工具。在JAVA里,一个基本的要点 是:String类对象是不需要指定编码表的!为什么它会自己知道一堆数字各代表什么字符呢?就是因为String里的字符信息是用UNICODE编码存 放的。而JAVA为了表示字符(注意是单个字符),也有char这个数据类型,而且他的大小是固定2个8位16进制数字长度,也就是0~65535罗。为 的就是对应UNICODE里面的一个字符。大家如果想取一个String里的按UNICODE数字,可以用 getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 方法取得一个 char[],这个char[]里就是表示String字符的,按UNICODE编码表编码的数字。
可惜现在绝大多数的系统和程序都不是按UNICODE来处理字符,而JAVA程序总是要和别的程序和系统交换数据的,所以在接收一个字 符,或者是发送一个字符的时候,就必须要留意当前系统和UNICODE的关系了。比如你从网络或者文件接受到一数字:0xB5,0xB1,JAVA程序并 不知道这两个字到底是中文呢?还是日文,或者英文。你如果不指明这个两个数字的编码表,JAVA就会按当前系统默认的编码表来处理。如果这两个数字是从中 文WIN98发出去的,JAVA程序又是在英文LINUX上运行的,那就出现了所谓的乱码问题了。也就是JAVA按英文的编码表ASCII来处理这两个数 字,当通过new String({0xB5,0xB1})得到的String的时候,这个String代表的已经不是中文的“当”字,而是两个英文的奇 怪字符了。不过如果你知道这两个数字一定是中文的话,就可以指定用new String({0xB5,0xB1},"GB2312")来处理,这时候新建 立的String才真的是一个“当”字。当然拉,如果你要把一个“当”字的JAVA的String显示在中文WIN98上,必须把这个字输出成两个8位数 字:0xB5,0xB1,不管是写成文件还是输出到浏览器上,都必须是0xB5,0xB1。如何把“当”字用GB2312输 出?String.getBytes("GB2312")就可以拉!所以有一点要记住:和外界交换任何信息都是以byte[]来进行的!。 你可以留意一下JAVA大多数的I/O类,都有以byte[]作为参数和返回值的方法。不过,也有很多写的比较糊涂的程序,没有提供byte[]交换信息 的方法,害的不同文字平台的程序员很头疼。Servlet的HttpRequest.getParameter()就是这样。好在有的 JSP/SERVLET容易还提供先指定编码表的方法,才能比较简单的解决这个问题。
6,网上关于JAVA中文问题的一些错误处理方法。
一个是最常见的,不管什么内容,都用new String(...,"ISO-8859-1")来建立字符串,然后使用的时候按默认的编 码格式(通常在服务器上都是英文系统)输出字符串。这样其实你使用的String并不是按UNICODE来代表真正的字符,而是强行把BYTE数组复制到 String的char[]里,一旦你的运行环境改变,你就被迫要修改一大堆的代码。而且也无法在同一个字符串里处理几种不同编码的文字。
另一个是把一种编码格式的字符串,比如是GB2312,转换成另一种格式的字符串,比如UTF-8,然后不指明是UTF-8编码,而直 接用new String(...)来建立String,这样放在String里面的字符也是无法确定的,它在不同的系统上代表不同的字符。如果要求别人 用“UTF-8格式”的String来交换信息的时候,其实已经破坏了JAVA为了兼容各种语言所做的规定。这种错误的本质思想是还按写C语言的方式,把 字符串纯粹当作可以自己自由编码的存储器使用,而忽略了JAVA字符串只有一种编码格式。如果真的想自由编码,用byte[]或者char[]就完全了解 决问题的了。
以上,除了是解决JAVA中文问题的基础知识外,也是多年前应该掌握的计算机基础知识。温故而知新,以期共勉
浅谈并行编程中的任务分解模式(转)
并行编程使用线程来使得多个操作能够同时运行。并行编程主要包括应用程序中线程设计,开发和部署以及线程间相互协调和各自的操作。
在下文中我们将讨论怎样分割适合线程化大小的编程任务来多任务化一个应用程序。
设计线程
不熟悉并行编程的开发者通常对例如面向对象的传统的编程模式感到非常适应。在传统的编程模式下,程序以预先定义的起点开始运行,譬如main函数,然后接连地做完一系列任务。如果程序依赖用户交互,主要的工作代码通常被封装在一个处理用户事件的循环里。
从一个约定事件开始,譬如点击按钮,程序运行一段已经制定的顺序行为,最终以等待用户下个动作结束。
当设计这样的程序时,程序员喜欢一个相对简单的编程模式因为在任意一段给定的时间内只有一个事件发生。如果程序任务必须按某种方式顺序运行, 程序员必须在这些事件上特意安排顺序。在这个过程的任一时刻,程序运行一步接着下一步,最终基于预先确定的参数到达一个预见的结果。
从这种线性的模式到并行编程模式,程序设计者必须重新思考程序的过程流。相比顺序执行序列限制,程序员应该识别出那些能被并行化的行为。
要这样做,他们必须把程序看作一组相互间有依赖关系的任务。把程序分解成一些独立的任务并识别这些任务间的依赖性。这个过程被称为分解。
一个问题有许多分解方式: 按任务,数据,或者按数据流。下面的表总结了这些分解的形式。您将很快看到,这些不同分解形式对应了不同的编程行为。
| 分解类型 | 设计 | 评论 |
| 任务 | 不同的行为分配给不同的线程 | 通常在GUI应用 |
| 数据 | 多个线程对不同的数据集执行同样的操作 | 通常在音频处理,做图和科学编程 |
| 数据流 | 一个线程的输出是第二个线程的输入 | 需要特别关注消除开始和结束的延迟 |
主要的分解形式总结
任务分解
按功能分解一个程序被称为任务分解。这是一种实现并行执行最简单的方式。使用这种方法,每个任务被按目录分类。
如果它们中的两个能同时运行,它们会被程序员按此调度。以这种方式并行运行任务通常需要对每个函数做小量修改来避免冲突,并指出这些任务已经不再连续。
以园艺工作举例,任务分解会建议园丁按工作本身的属性分配任务:如果两个园丁到达一个客户家,一个修剪草坪,另一个铲除杂草。修剪草坪和铲除杂草是两个被分开的功能。
要完成这两个功能,园丁们需要确保他们之间相互协调,这样铲除杂草的园丁就不会坐在待修剪草坪的中间。
举个编程的例子,一个任务分解的典型案例是文字处理软件,譬如微软的Word。当用户打开一个很长的文档的时候,他(她)能够马上开始输入文字。当用户输入文字时,文档分页在后台发生,于是他(她)能够很容易地看到状态栏中页数的增加。
文档输入和分页是两个独立的任务,程序员按功能将它们分开来并行运行。如果程序员没有这样设计,用户将不得不在能够输入任何文字之前等待整个文档被分页。有些朋友可能回忆起这种现象在早期的个人电脑文字处理器中非常常见。
数据分解
数据分解,也被认为是数据级并行,将任务按它们处理的数据进行分解,而不是按照任务本身的性质。使用数据分解的程序通常有许多线程在执行同样的任务,只是处理的数据项不同。
举个例子,假设在一个大的电子数据表里计算值。相比一个线程执行所有的计算,数据分解会建议有两个线程,每个执行一半的计算量,或者n个线程执行1/n的工作量。
如果园丁应用数据分解来分解他们的任务,他们两个会同时修剪一半的草坪,然后两个人分别铲除一半的杂草。在计算领域,决定哪一种分解形式更高效取决于系统的限制。
举例说,如果需要修剪草坪的地块非常小以至于没必要有两个人来修剪草坪,修剪草坪这个任务最好只被分配给一个园丁做,那么任务分解在这一步是最好的选择。数据分解或许适用于其它的任务序列,譬如当修剪草坪完成后,两个园丁并行地来铲除杂草。
随着处理器核心数目的增加,数据分解使得任务处理规模增加。这允许在同样的时间内做更多的工作。
举园丁的例子,假设有另外两个园丁加入了工作。相比分配所有四个园丁到一个地块工作,我们不如分配两个新的园丁去另一个地块,非常有效地增加我们总的任务处理量。
假设两位新园丁和两位老园丁能够做同样多的工作,两个地块的大小也是一样的,我们已经在同样的时间内把工作量翻倍了。
数据流分解
许多时候,当分解一个问题时,关键不是任务应该做什么事情,而是数据在不同任务中怎样传递。在这些情况下,数据流分解将问题按数据在任务中传递的方式来分解。
生产者/消费者问题是数据流影响程序并行执行能力的著名例子。这里,一个生产者任务的输出,成为另一个消费者的输入。两个任务被不同的线程执行,直到生产者完成他的部分工作,消费者不能开始工作。
依然引用园丁的例子,一个园丁准备工具,譬如他承担为割草机加油,清扫剪刀等类似的任务来提供这些工具给另两个园丁使用。直到这个准备步骤基本结束,其他园丁的园艺工作才能开始。
由第一个任务引起的延迟为第二个任务产生一个暂停,在此之后两个任务才能并行运行。在计算机领域这样的模式经常发生。
在常见的编程任务里,生产者/消费者问题在多个典型的场景发生。譬如,必须对读文档做回应的程序就符合这种场景:文件的输入/输出结果成为下一步可能被线 程化的工作的输入。下一步直到读完或读到其他处理需要的足够信息才会开始执行。另一个编程的例子是分析:一个输入文件必须在后端操作之前被分析或者语义分 析,譬如编译器的代码生成。
生产者/消费者问题有许多需要注意的方面:
1) 如果这种模式没有正确地执行,消费者和生产者间产生的依赖性会引起重大的延迟。一个性能敏感的设计需要充分理解依赖关系的性质以减小延迟的影响。这也是为了避免消费者线程空闲等待生产者线程的情况。
2) 在完美的情况下,生产者和消费者间的传递是完全"清洁"的,就像在文件分析器的例子中一样。输出是上下文相关的,消费者不需要知道生产者的任何事情。然而在很多时候,生产者和消费者并不享受如此干净的任务分割,安排他们间的互动需要非常仔细的计划。
3) 如果当生产者完全做好后消费者开始加工,那么当其他线程忙着工作时一个线程就保持空闲。这个问题破坏了一个并行处理的重要目标,那就是负载均衡以使得所有能用的线程保持忙碌。由于线程间的逻辑关系,要保持线程平等地被占用非常困难。
下面,我们看看流水线模式,它允许开发者以可升级的模式解决生产者/消费者问题。
不同分解的含义
不同的分解具有不同的优势。如果目标是使编程简便,任务能够清楚地按功能分割,那么任务分解通常更合适。
数据分解增加了一些额外的代码级复杂度,因此他专供数据非常容易分解而性能又非常重要的情况使用。
线程化程序的最常见原因就是性能。在这种情况下,分解方式的选择就更加困难。在许多情况下,选择依赖于问题的领域:一些任务明显更适合于其中一种分解方式。
但是一些任务没有明显的偏向。譬如视频流中的图像处理。在帧与帧间没有依赖的格式,你需要作出分解模式的选择。他们应该选择任务分解么,那样一个线程解码,另一个线程配色,诸如此类?或者选择数据分解,每个线程做一帧上的所有工作,然后一起开始处理新的一帧?
回到园丁的例子:如果两个园丁需要修整两块草坪和铲除两块花园的杂草,他们应该怎样工作?是应该一个园丁只修剪草坪,也就是他们选择基于任务的分解呢?还是两个人应该同时修剪草坪然后同时铲除杂草?
在一些情况下,答案很快显现。例如当一个资源限制存在,譬如只有一个割草机。其它情况下每一个园丁都有一个割草机,答案只能通过仔细分析行为要素来得出。在园丁的例子中,任务分解看起来更好,因为如果只有一个割草机在使用,开始的割草时间就被节省了。
最终,你通过仔细的计划和测试来为你的应用程序使用并行编程作出正确的选择。 根据经验估计在你决定并行程序设计时比标准的单线程编程中扮演更加重要的角色。
你将面对的挑战
使用线程通过允许两个或多个行为同时发生使得你显著改进性能。然而,开发者不能不认识到线程增加了复杂性度量,需要细致的考虑来正确引导。
这种复杂度源于程序中多于一个行为发生的自身性质。管理同步行为和他们可能的交互使你面对下面四种问题:
1) 同步是两个或多个线程协调他们行为的过程。譬如,一个线程在继续运行前等待另一个完成任务。
2) 交互代表与线程间交换数据相关的带宽和延迟问题。
3) 负载均衡表示任务在多个线程间的分配,因此他们都处理基本同样的工作量。
4) 可扩展性是当软件在更先进的系统上运行时高效利用许多线程的挑战。譬如,如果一个程序被编写来充分利用四核处理器,当它在一个八核处理器上运行时它是否能适当地扩展?
上述每个问题都必须被仔细地处理来最大化程序的性能。
并行编程模式
对于多年编写面向对象程序的程序员,他们使用设计模式来逻辑地设计他们的应用程序。并行编程和面向对象编程没有什么不同,并行编程问题通常对应于许多知名的编程模式之一。
下面的表格显示了一些常见的并行编程模式和他们对应的上述分解类型。
| 模式 | 分解 |
| 任务级并行 | 任务 |
| 分离并战胜 | 任务/数据 |
| 几何分解 | 数据 |
| 流水线 | 数据流 |
| 波阵面 | 数据流 |
常见的并行编程模式
在这部分,我们将提供每种模式及其适用的问题种类的简要概述,包括:
1) 任务级并行编程模式。在许多情况下,完成并行执行的最佳方法是直接关注任务本身。在这种情况下,任务级并行模式最合适。这种模式下,问题被分解成一组独立操作的任务。
通常移除任务间的依赖性或使用复制来分离依赖性是必要的。适合这种模式的问题包括线程间没有依赖性,或线程间的依赖性可从每一个线程中移除。
2) 分而治之模式。在分而治之模式中,问题被分成许多并行的子问题。每个子问题被单独解决。当每个子问题被解决时,结果合计到最后的结果中。因为每个子问题都能被单独解决,这些子问题有可能被并行执行。
分而治之的方法被广泛应用于诸如合并分类的算法。这些算法非常容易被并行化。这种模式很好地处理了负载均衡,这点对缓存的有效利用非常重要。
3) 几何分解模式。几何分解模式基于正在解决问题的数据结构的并行化。在几何分解中,每个线程负责操作数据块。这种模式可能适用于诸如热流和声波传播之类的问题。
4) 流水线模式。流水线模式的意思类似于一条工厂的产品装配线。这种寻找并发的方式使计算被分割成一系列阶段,每个线程在不同的阶段同时工作。
5) 波阵面模式。波阵面模式在处理二维网格中延对角线的数据元素时非常有用。如下图所示。
波阵面数据模式
上图中的数字解释了数据元素被处理的顺序。譬如对角线的元素包括数字3是独立于之前被处理的数字元素1和2的。
上图中阴影中的数据元素表示数据已经被处理。在这种模式下,减小每个线程的空闲时间非常关键。负载均衡在此种模式中非常关键。
更加详细的并行编程设计模式的介绍请参考"并行编程模式"(Mattson 2004) 一书。
*本文观点引自英特尔公司系统架构师Shameem Akhter和高级软件工程师Jason Roberts的文章
WEB(Javascript)远程调用方案清单(转)
WEB(Javascript)远程调用方案清单
Web远程过程调用(以下简称WebRPC)是在不刷新页面的前提下,对远程方法进行调用,是最近的一个热点;在一些场合下,他甚至成为不可替代的 实现方式。WebRPC的实现方式经历了从普通URL读取,隐藏帧,IFrame, XMLHTTP乃至 Flash等。本文将对目前存在的WebRpc方案(产品)进行列表,并作简单评价。
评价将在以下几个方面进行:客户端实现方式,服务器端实现方式,是否自行封装协议,是否支持序列化/反序列化,序列化支持是否完备(原子类型,对象 类型),是否支持异步/同步方式。注意,由于Web方式的远程调用没有得到大规模运用。笔者自己并没有在企业应用中采用WebRPC的经验,但在娱乐应 用、在线游戏中,已经得到了相当好的运用。这些应用已经在《面向异步消息的Web应用(AMOWA)》中得到详细论述,有兴趣的可以在产品指南栏目中阅读 这篇文章。
1 MSRS (Microsoft Remote Scripting)
地址:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rmscpt/Html/rmscpt1.asp
简介:在网页出现的早期,浏览器功能有限。Applet的出现,为MSRS提供了平台。在这项方案中,MSRS通过一个applet类以及页面上的参数配 置,来与服务器端交互,从而实现了远程调用。采用此项技术实际上将页面不刷新的工作交给了一个名为rsproxy.class的不可见Applet完成。 我见过早期的在线Web象棋采用此项方案。优点:轻而易举跨浏览器;缺点:服务器端采用微软asp, applet加载缓慢;不支持数据类型序列化/反序列化。
2 JSRS (Javascript Remote Scripting)
地址:http://www.blueshoes.org/en/javascript/jsrs/
简介:支持两种数据访问方式:HTTP GET方式(动态加载JS文件),HTTP POST方式(用JS动态创建一个Iframe, 在其中提交一个表单)。不用刷新页面,支持简单数据的序列化/反序列化。
3 XML-RPC
地址:http://www.xmlrpc.org/
简介:XML-RPC定义了一种协议规范,由于它的轻量级、概念完整,因此目前绝大多数语言都有实现,包括Java(Apache xml-rpc), PHP, javascript, VBScript, python等等。最大的交流方式Blog协议,管理方法也遵循XML-RPC规范。优点:绝大多数语言都支持,简单,规范。缺点:Java实现对数据类 型序列化支持有限
4 dwr (Direct Web Remoting)
地址:https://dwr.dev.java.net/
简介:一个在适当时候提出适当概念的小东西。采用xmlhttp传递请求,服务器端利用反射找到相应方法执行后将结果返回。较有创意的是,他将服务器端需 要进行远程调用的代码动态转换为相应的js代码,前端可以直接显式调用。简单,可以作为WebRPC学习入门。不支持数据序列化
5 JSON-RPC
地址:http://oss.metaparadigm.com/jsonrpc/
简介:采用一种没听说过的数据交换协议JSON(JavaScript Object Notation, http://www.crockford.com/JSON/) 作为协议基础,在此之上进行数据调用,采用xmlhttp发送/接受请求,支持完整的数据序列化/反序列。目前,jason Web框架采用json-rpc为底层方式。
6 Burlap (http://caucho.com/burlap/index.xtp)
简介:也许会奇怪,为什么Burlap也能够算得上远程协议。实际上,与Hessian实现方式基本相同的Burlap(前者为二进制,后者为文本), 在协议完整性上能够超过上述任一产品。目前我已经实现了JS调用Burlap服务的代码,是目前所有远程调用方式中最为优雅的实现。
7 XINS (XML Interface for Network Services)
地址:http://xins.sourceforge.net/index.html
简介:按照官方网站的说法,SOA + Java + XML + code_generation - complexity => XINS。这个庞大的东西需要定义一揽子描述文件然后才能在HTML中进行调用。从外观上看,这是最像样子的解决方案。对其了解不多,不做评价。
8 WebService, SOAP
简介:除了微软有一个webservice.htc控件,mozilla也有相应的webservice访问方式。因此,在HTML中访问webservice也是可行的。只是这种协议过于笨重,除非必要,没有人会在web客户端中使用。
初学者如何开发出一个高质量的J2EE系统(转)
摘自:http://nodex.javaeye.com/blog/358237
板桥里人 http://www.jdon.com 2005/06/20
| |
J2EE学习者越来越多,J2EE本身技术不断在发展,涌现出各种概念,本文章试图从一种容易理解的角度对这些概念向初学者进行解释,以便掌握学习J2EE学习方向。
首先我们需要知道Java和J2EE是两个不同概念,Java不只是指一种语言,已经代表与微软不同的另外一个巨大阵营,所以Java有时是指一种软件系统的流派,当然目前主要是.NET和Java两大主流体系。
J2EE可以说指Java在数据库信息系统上实现,数据库信息系统从早期的dBase、到Delphi/VB等C/S结构,发展到B/S(Browser浏览器/Server服务器)结构,而J2EE主要是指B/S结构的实现。
J2EE又是一种框架和标准,框架类似API、库的概念,但是要超出它们。如果需要详细了解框架,可先从设计模式 开始学习。
J2EE是一个虚的大的概念,J2EE标准主要有三种子技术标准:WEB技术、EJB技术和JMS,谈到J2EE应该说最终要落实到这三个子概念上。
这三种技术的每个技术在应用时都涉及两个部分:容器部分和应用部分,Web容器也是指Jsp/Servlet容器,你如果要开发一个Web应用,无论是编译或运行,都必须要有Jsp/Servlet库或API支持(除了JDK/J2SE以外)。
Web技术中除了Jsp/Servlet技术外,还需要JavaBeans或Java Class实现一些功能或者包装携带数据,所以Web技术最初裸体简称为Jsp/Servlet+JavaBeans系统。
谈到JavaBeans技术,就涉及到组件构件技术(component),这是Java的核心基础部分,很多软件设计概念(设计模式)都是通过JavaBeans实现的。
JavaBeans不属于J2EE概念范畴中,如果一个JavaBeans对象被Web技术(也就是Jsp/Servlet)调用,那么JavaBeans就运行在J2EE的Web容器中;如果它被EJB调用,它就运行在EJB容器中。
EJB(企业JavaBeans)是普通JavaBeans的一种提升和规范,因为企业信息系统开发中需要一个可伸缩的性能和事务、安全机制,这样能保证企业系统平滑发展,而不是发展到一种规模重新更换一套软件系统。
至此,JavaBeans组件发展到EJB后,并不是说以前的那种JavaBeans形式就消失了,这就自然形成了两种JavaBeans技术:EJB 和POJO,POJO完全不同于EJB概念,指的是普通JavaBeans,而且这个JavaBeans不依附某种框架,或者干脆可以说:这个 JavaBeans是你为这个应用程序单独开发创建的。
J2EE应用系统开发工具有很多:如 JBuilder、Eclipse等,这些IDE首先是Java开发工具,也就是说,它们首要基本功能是可以开发出JavaBeans或Java class,但是如果要开发出J2EE系统,就要落实到要么是Web技术或EJB技术,那么就有可能要一些专门模块功能(如eclipse需要 lomboz插件),最重要的是,因为J2EE系统区分为容器和应用两个部分,所以,在任何开发工具中开发J2EE都需要指定J2EE容器。
J2EE容器分为WEB容器和EJB容器,Tomcat/Resin是Web容器;JBoss是EJB容器+Web容器等,其中Web容器直接使用 Tomcat实现的。所以你开发的Web应用程序可以在上面两种容器运行,而你开发的Web+EJB应用则只可以在JBoss服务器上运行,商业产品 Websphere/Weblogic等和JBoss属于同一种性质。
J2EE容器也称为J2EE服务器,大部分时它们概念是一致的。
如果你的J2EE应用系统的数据库连接是通过JNDI获得,也就是说是从容器中获得,那么你的J2EE应用系统基本与数据库无关,如果你在你的J2EE 应用系统耦合了数据库JDBC驱动的配置,那么你的J2EE应用系统就有数据库概念色彩,作为一个成熟需要推广的J2EE应用系统,不推荐和具体数据库耦 合,当然这其中如何保证J2EE应用系统运行性能又是体现你的设计水平了。
衡量J2EE应用系统设计开发水平高低的标准就是:解耦性;你的应用系统各个功能是否能够彻底脱离?是否不相互依赖,也只有这样,才能体现可维护性、可拓展性的软件设计目标。
为了达到这个目的,诞生各种框架概念,J2EE框架标准将一个系统划分为WEB和EJB主要部分,当然我们有时不是以这个具体技术区分,而是从设计上抽象为表现层、服务层和持久层,这三个层次从一个高度将J2EE分离开来,实现解耦目的。
因此,我们实际编程中,也要将自己的功能向这三个层次上靠,做到大方向清楚,泾渭分明,但是没有技术上约束限制要做到这点是很不容易的,因此我们还是必须借助J2EE具体技术来实现,这时,你可以使用EJB规范实现服务层和持久层,Web技术实现表现层;
EJB为什么能将服务层从Jsp/Servlet手中分离出来,因为它对JavaBeans编码有强制的约束,现在有一种对JavaBeans弱约束,使用Ioc模式实现的(当然EJB 3.0也采取这种方式),在Ioc模式诞生前,一般都是通过工厂模式来对JavaBeans约束,形成一个服务层,这也是是Jive这样开源论坛设计原理之一。
由此,将服务层从表现层中分离出来目前有两种可选架构选择:管理普通JavaBeans(POJO)框架(如Spring、JdonFramework )以及管理EJB的EJB框架,因为EJB不只是框架,还是标准,而标准可以扩展发展,所以,这两种区别将来是可能模糊,被纳入同一个标准了。 但是,个人认为:标准制定是为某个目的服务的,总要牺牲一些换取另外一些,所以,这两种架构会长时间并存。
这两种架构分歧也曾经诞生一个新名词:完全POJO的系统也称为轻量级系统(lightweight),其实这个名词本身就没有一个严格定义,更多是一 个吸引人的招牌,轻量是指容易学习容易使用吗?按照这个定义,其实轻量Spring等系统并不容易学习;而且EJB 3.0(依然叫EJB)以后的系统是否可称为轻量级了呢?
前面谈了服务层框架,使用服务层框 架可以将JavaBeans从Jsp/Servlet中分离出来,而使用表现层框架则可以将Jsp中剩余的JavaBeans完全分离,这部分 JavaBeans主要负责显示相关,一般是通过标签库(taglib)实现,不同框架有不同自己的标签库,Struts是应用比较广泛的一种表现层框 架。
这样,表现层和服务层的分离是通过两种框架达到目的,剩余的就是持久层框架了,通过持久层的框架将数据库存储从服务层中分离出来是其目的,持久层框架有两种方向:直接自己编写JDBC等SQL语句(如iBatis);使用O/R Mapping技术实现的Hibernate和JDO技术;当然还有EJB中的实体Bean技术。
持久层框架目前呈现百花齐放,各有优缺点的现状,所以正如表现层框架一样,目前没有一个框架被指定为标准框架,当然,表现层框架现在又出来了一个JSF,它代表的页面组件概念是一个新的发展方向,但是复杂的实现让人有些忘而却步。
在所有这些J2EE技术中,虽然SUN公司发挥了很大的作用,不过总体来说:网络上有这样一个评价:SUN的理论天下无敌;SUN的产品用起来撞墙;对 于初学者,特别是那些试图通过或已经通过SUN认证的初学者,赶快摆脱SUN的阴影,立即开溜,使用开源领域的产品来实现自己的应用系统。
最后,你的J2EE应用系统如果采取上面提到的表现层、服务层和持久层的框架实现,基本你也可以在无需深刻掌握设计模式的情况下开发出一个高质量的应用系统了。
还要注意的是: 开发出一个高质量的J2EE系统还需要正确的业务需求理解,那么域建模提供了一种比较切实可行的正确理解业务需求的方法,相关详细知识可从UML角度结合理解。
当然,如果你想设计自己的行业框架,那么第一步从设计模式开始吧,因为设计模式提供你一个实现JavaBeans或类之间解耦参考实现方法,当你学会了 系统基本单元JavaBean或类之间解耦时,那么系统模块之间的解耦你就可能掌握,进而你就可以实现行业框架的提炼了,这又是另外一个发展方向了。
以上理念可以总结为一句话:
J2EE开发三件宝: Domain Model(域建模)、patterns(模式)和framework(框架)。
利用JQuery实现更简单的Ajax跨域请求(转)
摘自:http://www.cnblogs.com/yjmyzz/archive/2008/09/23/1296818.html
利用JQuery实现更简单的Ajax跨域请求
前一阵发过一篇利用ExtJs的ScriptTagProxy实现Ajax跨域请求的文章(http://www.cnblogs.com/yjmyzz/archive/2008/09/14/1290789.html),这几天看了一下Jquery,发现如果用JQuery中的getScript其实更简单(jquery 1.2.6版本)
这里给出代码,希望对Ajax跨域感到棘手的朋友有所帮助:
<html>
<head>
<title>JQuery学习</title>
<script src="jquery-1.2.6.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
var oBtnTest = $("#btnTest");
oBtnTest.click(function(){
oBtnTest.disabled = true;
var oResult = $("#result");
oResult.html("loading
").css("color","red");
jQuery.getScript("http://app.cntvs.com/test/js.txt",
function(){
oResult.html("name:" + jimmy.name + "<br/>email:" + jimmy.email).css("color","black");
oBtnTest.disabled = false;
});
});
});
</script>
</head>
<body>
<button id="btnTest">BtnTest</button>
<div id="result"></div>
</body>
</html>
远程服务器端js.txt的内容为:
var jimmy = {name:"jimmy.yang",email:jimmy.yang@163.com}
感觉是不是比ExtJs的ScriptTagProxy还要简洁? 个人感觉Jquery简单明了,短小精干,ExtJs功能强大,组件丰富!
欢迎转载,但请保留来源:菩提树下的杨过 http://www.cnblogs.com/yjmyzz/archive/2008/09/23/1296818.html
2003年以来网页尺寸增长3倍
2003年以来,网页的平均尺寸已经增长3倍。从2003到2008,网页的平均尺寸从93.7K增至312K,增幅233%。同时,在这5年之 内,网页中的平均对象数量翻番,从25.7个增长到49.9个。结合更早的数据,从1995年以来,网页平均尺寸已增长22倍,而网页中平均对象数量也增 长了21.7倍。
2007年全球前1000个最受欢迎网页的增长情况
在过去的1年(从2006年12月到2007年12月),全球最受欢迎的1000个网页尺寸平均增长24.2%,从250K 增长至310.4K,根据这个增长速度,到2008年末,这一数字可能超过385K。而网页中的对象的数量增长了14.5%,从平均44.2个增长到 50.6个。
页面响应时间趋势
从2003到2008,窄带用户(56K Modem 与 ISDN 用户)要忍受页面响应速度迟缓越来越严重。相反,宽带用户却感受到逐渐改善的响应速度,从2006年2月的2.8秒到2008年2月的2.33秒。
页面构成元素的统计(2006年)
Ryan Levering 和 Michal Cutler 在2006年对21500个非 Frame 型网页进行了统计,发现,这些网页平均包含474个单词,281个 HTML 标签,41个链接,其中有10个是站外链接,他们还发现,平均页面高度为1440像素,是屏幕高度的两倍,当页面打开的时候,用户看到最多的是图形,而不 是文字,图形是网页中最主要的对象,图形是页面打开速度缓慢的最主要因素。
2007年的变化
2007的类似统计发现,虽然 CSS 已经被广泛采用,但仍有62.6%的页面使用 table 布局,32.8%的网页使用 font 标签,然而,平均 table 嵌套深度和2006年比已经减半,从 2.95级 下降到1.47级。过分复杂的嵌套表格会降低页面渲染速度。和2006年相比,2007年页面中平均 HTML 元素数量翻番,从281个到592.6个。
JavaScript 的使用情况
2007年,84.8%的网页使用了脚本,外部脚本的平均尺寸约为8K,压缩后约为6K。总的脚本尺寸为68K,压缩后为49K。外部脚本的平均数量为7个。
CSS的使用情况
在2007年的统计中,82.4%的网页使用了链接标签,54.5%的使用了式样标签(平均含2.27个 内部式样标签),外部式样表的平均尺寸为6K, 压缩后为4K,总式样表的尺寸为15K,压缩后为10K。
图片的使用情况
2007年的统计显示,91.6%的网页使用了图片,各种不同格式图片的使用情况见下表。
| 图片格式 | 2006 | 2007 |
|---|---|---|
| GIF | 77.9% | 84.6% |
| JPEG | 55.8% | 64.5% |
| PNG | 7.2% | 32.2% |
| BMP | 0.8% | - |
多媒体内容的增长趋势
流媒体的使用几乎按每年100%的速度增长,从2000年到2005年,流媒体文件的容量增长了600%,87%的流媒体内容在播放的前10秒内被 用户中断,然而它们浪费了20%的服务器带宽。统计还显示,3%的流媒体为视频,却占用了98.6%的带宽,10%最受欢迎的视频来自 YouTube,抢占了80%的眼球。
1997年,90%的视频都不超过45秒,而2005年,视频的平均长度为120秒,到了2007年,长度增长为192.6秒,视频的比特率从 2005年的200K增长为2007年的328K(YouTube),因此,2007年末,视频内容的平均尺寸为63M,在YouTube,平均尺寸为 10M,每天新增的视频文件为65000个。
本文国际来源:http://www.websiteoptimization.com/speed/tweak/average-web-page/
中文翻译来源:COMSHARP CMS 官方网站
24 个漂亮的个性化 HTML 表单技术
HTML 表单对象在不同浏览器渲染方式并不一致,尽管一些对象,如 textbox 和 textarea 可以通过 CSS 在不同浏览器获得一致的外观,其它多数无法通过CSS 控制外观的对象在有些浏览器中看上去十分丑陋,本文精选了24个对表单对象进行个性化定制的技术。
Checkbox 与 Radio Buttons 相关
1.) FancyForm
FancyForm 是一个非常强大的 JavaScript 库,可以作为 checkbox 和 radio button 的替代品,能生成非常漂亮的 checkbox 和 radio button,并支持几乎所有浏览器,该 JavaScript 库需要 MooTools JavaScript 框架的支持。
2.) CRIR: Checkbox & Radio Input Replacement
这个 JavaScript 和 CSS 组合可以隐藏表单中的 checkbox 和 radio button,并允许你使用 CSS 对 checkbox 与 radio button 的设置式样模拟 checkbox 和 radio button。表单的功能不会改变,仍可以收集 checkbox 和 radio button 的数据值,checkbox 和 radio button 的标签会触发那些隐藏的对象。
3.) Ryan Fait's Custom Checkboxes & Radio Buttons
这个 JavaScript 和 CSS 组合允许你使用自己的图片模拟 checkbox,radio button 以及 select 列表控件。这个很周到的 JavaScript 库还可以在浏览器禁用了 JavaScript 的时候,自动用回传统的表单控件。
4.) ARC - Adam's Radio/Checkbox Customization
该脚本会对表单中的 checkbox 和 radio button 及其标签进行探测,一旦发现,就会使用基于 CSS 式样的图形标签替换这些控件。
5.) prettyCheckboxes
6.) jQuery checkbox
7.) 一些用来定制 checkbox 和 radion button 的文章
- Custom Radio Button Implement With jQuery
- slayeroffice Custom Checkbox Elements
- Customized Html Controls: Creating Custom Checkbox
- Styled Form Controls
- Fancy Checkboxes and Radio Buttons
- Inside Technique : Custom Checkboxes
选择和下拉框(Select / Dropdown Box)相关
1.) JavaScript Image Combobox (JavaScript 图形化 Combobox)
2.) jQuery Dropdown Check List
3.) Custom Select With Icons
4.) ComboBoxes Using MooTools
5.) Select Replacement
6.) 更多 select box 定制技术 (基于 JavaScript)
更多 Form 控件对象
1.) Custom Form Elements (CFE)
Custom Form Elements 集合了各种技术,增强 XHTML Web 表单控件对象,基于 javaScript 和 CSS 实现更漂亮的效果,提高易用性与可访问性。支持绝大多数主流浏览器。
2.) Emblematiq Niceforms
Niceforms 是一个可以替代几乎所有 web 表单对象的 JavaScript 库。你可以使用默认的主题,甚至可以开发自己的主题。
3.) jQuery Plugin: jNice
本文来源:http://www.netwaver.com/23/24-html-form-elements-customization-techniques/
中文翻译来源:COMSHARP CMS 官方网站