posts - 120,  comments - 19,  trackbacks - 0
 

CSS中,一个很少被提及的优点就是能够层叠背景图片,允许它们之间通过"滑动"和层叠来创造出特定的效果。CSS2目前的状况要求每个背景图片都分别有与之相对应的HTML元素。在通常情况下,组成通用界面的典型标记已经提供了一些我们可以使用的元素。

其 中的一个例子就是标签导航栏(tabbed navigation)。随着[标签导航]的使用率不断上升,它已逐渐成为了站点导航的主流方式,现在是时候来讨论一下对标签导航栏的控制了。既然CSS 被广泛地支持,我们就可以用它来优化站点标签的质地和外观。你很可能会想到,CSS可以驯服平坦的无序列表。可能你已经见到过一些样式化为标签的列表,比如下面这个:

如果我们采用与上面完全相同的标记,但却把它们变成了下面的样子,该如何去做呢:

在这里,仅仅用非常简单的样式就可以实现。

创新之道

我所见过的许多基于CSS的标签都受到了一些共同特性的限制:单色的矩形块,可能在当前标签上加了轮廓,或者边框;在鼠标掠过时改变矩形的颜色等等。这就是CSS能为我们提供的全部吗?仅仅是成堆的单色方块?

早 在CSS被广泛采用之前,我们就能够看到许多在导航设计上的创新。创新的外形,可控的色彩混合,以及对现实世界中物力表面的模仿。但是这些设计通常都依赖 于将文字内嵌于图片的复杂结构或多层的表格嵌套。编辑标签上的文字或者改变它们的顺序都会引起繁重的工作。文字的缩放更是不可能,不然就会引起严重的页面 布局错误。

单纯的文字导航要比嵌入文字的图片式导航更加易于管理并且加载更迅速。而且,虽然我们可以给每个图片都加上alt属性, 但是单纯的文字导航更具有可读性,因为对于视力不好读者,这些文字都是可缩放的。也正因为如此,由CSS样式化的文字的导航栏再次成为网页设计者们的选 择,并不足为奇。但是到目前为止,大多数基于CSS的标签设计,只是后退了一步,回到了我们曾经的做法--当然这些是无法被优秀的设计作品采用的。采用一 项新技术(比如CSS)应该能够让我们创作出一些更好的东西,而不至于失去先前的表格或者图片式标签所能表现的质地。

“滑动门”技术

只 要我们用两片分离的背景图片,就能够创造出精美的手工界面,并且具有高度的灵活性,可随文字的缩放而自动适应。试想一下,左右两幅图片,就像左右两扇滑动 门一样,构成了一扇完整的门。将这两扇门推近,重叠的部分多一些,就可以适应一个比较狭窄的空间,而如果将它们拉开,重叠的部分减少,就可以满足较宽的空 间,正如下图所示:

在 这个例子中,一幅图片盖住了另一幅的某些部分。假设每幅图片的边缘都有些独特的形状,例如标签的圆角,我们不希望这些边缘被它前方图片盖住。为了防止这种 情况发生,我们将放置在前方(以左边为例)的图片制作得尽可能地窄,但是保证它能够完整地显示出边缘上的独特形状。以圆角标签为例,我们将前方的图片制作 到仅与圆角的部分同宽即可:

如 果目标物由于不同文字或文字类型而变得比上图所示的宽度更大,那么这两幅图就会被拉开,出现一个非常不美观的缺口。 这时就需要我们对可能的扩展性进行预测。 在用户缩放字体的时候,目标物会增大多少?实际上,我们至少应该为文字的缩放而作出300%的可伸缩性准备。 我们需要将背景图扩大到足够弥补缺口。 对于这些例子,我们将把后面的图像 ( 右边) 制作为 400 x150 图素, 前面的图像制作为 9 x150 图素。

要记住,背景图片只能在它所应用的元素的“门前”出现 [内容区域+补丁区域(padding)]。 这两幅图被分别安放到他们所应用的元素外侧。 而这些背景的可见部分交叠在一起构成了一个完整的标签样式:

如果标签被扩大的话,这两幅图就分别向两侧滑动,每一幅都更多地被显示出来,以满足更宽的“门”的需求。

就 比如我用Photoshop制作了两幅平滑的,略带3D效果的个性化标签图片,正如文章开头的图片所示。在另一个色彩明亮一点的版本中,这两幅图片的填充 色变的更亮,边缘的阴影更暗,这是为“当前”标签准备的。为了给上面所述的技术作示范,我们需要扩展标签背景的覆盖区域,并把它切成了两片:

那个明亮一些的版本也需要这样做,一旦这些图片都作好了(1, 2, 3, 4),我们就可以进入CSS标记部分了。

创建标签

当发现了如何利用CSS创建横向列表后,你可能会注意到,至少有两种方法能够将一组列表排列成一行。一种是用内嵌方框,另一种是利用浮动属性。它们各有利弊。而且每一种方法都会遇到CSS中非常奇怪的方面,很容易让人迷惑。

第一种方法,也是最常用的方法,就是将列表的项目属性设置为“内嵌”,这种方法由于非常简便而具有相当的吸引力。然而,对于我们将要讨论的“滑动门”技术来说,这种内嵌的方法在某些特定的浏览器上会出现渲染问题。第二种方法,也是我们所要关注的,是利用“浮动”属性将列表项排成一横行。而浮动属性也会同样令人无所适从。它们那些看来不协调的行为并不遵从自然逻辑。尽管如此,处理多个浮动元素的基本认识以及将它们确实可靠地处理为可用元素的方法依然会取得另人惊奇的效果。

我 们会在一个浮动的容器中创建多个浮动的元素。这样做是为了使外部容器紧密围绕在内容元素的周围。利用这种方法,我们可以给标签后的空白加上背景。要切记, 在标签之后布局的元素,一定要在CSS中用clear属性重新定位它的位置。这样是为了防止浮动标签影响布局中的其他页面元素的位置。

那么,现在就让我们看看这些标记语言:

<div id="header">
<ul>
<li><a href="#">Home</a></li>
<li id="current"><a href="#">News</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>

事实上,头部(#header)的层可能同时会包含网站的LOGO以及一个搜索框。在这个的例子中,我们会精简每个锚点(anchor)中的href值。显然,正常情况下这些值应该为锚点地址或者文件位置。

我 们最初的样式化就是让头部(#header)的层浮动。这样做是为了让这个作为容器的层能够真正地将它所容纳的那些浮动列表项包在内部。由于这个元素是浮 动的,我们需要给它标记为“100%”的宽度。再给它加上临时的黄色背景来确认这一父容器的伸缩能够正好填满标签的整个背景区域。同时设置默认文字的属 性,以保证容器内的文字看起来一致:

#header {
float:left;
width:100%;
background:yellow;
font-size:93%;
line-height:normal;
}

现在,我们将无序列表默认的内外补丁(padding)都设置为0,并将列表的项目符号去掉,给他们加上向左浮动的属性:

#header ul {
margin:0;
padding:0;
list-style:none;
}
#header li {
float:left;
margin:0;
padding:0;
}

我们将锚点的显示属性设置为“块(display:block;)”,这样在控制它们的时候就不必担心内嵌方框的问题了:

#header a {
display:block;
}

接下来,我们将右侧的图片添加到列表项的背景中(添加的部分用粗体显示):

#header li {
float:left;
background:url("norm_right.gif")
no-repeat right top;

margin:0;
padding:0;
}

在加入左边的图片之前,我们先停下来看看到目前为止,效果一究竟是怎样的。

- - -

现在,我们就可以将在上方显示的左侧图片加入到锚点(内层元素)的背景中,与此同时,我们也加入了内补丁,将标签扩展,给文字与标签的边缘间添加一些空白:

#header a {
display:block;
background:url("norm_left.gif")
no-repeat left top;
padding:5px 15px;

}

这些变化出现在效果二中。 看,现在标签已经有了大体的形状。对于这一点,IE5/Mac的用户可能会感到奇怪了,“这是怎么了,为什么标签会堆叠着伸展地穿过整个屏幕?”别急,我 们很快就要帮你解决这些问题。那么现在,尽可能地跟着我们继续下去,如果手头有其他浏览器的话,暂时先换一个来继续往下看。IE5/Mac的问题一定会得 到很好的解决。

- - -

这时,普通的标签背景已经做好了,接下来,需要为“当前”标签加上背景。我们通过为当前标签内的锚点加上id=“current”来实现对它的定位。由于并不需要改变当前标签的其他设置,只需要更换背景,所以我们仅用以下的代码即可:

				#header #current {
background-image:url("norm_right_on.gif");
}
#header #current a {
background-image:url("norm_left_on.gif");
}

在标签的下方,我们想要有边框出现,但是如果用对父容器#header设置下边框的的方法,那么就无法消除当前标签的下边框。因此,我们用创建一幅新图片的方法来代替,这幅图片的底部包含了我们想要的边框,同时将图片的颜色设置为少许的梯度,就像下面这幅:

我们将这幅图片用于容器#header的背景(代替了我们刚才所用的黄色),并将它设置为底部对齐,给容器设置与之相应的背景色。同时,将body的内补丁移除,给列表ul的上,左,右侧,分别加上10像素的内补丁:

#header {
float:left;
width:100%;
background:#DAE0D2 url("bg.gif")
repeat-x bottom;

font-size:93%;
line-height:normal;
}
#header ul {
margin:0;
padding:10px 10px 0;
list-style:none;
}

要 完成标签导航栏,还需要将当前标签的下边框消除。你可能会想到,给其他标签加上与#header背景色完全相同的下边框,然后给当前标签加上一个白色的下 边框。然而,那些观察非常仔细的人还是会在这样的做法中发现些许破绽。我们用给锚点加上内补丁的方法来替代它,这样就可以创建出完美的方形边角了。在下面 经过放大的示意图中就可以看出区别:

为了实现这样的效果,我们为其他标签设置了4像素的内补丁,而当前标签的设置为5像素:

#header a {
display:block;
background:url("norm_left.gif")
no-repeat left top;
padding:5px 15px 4px;
}
#header #current a {
background-image:url("norm_left_on.gif");
padding-bottom:5px;
}

上面的代码保证了在效果三中下边框只出现在其他标签上,而不出现在当前标签上。

打磨完工

敏 锐的目光可能会发现,在上一效果图中,圆角标签的角落上仍然留有白色的色块。这些前方图片上的不透明的边角挡住了导航栏的背景。从理论上说,我们可以将这 些边角的背景修改为与导航栏背景色一致来达到看似透明的效果。但是我们的导航标签可能会改变高度,超过背景的范围,或者背景色出现更改。因此,不如直接将 前方背景的边角设置为透明,这样更为方便。如果圆角是抗锯齿的话,我们可以让它的边缘以背景色进行柔化。

现在边角透明了,可是右侧图片的一部分出现在左侧透明的边角后。为了抵消它,我们在项目列表的左侧加上与左侧图片相同大小的9像素的内补丁。由于项目列表加上了左内补丁,就需要在锚点的左侧减去一部分内补丁,以保证文字的居中(15px - 9px = 6px):

#header li {
float:left;
background:url("right.gif")
no-repeat right top;
margin:0;
padding:0 0 0 9px;
}
#header a {
display:block;
background:url("left.gif")
no-repeat left top;
padding:5px 15px 4px 6px;
}

然而,并不能就这样把它放在那儿,因为左侧的图片由于刚才加上的9像素的内补丁而被推开了。既然左右两幅图片的内边缘已经相连了,我们就没必要非将左侧的图片保持在上方。因此,我们交换一下左右两幅图片,让他们应用到对方的元素上。当然,当前标签也需要这样做:

#header li {
float:left;
background:url("left.gif")
no-repeat left top;
margin:0;
padding:0 0 0 9px;
}
#header a, #header strong, #header span {
display:block;
background:url("right.gif")
no-repeat right top;
padding:5px 15px 4px 6px;
}
#header #current {
background-image:url("left_on.gif");
}
#header #current a {
background-image:url("right_on.gif");
padding-bottom:5px;
}

一旦这样做好了,就完成了效果四。 注意,为了使边角透明而做的这一系列调整使得每个标签的左侧都有一小部分不可点击。这一非活动区域是在文字之外的,所以并不是非常引人注目。并不是每个站 点都要求标签背景是透明的,如果不希望有这一小部分非活动区域的话,尽可以用纯色的背景和方角来代替透明和圆角。在我们的例子中,依然保持透明和圆角的效 果。

- - -

剩下的调整就很简单了,我们一并来完成:将标签字体设置为粗体,正常标签的字体颜色设置为棕色,当前标签颜色设置为深灰色,去掉下滑线,将鼠标悬浮时的字体颜色同样设置为深灰色。这些增加的变化在效果五中表现出来。

一致性的特例

在效果二之后,我们认识到,在IE5/Mac中,标签被扩大到与页面同宽,导致了他们垂直堆叠在下一个的上方,这并不是我们想要的效果。

在大多数浏览器中,浮动会引起收缩的效果-它会收缩到仅能容纳其所含元素的最小空间。如果浮动元素中包含的是图片,那么它会收缩到与图片大小相同,如果仅包含文字的话,它会收缩到与最长的不换行文字同宽。

而 在IE5/Mac中,当一个自动调整宽度的块级元素(block-level element)被插入到另一浮动元素中时,就会出现问题。其他浏览器依然会尽可能地收缩浮动元素,并不理会它所容纳的块级元素。但是IE5/Mac在这 种情况下并不收缩浮动元素,反而将浮动和块级元素扩展到最大的可用宽度。在这种情况下,我们需要将锚点也同时浮动,但是仅在IE5/Mac中这样做,以免 影响到其他浏览器。之后,我们就可以用反斜杠注释法(Commented Backslash Hack)来隐藏这些代码,使其仅在IE5/Mac下工作:

#header a {
float:left;
display:block;
background:url("right.gif")
no-repeat right top;
padding:5px 15px 4px 6px;
text-decoration:none;
font-weight:bold;
color:#765;
}
/* Commented Backslash Hack
hides rule from IE5-Mac \*/
#header a {float:none;}
/* End IE5-Mac hack */

这回,IE5/Mac浏览器应该显示我们所希望的效果了,见效果六。 在非IE5/Mac浏览器中,应该没有任何变化。注意,IE5.0/Mac中出现了很多渲染错误,在IE5.1中已得到更正。因此,在IE5.0中出现的 错误已经超出了我所应该作为特例而修改的范畴了。由于现在升级到5.1并不困难,而OS 9 Macs用户中仍然使用IE5.0的已经相当的少了。

适用性

我 们刚刚看过如何运用滑动门技术创建纯文本的导航标签,它们是由一系列锚点组成的无序列表标记而成,并赋予一些个性化的样式。它加载快速,易于维护,并且可 以在不破坏原有设计的同时对其文本进行大比例的缩放。那么这项技术足够灵活吗?可以胜任创建各种类型的精美导航栏的任务吗?

无需怀疑,这项技术的使用只局限于我们的想象力。最终效果只展示出了其中一种可能性。但是我们不应被一种设计局限了自己的想法.

例如,标签没必要非得对称。我很快就制作出这些标签的2.0版, 在这个版本中,并没有使用3D阴影效果,这样更利于展示平面色彩,有角的边缘,以及更宽,更细致的左边框。正如2.0版所示,我们甚至可以交换左右两幅图 片的位置,当然,这些均取决于你的设计。通过细致的计划和巧妙的图片处理,我们尽可以将下边框彻底放弃,这更有利于标签图片与背景的搭配,就如在我充满灵 感的3.0版中所表现的那样。如果你的浏览器支持在样式表间切换的话,你甚至可以看到这个主文件在三个不同的版本的样式间切换(注:Firefox和Opera支持样式切换)。

其 他我们没有讨论到的效果可以基于这项技术使用。在一路举来的这个例子中,我只改变了鼠标悬浮时的文字颜色,但除此之外你还可以将整个背景替换掉,以创造出 更为有趣的翻转效果。只要有两个嵌套的HTML元素标记,就可以利用CSS为他们加上背景,创造出我们甚至想都没想过的的效果。在这个例子中我制作了一个 水平的导航标签,但是滑动门技术在其他许多情况下都是可以使用的。

那么,会用它做什么呢?

posted @ 2006-08-16 17:01 阿成 阅读(783) | 评论 (0)编辑 收藏

第一篇、http://www.blueidea.com/bbs/newsdetail.asp?id=996916(里面有很多例子)

第二篇、彻底明白Java的IO系统(文摘)---JAVA之精髓IO流
一. Input和Output
1. stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。在Java的IO中,所有的stream(包括Input和Out stream)都包括两种类型:
1.1 以字节为导向的stream
以字节为导向的stream,表示以字节为单位从stream中读取或往stream中写入信息。以字节为导向的stream包括下面几种类型:
1) input stream:
1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
2) StringBufferInputStream:把一个String对象作为InputStream
3) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作
4) PipedInputStream:实现了pipe的概念,主要在线程中使用
5) SequenceInputStream:把多个InputStream合并为一个InputStream
2) Out stream
1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中
2) FileOutputStream:把信息存入文件中
3) PipedOutputStream:实现了pipe的概念,主要在线程中使用
4) SequenceOutputStream:把多个OutStream合并为一个OutStream
1.2 以Unicode字符为导向的stream
以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream中写入信息。以Unicode字符为导向的stream包括下面几种类型:
1) Input Stream
1) CharArrayReader:与ByteArrayInputStream对应
2) StringReader:与StringBufferInputStream对应
3) FileReader:与FileInputStream对应
4) PipedReader:与PipedInputStream对应
2) Out Stream
1) CharArrayWrite:与ByteArrayOutputStream对应
2) StringWrite:无与之对应的以字节为导向的stream
3) FileWrite:与FileOutputStream对应
4) PipedWrite:与PipedOutputStream对应
以 字符为导向的stream基本上对有与之相对应的以字节为导向的stream。两个对应类实现的功能相同,字是在操作时的导向不同。如 CharArrayReader:和ByteArrayInputStream的作用都是把内存中的一个缓冲区作为InputStream使用,所不同的 是前者每次从内存中读取一个字节的信息,而后者每次从内存中读取一个字符。
1.3 两种不现导向的stream之间的转换
InputStreamReader和OutputStreamReader:把一个以字节为导向的stream转换成一个以字符为导向的stream。
2. stream添加属性
2.1 “为stream添加属性”的作用
运用上面介绍的Java中操作IO的API,我们就可完成我们想完成的任何操作了。但通过FilterInputStream和FilterOutStream的子类,我们可以为stream添加属性。下面以一个例子来说明这种功能的作用。
如果我们要往一个文件中写入数据,我们可以这样操作:
FileOutStream fs = new FileOutStream(“test.txt”);
然 后就可以通过产生的fs对象调用write()函数来往test.txt文件中写入数据了。但是,如果我们想实现“先把要写入文件的数据先缓存到内存中, 再把缓存中的数据写入文件中”的功能时,上面的API就没有一个能满足我们的需求了。但是通过FilterInputStream和 FilterOutStream的子类,为FileOutStream添加我们所需要的功能。
2.2 FilterInputStream的各种类型
2.2.1 用于封装以字节为导向的InputStream
1) DataInputStream:从stream中读取基本类型(int、char等)数据。
2) BufferedInputStream:使用缓冲区
3) LineNumberInputStream:会记录input stream内的行数,然后可以调用getLineNumber()和setLineNumber(int)
4) PushbackInputStream:很少用到,一般用于编译器开发
2.2.2 用于封装以字符为导向的InputStream
1) 没有与DataInputStream对应的类。除非在要使用readLine()时改用BufferedReader,否则使用DataInputStream
2) BufferedReader:与BufferedInputStream对应
3) LineNumberReader:与LineNumberInputStream对应
4) PushBackReader:与PushbackInputStream对应
2.3 FilterOutStream的各种类型
2.2.3 用于封装以字节为导向的OutputStream
1) DataIOutStream:往stream中输出基本类型(int、char等)数据。
2) BufferedOutStream:使用缓冲区
3) PrintStream:产生格式化输出
2.2.4 用于封装以字符为导向的OutputStream
1) BufferedWrite:与对应
2) PrintWrite:与对应
3. RandomAccessFile
1) 可通过RandomAccessFile对象完成对文件的读写操作
2) 在产生一个对象时,可指明要打开的文件的性质:r,只读;w,只写;rw可读写
3) 可以直接跳到文件中指定的位置
4. I/O应用的一个例子
import java.io.*;
public class TestIO{
public static void main(String[] args)
throws IOException{
//1.以行为单位从一个文件读取数据
BufferedReader in =
new BufferedReader(
new FileReader("F:\\nepalon\\TestIO.java"));
String s, s2 = new String();
while((s = in.readLine()) != null)
s2 += s + "\n";
in.close();

//1b. 接收键盘的输入
BufferedReader stdin =
new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Enter a line:");
System.out.println(stdin.readLine());

//2. 从一个String对象中读取数据
StringReader in2 = new StringReader(s2);
int c;
while((c = in2.read()) != -1)
System.out.println((char)c);
in2.close();

//3. 从内存取出格式化输入
try{
DataInputStream in3 =
new DataInputStream(
new ByteArrayInputStream(s2.getBytes()));
while(true)
System.out.println((char)in3.readByte());
}
catch(EOFException e){
System.out.println("End of stream");
}

//4. 输出到文件
try{
BufferedReader in4 =
new BufferedReader(
new StringReader(s2));
PrintWriter out1 =
new PrintWriter(
new BufferedWriter(
new FileWriter("F:\\nepalon\\ TestIO.out")));
int lineCount = 1;
while((s = in4.readLine()) != null)
out1.println(lineCount++ + ":" + s);
out1.close();
in4.close();
}
catch(EOFException ex){
System.out.println("End of stream");
}

//5. 数据的存储和恢复
try{
DataOutputStream out2 =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("F:\\nepalon\\ Data.txt")));
out2.writeDouble(3.1415926);
out2.writeChars("\nThas was pi:writeChars\n");
out2.writeBytes("Thas was pi:writeByte\n");
out2.close();
DataInputStream in5 =
new DataInputStream(
new BufferedInputStream(
new FileInputStream("F:\\nepalon\\ Data.txt")));
BufferedReader in5br =
new BufferedReader(
new InputStreamReader(in5));
System.out.println(in5.readDouble());
System.out.println(in5br.readLine());
System.out.println(in5br.readLine());
}
catch(EOFException e){
System.out.println("End of stream");
}

//6. 通过RandomAccessFile操作文件
RandomAccessFile rf =
new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
for(int i=0; i<10; i++)
rf.writeDouble(i*1.414);
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + ":" + rf.readDouble());
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
rf.seek(5*8);
rf.writeDouble(47.0001);
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + ":" + rf.readDouble());
rf.close();
}
}
关于代码的解释(以区为单位):
1区中,当读取文件时,先把文件内容读到缓存中,当调用in.readLine()时,再从缓存中以字符的方式读取数据(以下简称“缓存字节读取方式”)。
1b区中,由于想以缓存字节读取方式从标准IO(键盘)中读取数据,所以要先把标准IO(System.in)转换成字符导向的stream,再进行BufferedReader封装。
2区中,要以字符的形式从一个String对象中读取数据,所以要产生一个StringReader类型的stream。
4区中,对String对象s2读取数据时,先把对象中的数据存入缓存中,再从缓冲中进行读取;对TestIO.out文件进行操作时,先把格式化后的信息输出到缓存中,再把缓存中的信息输出到文件中。
5 区中,对Data.txt文件进行输出时,是先把基本类型的数据输出屋缓存中,再把缓存中的数据输出到文件中;对文件进行读取操作时,先把文件中的数据读 取到缓存中,再从缓存中以基本类型的形式进行读取。注意in5.readDouble()这一行。因为写入第一个writeDouble(),所以为了正 确显示。也要以基本类型的形式进行读取。
6区是通过RandomAccessFile类对文件进行操作。

第三篇、花1K内存实现高效I/O的RandomAccessFile类(http://www-128.ibm.com/developerworks/cn/java/l-javaio/index.html),解决RandomAccessFile类效率低下的问题,特别是“与JDK1.4新类MappedByteBuffer+RandomAccessFile的对比”部分讲了怎样用jdk自己的功能实现。

posted @ 2006-08-16 16:59 阿成 阅读(270) | 评论 (0)编辑 收藏


1.网页技术分为三个方面:静态网页、网页美工、动态网页。
2.DHTML(动态HTML)是一种通过各种技术的综合而得以实现的概念,包括三部分:HTML、Script(JavaScrip or VBScript)、CSS(Cascading Style Sheets)。
3.颜色“#rrggbb”六位十六进制数。
4.js删除提示
1)<a  href="#" onclick="return(confirm('删除后无法恢复,您确定删除吗?'))">删除</a>
2)JS
<a  href="#" >删除</a>
<script language="javascript" type="text/javascript">
function delete_confirm(){
 if(event.srcElement.outerText=="删除" || event.srcElement.value=="删除")
  event.returnValue=confirm("删除后将不能恢复,您确认执行删除操作么?");
 }
 document.onclick=delete_confirm;
</script>

5.点击按钮/链接弹出提示
1)<input type=button value="reload" onclick="javascript:reload()">
<script type="text/javascript">
function reload() {
  if (confirm("确认?"))
 {
 var url="#";
 window.location.href=url;
 }
}
2)<a  href="确认后的连接地址" onclick="return(confirm('想要的提示信息?'))">显示信息</a>

6.返回主页/前页
返回前页:使用OnClick="history.go(-1)"
返回主页:使用OnClick='top.location.href="index.jsp"'
<a href="javascript:history.back()">后退</a>
<a href="javascript:history.go()">前进</a>
<a href="javascript:location.reload()">刷新</a>

7.定时关闭网页
在head区加入
<SCRIPT LANGUAGE="javascript">
setTimeout('window.close();',2000);
</SCRIPT>
表示两秒后自动关闭窗口。

8. 背景音乐
显示操作面板:
在相应地方加<embed src="aladdin.mid" width="140" height="35" autostart=true controls="middleconsole">
不显示操作面板:
在页中任意地方加<embed src="aladdin.mid" hidden=true autostart=true loop=true>
或<embed src="aladdin.mid" autostart="true" loop="2" width="80" height="30">

9. 如何让浏览器正确显示word 文件格式?
为了正确处理word 等格式,你需要在HTML文件中设置好该文件类型
<meta http-equiv="Content-Type" content="application/msword">
还有其它经常设置的文件类型:
application/msword Microsoft Word Document
application/pdf PDF Document
application/wordperfect6.0 WordPerfect 6.0 Document
application/zip ZIP archive
audio/x-wav WAV audio format
audio/midi MIDI audio format
audio/x-pn-realaudio RealAudio
image/gif GIF image format
image/jpeg JPEG image format
image/png PNG image format
text/html HTML document
text/plain Plain text
video/mpeg MPEG video format
video/quicktime QuickTime video format
video/x-msvideo AVI video format

10. 链接的不同方式
在帧里显示:在链接处加target="main"语句,其中main为帧名
整页显示:在链接处加target="_top"语句
开新窗口:在链接处加target="resource window"语句,如<A HREF="index.htm" TARGET="resource window"></A>

11. 强制主页每次都不进行缓存,而从服务器上重读
在Head部分加
<MEAT HTTP-EQUIV="Pragma" CONTENT="no-cache">
这样一来,浏览器将不考虑cacke中的内容而强制重新读入您的页面,等于用户使用Reload。

12. 自动刷新
定时刷新:<META HTTP-EQUIV="Refresh" content="10; URL=http://自己的URL">
幻灯片效果:语句类似上面,但在页面1中URL指向页面2,而页面2指向页面3 ...
页面n指回页面1,即可实现循环显示页面的效果

13.提前载入图片
如果您的站点中后面的页有大图形需要显示,您不妨在第一页中提前载入。把语句:
<img src="image.jpg" width=0 height=0> ,其中width,height要设置为0, 放在第一页HTML中的任何地方。
如果您的访问者在第一页停留的时间足够长,当他进入第二页时,图象会立即显示出来

14. 自动连接
在预定时间后自动连入另一个指定的页面。
方法:
在<title>...</title>中加入以下一行:
<meta http-equiv="refresh" content="10"; url="otherpage.htm">
其中10代表10秒后自动连接。

15. 移动文字
这在主页上是常用的,其制作方法很简单。
<marquee>要移动的文字</marquee>
  1.移动 的方向:<direction=!> !=left, right
  2.移动的方式:<bihavior=!> !=scroll ,side,alternate
  3.循环次数:<loop=!> !=次数。若未指定则循环不止。
  4 循环速度:<scrollamount=!> !=数

16. 浮动背景(背景图像不滚动 )
当你拉住下拉条时,背景不动。
<body backgroud="#ffff" bgproperties="fixed">
或用CSS样式表定义:
<style type="text/css">
<!--
body { background-image: url(image/bg.gif); background-attachment: fixed}
-->
</style>

17. 让背景图像不平铺的CSS样式表定义:
<style type="text/css">
<!--
body { background-image: url(image/bg.gif); background-repeat: no-repeat}
-->
</style>
(不懂)18. 测试浏览器类别并自动装入不同的网页
目前微软和网景的浏览器并不能完全兼容所有网页,有的在某种浏览器里非常漂亮,而用其它浏览器查看时却一团糟。如果你需要测试浏览器,可以加入以下javascript代码并保存单独一个网页:
<script language="javascript">
function TestBrowser(){
ie = ((navigator.appName ==
"Microsoft Internet Explorer") & &
(parseInt(navigator.appVersion) >= 3 ))
ns = ((navigator.appName == "Netscape") & &
(parseInt(navigator.appVersion) >= 3 ))
if (ns) {
setTimeout(''location.href="nn4.htm"'',10);
} else {
setTimeout(''location.href="ie4.htm"'',10);
}
}
</script>
19. 定义本网页的关键字
在网页中加入关键字,可以供某些搜索站台机器人的使用,它们会利用该关键字为你的网站做索引,这样,当别人用关键字搜索网站时,如果你的网页包含该关键字,那么就可以被列出了,定义本网页关键字,可以加入以下代码:
<meta name="keywords" content="html,dreamweaver,flash,css">
  content 所包含的就是关键字,你可以自行设置。
  这里有个技巧,你可以重复某一个单词,这样可以提高自己网站的排行位置,如:
<meta name="keywords" content="dreamweaver,dreamweaver,dreamweaver">
20. 在网页中加入E-mail链接并显示预定的主题
<a href="mailto:renyang@mail.taiji.com.cn?cc=renyangok@yahoo.com.cn&subject=hello&body=hello">
21. 隐藏在状态栏里出现的链接信息
当指向一个链接时,该链接的信息会出现在浏览器状态栏里,如果需要隐藏信息,可以如下设置:
<a href="http://www.yhyhw.com" onMouseOver="window.status='none';return true">test</a>
  如果想要指向一个链接时,浏览器状态栏里出现特定的信息,把none 改成你需要的文字即可。
22.如何正确使用图片格式?
目前在网络上的图片准标准格式为JPG和GIF。当图片颜色数很多时,就选择JPG,它的压缩比高,而GIF适合颜色数少的图片。
23. 如何在网页上显示访问者系统信息?
把以下代码加入到<Body></Body>:
<script Language="javascript">
document.write(navigator.appVersion)
</script>
24. 如何点击一个链接同时在两个frame 内变化?
对于一个由topFrame、leftFrame、mainFrame 构成的页面,如果想在leftFrame 中点击链接,同时在其他两个frame 内变化,代码如下:
<a href="x1.htm" onclick="parent.topFrame.location.href=''x2.htm''" target="mainframe">
25. 打开一个新的浏览器窗口并设置窗口的属性
如果你需要在载入站点的同时,再打开另一个新窗口,加入以下代码即可:
<script language="javascript">
<!--
var gt = unescape('%3e');
var popup = null;
var over = "Launch Pop-up Navigator";
popup = window.open('', 'popupnav', 'width=160,height=160,resizable=1,
     status=yes,menubar=no,scrollbars=yes');
if (popup != null) {
     if (popup.opener == null) {
          popup.opener = self;
     }
    popup.location.href = 'pop.htm';}
//-->
</script>
期中pop.htm可以设置为你的htm文件,对于设置新窗口的属性,对照以下设置:
popup = window.open('', 'popupnav', 'width=200,height=170,resizable=1,scrollbars=auto');
width:宽,height:高,resizable:是否允许访客缩放新窗口,scrollbars:如果文本超过一屏,是否生成滚动条,status:是否显示状态栏,menubar:是否显示菜单,location:是否显示地址栏.
以上所有属性使用格式为:属性=yes或者no.而width和height两个属性为:width=#pixels,height=#pixels.
26. 打印按钮
<form>
<input name="Print" onClick="window.print();
return false" type="button" value="Print">
</form>
27. 查看源码按钮
<input type=button name="view" value="查看源码" onClick=''window.location="view-source:" +window.location.href'' style="font-size:9pt">
28. 如何去掉页面滚动条?
在body 中加入样式表控制,代码如下:
<body bgcolor="#000000" leftmargin="0" topmargin="0"
style="overflow-x: hidden; overflow-y: hidden; width: 100%">
29. 如何让站点自动跳转到另一页?
加入以下代码到HTML文件中即可:
<meta http-equiv="refresh" content="5;url=http://www.yhyhw.com/">
content中的"5"为停留的秒数,http://www.yhyhw.com/ 是将要跳转的页面。
30. 水平线、垂直线
插入HR很简单:<hr size="1">。如何让它垂直呢,更简单:<hr size="100" width="1">
31. 如何让下拉式菜单中的链接来打开一个新的窗口?
先把下拉式菜单设置好,如:
<form method="POST">
<select name="D1" size="1">
<option value="http://www.163.com/">网易</option>
<option value="http://www.suho.com/">搜狐</option></select>
<input type="submit" value="确定" name="B1"><input type="reset" value="重置"name="B2"></p></form>
然后把<select name="D1" size="1">改为
<select onChange="javascript:window.open(this.options[this.selectedIndex].value)">即可。
32. 如何让下拉式菜单中的链接来打开一个新的窗口?
先把下拉式菜单设置好,如:
<form method="POST">
<select name="D1" size="1">
<option value="http://www.163.com/">网易</option>
<option value="http://www.suho.com/">搜狐</option></select>
<input type="submit" value="确定" name="B1"><input type="reset" value="重置"name="B2"></p></form>
然后把<select name="D1" size="1">改为
<select onChange="javascript:window.open(this.options[this.selectedIndex].value)">即可。

34. 如何跳到页面的顶部?
当浏览者浏览到页面底部后,你需要提供一个单击,让浏览者方便的跳到页面顶部,加入以下代码:
<a href="#top">返回顶部</a>
35.如何让浏览器正确显示word文件格式?
为了正确处理word等格式,你需要在HTML文件中设置好该文件类型,比如:
<meta http-equiv="Content-Type" content="Application/msword">
还有其它经常设置的文件类型:
Application/msword Microsoft Word Document application/pdf PDF Documentapplication/wordperfect6.0 WordPerfect 6.0 Documentapplication/zip ZIP archiveaudio/x-wav WAV audio formataudio/midi MIDI audio formataudio/x-pn-realaudio RealAudioimage/gif GIF image formatimage/jpeg JPEG image formatimage/png PNG image formattext/html HTML documenttext/plain Plain textvideo/mpeg MPEG video formatvideo/quicktime QuickTime video formatvideo/x-msvideo AVI video format
36.如何在一个站点不同页面间播放同一种声文件?
大家 有这样的经验,当你访问一个站点首页时,会听到该页设置的背景声音文件,比如一段音乐。当你链接到该站点另一页时,音乐就停止了。如何让声音不断呢。其 实,你只需要建立一个上下框架结构的网页,把声音文件建立在下框架里,并把下框架的宽度设置为一个像素,而上框架里是页面内容,当访问者离开站点首页时, 因下框架内容未变,所以,声音不会间断。大家还要注意两点,第一,把框架的边框设置为0;第二,隐藏声音文件的播放界面,然后把上下两个框架的背景设置为 相同。
37.如何让所有页面共享同一个层叠样式表(CSS)?
在每一个页面的<HEAD></HEAD>部分中加入以下代码:
<link rel="stylesheet" Type="text/css" href="cnshell.css">
其中cnshell.css为共享的层叠样式表文件
38.如何为链接定制新窗口?
我们可以打开一个新的窗口来显示链接的内容,但如何定制这个新窗口呢。
只需要在标签<A>中加入onClick事件:
<a href="#" onClick="window.open('cnshell.htm','help','scrollbars=yes,
resizable=yes,width=500,height=40')">问答</a>
"#"表示单击链接"问答"后,当前窗口保持不变,cnshell.htm为单击链接"问答"后所打开新窗口装载的内容,而scrollbars=yes,resizable=yes,width=500,height=40为设置新窗口的大小等属性。
39. 如何在页面利用单击来关闭浏览窗口?
在<BODY></BODY>部分加入以下代码:
<a href="javascript:window.close()">关闭窗口</a>
40. 如何删除图片链接的蓝色边框?
如果我们设置了图片为一个链接,会发现图片四周出现了蓝色边框。要删除边框,需要在图片标签里加上border="0"。如:<img src="dog.jpg" border="0">
41. 如何清除页面中的框架结构?
在链接属性中加入target="_top" 如下设置:
<a href="http://www.yufeng21.com" target="_top">宇风多媒体</a>
当你单击了这个链接,页面所有框架被清除并以该链接内容替代。
42.直接跳转到下一页面
<meta http-equiv="Content-Type" content="text/html; charset=GBK"/>
后加入下面语句,表示跳转到Config.do
<meta http-equiv="refresh" content="0;url=Config.do" />
43. 如何创建一个下拉菜单?
我们在主页中常会用到下拉菜单,一般来说,它需要CGI程序支持。你也可以利用javascript编写一个。
<head>
<script LANGUAGE="javascript">function formHandler(){var URL = document.form.site.options[document.form.site.selectedIndex]
.value;window.location.href = URL;}
</script>
</head>
<body>
<form name="form"><select NAME="site" SIZE="1" onChange="formHandler()"><option value="请选择">请选择</option><option value="http://www.yufeng21.com/">分栏内容</option><option value="http://www.yufeng21.com/">分栏内容</option><option value="http://www.yufeng21.com/">分栏内容</option><option value="mailtocnshell@163.net">给我写信</option></select></form>
</body>
44.如何建立一个站点的搜索引擎系统?
如果你的站点有许多内容,你希望访问者能很快找到他想要的信息。那么你需要建立一个搜索引擎。连接到网站网络特区http://netzone.swatou.com/personal/,单击"申请站点引擎"并填写申请表,再按照要求建立站点页面数据库即可。
45. 什么是目标窗口,它该如何设置?
目 标窗口是页面链接所指内容显示的窗口,也就是当你单击了页面某一个链接后,该链接所指的内容在那个窗口显示。大多数情况下,我们无需关心它,因为一般都是 在同一窗口显示。target是链接标签<a>的属性,它的作用就是指定目标窗口,target有以下几个值:
_self-将链接指向的内容装载到当前页的窗口或框架中
_top-完全取代当前页面的所有框架
_blank-为链接指向的内容打开一个新的窗口
_parent-把链接指向的内容装入当前页<FRAMESET>父窗口中
以上设置多用在框架结构的页面中。
46. 如何为所有链接指定同一目标窗口?
在框架网页结构中,我们需要指定链接所指向的内容显示在那个窗口中。如果你的链接大部分都指定到同一个窗口中,就可以在<HEAD></HEAD>部分中加入:<base target="窗口名">,你无需为每个链接再指定窗口了。
47. 尽量用table标签,这样可以避免<td>之间的干扰;<table>尽量设为<table width="100%" border="0" cellpadding="0" ellspacing="0">,一方面是不显示表格线,另一方面占满整个宽度,不会因为内容不够而宽度变窄;包含<table>的 <td>要设为<td valign="top">,不然内部table默认居中。
48.<table>中第一行表格的width控制各列宽度;每列第一个格的height控制各行高度。
49.如何把一行表单或图片都放于middle位置:要把每一个都用<td>隔开,每个<td>都要设valign="middle"。
50.<td></td>之间不要有空格或空行,即应该<td><img src="***"></td>这么写,否则图片上下会产生空白的一细条。
51.&nbsp;表示一个空格,这个空格占一个字符(对于字母)还是两个字符(对于汉字)是根据浏览器的(工具->Internet选项->语言)来决定的,是不确定的,所以中文开头只需要两个&nbsp;而不是四个&nbsp;。
52.在线播放:
下面两个视频,前一个是RM视频(.rm .rmvb),后一个是MP视频(.wmv .asf .avi),为了不影响大家,都设置为手动播放,并将相关的代码及说明放在了视频的下面:
RM源代码:
<OBJECT classid=clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA class=OBJECT id=RAOCX width=352 height=288>
<PARAM NAME=SRC VALUE="http://www.cqie.cn/pub/iec.rm">
<PARAM NAME=CONSOLE VALUE="http://www.cqie.cn/pub/iec.rm">
<PARAM NAME=CONTROLS VALUE=imagewindow>
<PARAM NAME=AUTOSTART VALUE=0 >
</OBJECT>
<br>
<OBJECT classid=CLSID:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA height=32 id="video" width=352>
<PARAM NAME=SRC VALUE="http://www.cqie.cn/pub/iec.rm">
<PARAM NAME=AUTOSTART VALUE=0>
<PARAM NAME=CONTROLS VALUE=controlpanel>
<PARAM NAME=CONSOLE VALUE="http://www.cqie.cn/pub/iec.rm">
</OBJECT>
说明:以后可以直接把以上代码放到网页中使用,需要修改的属性说明如下width=352 height=288 这是控制媒体高度和宽度的VALUE="http://www.cqie.cn/pub/iec.rm" 这是指定媒体文件URL地址的,如果安装了REALSERVER的话,可以用rtsp://www.cqie.cn/pub/iec.rm来进行流式播 放,看起来会更流畅,而且可拖动。AUTOSTART VALUE=0  这是控制是否自动播放的,你只要将value=1就可以自动播放了

MP源代码:
<object align=middle classid=CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95 class=OBJECT id=MediaPlayer width=160 height=168 >
<PARAM NAME=AUTOSTART VALUE=0 >
<param name=ShowStatusBar value=-1>
<param name=Filename value=http://xiaoping.cqie.cn/wmv/jler.wmv>
<embed type=application/x-oleobject codebase=http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701 flename=mp src="http://xiaoping.cqie.cn/wmv/jler.wmv" width=160 height=168>
</embed>
</object>

53.树状显示js代码
(要求:某行文本前面有一个加号的标签,一点击加号变成减号,同时该行展开它之下所属信息,以缩进形式呈现,再点击减号又变回加号、下面展开的文本收回,这应该怎么做?除了js方式有什么其他方式实现么?谢谢!)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>无标题文档</title>
<script language="javascript">
function showLay(divId){
        var objDiv = eval(divId);
        if (objDiv.style.display=="none"){
                eval("sp"+divId+".innerHTML='-'");
                objDiv.style.display="";
        }else{
                eval("sp"+divId+".innerHTML='+'");
                objDiv.style.display="none";
        }}
</script>
</head>
<body>
<a href="#" onclick="showLay('Layer1')"><span id="spLayer1">+</span>a</a><br>
<div id="Layer1" style="display:none;">
|-<a href="insert_unit_info.html" target="body">a1</a><br>
|-<a href="select_unit_info.jsp" target="body">a2</a><br>
</div>
<a href="#" onclick="showLay('Layer2')"><span id="spLayer2">+</span>b</a><BR>
<div id="Layer2" style="display:none;">
|-<a href="insert_item_info.html" target="body">b1</a><br>
|-<a href="select_item_info.jsp" target="body">b2</a><br>
</div>
<a href="#" onclick="showLay('Layer3')"><span id="spLayer3">+</span>c</a><BR>
<div id="Layer3" style="display:none;">
|-<a href="insert_expert_info.html" target="body">c1</a><br>
|-<a href="select_expert_info.jsp" target="body">c2</a><br>
</div>
<a href="#" onclick="showLay('Layer4')"><span id="spLayer4">+</span>d</a><BR>
<div id="Layer4" style="display:none;">
|-d1<br>
|-d2<br>
</div>
</body>
</html>

54.下拉菜单(新建个.html文件,把代码考进去就行)
<html>
<head>
<title>打造下拉菜单</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<script language="javascript">
function MM_reloadPage(init) {  //reloads the window if Nav4 resized
  if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
    document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
  else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
}
MM_reloadPage(true);
function MM_findObj(n, d) { //v4.0
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && document.getElementById) x=document.getElementById(n); return x;
}
function MM_showHideLayers() { //v3.0
  var i,p,v,obj,args=MM_showHideLayers.arguments;
  for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i]))!=null) { v=args[i+2];
    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v='hide')?'hidden':v; }
    obj.visibility=v; }
}
</script>
</head>
<body bgcolor="#CCCCCC" text="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" scroll=auto>
<div id="title" style="position:absolute; left:8px; top:15px; width:240px; height:15px; z-index:1; background-color: #006699;
layer-background-color: #006699; border: 1px none #000000">
  <table width="480" cellspacing="0" cellpadding="2">
    <tr>
      <td width="120" onMouseOver="MM_showHideLayers('menu1','','show')" onMouseOut="MM_showHideLayers
('menu1','','hide')"><b><font color="#FFFFFF"><a href="#">■
        经典论坛</a></font></b> </td>
    </tr>
  </table>
</div>
<div id="menu1" style="position:absolute; left:8px; top:34px; width:120px; height:80px; z-index:2; background-color: #999966;
layer-background-color: #999966; border: 1px none #000000; visibility: hidden" onMouseOver="MM_showHideLayers
('menu1','','show')" onMouseOut="MM_showHideLayers('menu1','','hide')">
  <table width="100%" cellspacing="0" cellpadding="2" height="80">
    <tr>
      <td>&nbsp;<a href="#">Dreamweaver 专栏</a></td>
    </tr>
    <tr>
      <td>&nbsp;<a href="#">Fireworks 专栏</a></td>
    </tr>
    <tr>
      <td>&nbsp;<a href="#">Flash 基本操作</a></td>
    </tr>
    <tr>
      <td>&nbsp;<a href="#">Flash 5 Action</a></td>
    </tr>
  </table>
</div>
</body>
</html>

55.防止下载网页信息(例如显示受控文件)的简单方法:
a。屏蔽鼠标左右键,<body oncontextmenu=self.event.returnValue=false onselectstart="return false">
b。加密网页源文件,推荐Batch Html Encryptor加密软件。
c.用Adobe Acrobat 6.0 Standard软件加密。
 
55。此方法显示下拉框默认值
<select name="max">
 <option value="1">第一名</option>
 <option value="2">第二名</option>
 <option value="3">第三名</option>
</select>
<script>document.all("max").value="3"</script>

56.用javascript设置输入框焦点
<html>
<head>
<script language="javascript">
function t() {
document.getElementById('aa').focus(); 
}                           <!--设置id为aa的元素得到焦点-->
</script>
</head>
<body onload="javascript:t()">
<input type="text" id="aa"> <!--设置文本输入框的id为aa-->
</body>
</html>

57.select标签下的OPTION标签没有value属性时,把内容当属性传过去,比如<OPTION>所有用户</OPTION>传的值就是所有用户,建议用以下方法。
<select name="account.accountId" >
    <OPTION value="">所有日志</OPTION>
    <OPTION value="renyang">任杨</OPTION>
</select>

58.不保留缓存方法:
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Cache-Control", "must-revalidate");
response.setDateHeader("Expires",0);
%>

59.全选、全不选js方法 (直接放在.htm文件中即可)
<SCRIPT language="javascript">
function checkAll(e, itemName)
{
  var aa = document.getElementsByName(itemName);
  for (var i=0; i<aa.length; i++)
   aa[i].checked = e.checked;
}
function check(e, allName)
{
  var all = document.getElementsByName(allName)[0];
  if(!e.checked) all.checked = false;
  else
  {
    var aa = document.getElementsByName(e.name);
    for (var i=0; i<aa.length; i++)
     if(!aa[i].checked) return;
    all.checked = true;
  }
}
</SCRIPT>
<input type=checkbox name=allPersons id=allPersons onclick="checkAll(this, 'persons')">&nbsp;<label for="allPersons">全选</label><br>
<input type="checkbox" name="persons" id=persons value="1">&nbsp;<label for="persons">第一名</label><br>
<input type="checkbox" name="persons" id=persons value="2">&nbsp;<label for="persons">第二名</label><br>
<!-- 问题:第一名和第二名这两个字ID不能一样,否则点第二名这三个字时第一名前的框变化 -->
posted @ 2006-08-16 16:42 阿成 阅读(1103) | 评论 (0)编辑 收藏
//对于gb2312来讲, 首字节码位从0×81 至0×FE,尾字节码位分别是0×40 至0×FE
//本例是验证此串是否含有gb2312格式的字符,即是否含有汉字
public class Test{
  public boolean isGB2312( String str )
  {
    char[] chars = str.toCharArray();
    boolean isGB2312 = false;
    for ( int i = 0; i < chars.length; i++ )
    {
      byte[] bytes = ( "" + chars[i] ).getBytes();
      if ( bytes.length == 2 )
      {
        int[] ints = new int[2];
        ints[0] = bytes[0] & 0xff;
        ints[1] = bytes[1] & 0xff;
        if ( ints[0] >= 0x81 && ints[0] <= 0xFE && ints[1] >= 0x40 && ints[1] <= 0xFE )
        {
          isGB2312 = true;
          break;
        }
      }
    }
    return isGB2312;
  }
 
  public static void main(String[] args)
  {
    String s = "ss您好ss";//结果为true
    String s = "ssssss";//结果为false
    Test test = new Test();
    System.out.println(test.isGB2312(s));
  }
}
posted @ 2006-08-16 16:38 阿成 阅读(455) | 评论 (0)编辑 收藏

插入排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;
/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class InsertSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for(int i=1;i<data.length;i++){
            for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
                SortUtil.swap(data,j,j-1);
            }
        }       
    }

}
冒泡排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class BubbleSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for(int i=0;i<data.length;i++){
            for(int j=data.length-1;j>i;j--){
                if(data[j]<data[j-1]){
                    SortUtil.swap(data,j,j-1);
                }
            }
        }
    }

}

选择排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class SelectionSort implements SortUtil.Sort {

    /*
     * (non-Javadoc)
     *
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for (int i = 0; i < data.length; i++) {
            int lowIndex = i;
            for (int j = data.length - 1; j > i; j--) {
                if (data[j] < data[lowIndex]) {
                    lowIndex = j;
                }
            }
            SortUtil.swap(data,i,lowIndex);
        }
    }

}

Shell排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ShellSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        for(int i=data.length/2;i>2;i/=2){
            for(int j=0;j<i;j++){
                insertSort(data,j,i);
            }
        }
        insertSort(data,0,1);
    }

    /**
     * @param data
     * @param j
     * @param i
     */
    private void insertSort(int[] data, int start, int inc) {
        int temp;
        for(int i=start+inc;i<data.length;i+=inc){
            for(int j=i;(j>=inc)&&(data[j]<data[j-inc]);j-=inc){
                SortUtil.swap(data,j,j-inc);
            }
        }
    }

}

快速排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class QuickSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        quickSort(data,0,data.length-1);       
    }
    private void quickSort(int[] data,int i,int j){
        int pivotIndex=(i+j)/2;
        //swap
        SortUtil.swap(data,pivotIndex,j);
       
        int k=partition(data,i-1,j,data[j]);
        SortUtil.swap(data,k,j);
        if((k-i)>1) quickSort(data,i,k-1);
        if((j-k)>1) quickSort(data,k+1,j);
       
    }
    /**
     * @param data
     * @param i
     * @param j
     * @return
     */
    private int partition(int[] data, int l, int r,int pivot) {
        do{
           while(data[++l]<pivot);
           while((r!=0)&&data[--r]>pivot);
           SortUtil.swap(data,l,r);
        }
        while(l<r);
        SortUtil.swap(data,l,r);       
        return l;
    }

}
改进后的快速排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ImprovedQuickSort implements SortUtil.Sort {

    private static int MAX_STACK_SIZE=4096;
    private static int THRESHOLD=10;
    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] stack=new int[MAX_STACK_SIZE];
       
        int top=-1;
        int pivot;
        int pivotIndex,l,r;
       
        stack[++top]=0;
        stack[++top]=data.length-1;
       
        while(top>0){
            int j=stack[top--];
            int i=stack[top--];
           
            pivotIndex=(i+j)/2;
            pivot=data[pivotIndex];
           
            SortUtil.swap(data,pivotIndex,j);
           
            //partition
            l=i-1;
            r=j;
            do{
                while(data[++l]<pivot);
                while((r!=0)&&(data[--r]>pivot));
                SortUtil.swap(data,l,r);
            }
            while(l<r);
            SortUtil.swap(data,l,r);
            SortUtil.swap(data,l,j);
           
            if((l-i)>THRESHOLD){
                stack[++top]=i;
                stack[++top]=l-1;
            }
            if((j-l)>THRESHOLD){
                stack[++top]=l+1;
                stack[++top]=j;
            }
           
        }
        //new InsertSort().sort(data);
        insertSort(data);
    }
    /**
     * @param data
     */
    private void insertSort(int[] data) {
        int temp;
        for(int i=1;i<data.length;i++){
            for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
                SortUtil.swap(data,j,j-1);
            }
        }      
    }

}

归并排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class MergeSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] temp=new int[data.length];
        mergeSort(data,temp,0,data.length-1);
    }
   
    private void mergeSort(int[] data,int[] temp,int l,int r){
        int mid=(l+r)/2;
        if(l==r) return ;
        mergeSort(data,temp,l,mid);
        mergeSort(data,temp,mid+1,r);
        for(int i=l;i<=r;i++){
            temp[i]=data[i];
        }
        int i1=l;
        int i2=mid+1;
        for(int cur=l;cur<=r;cur++){
            if(i1==mid+1)
                data[cur]=temp[i2++];
            else if(i2>r)
                data[cur]=temp[i1++];
            else if(temp[i1]<temp[i2])
                data[cur]=temp[i1++];
            else
                data[cur]=temp[i2++];           
        }
    }

}

改进后的归并排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ImprovedMergeSort implements SortUtil.Sort {

    private static final int THRESHOLD = 10;

    /*
     * (non-Javadoc)
     *
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] temp=new int[data.length];
        mergeSort(data,temp,0,data.length-1);
    }

    private void mergeSort(int[] data, int[] temp, int l, int r) {
        int i, j, k;
        int mid = (l + r) / 2;
        if (l == r)
            return;
        if ((mid - l) >= THRESHOLD)
            mergeSort(data, temp, l, mid);
        else
            insertSort(data, l, mid - l + 1);
        if ((r - mid) > THRESHOLD)
            mergeSort(data, temp, mid + 1, r);
        else
            insertSort(data, mid + 1, r - mid);

        for (i = l; i <= mid; i++) {
            temp[i] = data[i];
        }
        for (j = 1; j <= r - mid; j++) {
            temp[r - j + 1] = data[j + mid];
        }
        int a = temp[l];
        int b = temp[r];
        for (i = l, j = r, k = l; k <= r; k++) {
            if (a < b) {
                data[k] = temp[i++];
                a = temp[i];
            } else {
                data[k] = temp[j--];
                b = temp[j];
            }
        }
    }

    /**
     * @param data
     * @param l
     * @param i
     */
    private void insertSort(int[] data, int start, int len) {
        for(int i=start+1;i<start+len;i++){
            for(int j=i;(j>start) && data[j]<data[j-1];j--){
                SortUtil.swap(data,j,j-1);
            }
        }
    }

}
堆排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class HeapSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        MaxHeap h=new MaxHeap();
        h.init(data);
        for(int i=0;i<data.length;i++)
            h.remove();
        System.arraycopy(h.queue,1,data,0,data.length);
    }


     private static class MaxHeap{
        
       
        void init(int[] data){
            this.queue=new int[data.length+1];
            for(int i=0;i<data.length;i++){
                queue[++size]=data[i];
                fixUp(size);
            }
        }
        
        private int size=0;

        private int[] queue;
               
        public int get() {
            return queue[1];
        }

        public void remove() {
            SortUtil.swap(queue,1,size--);
            fixDown(1);
        }
        //fixdown
        private void fixDown(int k) {
            int j;
            while ((j = k << 1) <= size) {
                if (j < size && queue[j]<queue[j+1])
                    j++;
                if (queue[k]>queue[j]) //不用交换
                    break;
                SortUtil.swap(queue,j,k);
                k = j;
            }
        }
        private void fixUp(int k) {
            while (k > 1) {
                int j = k >> 1;
                if (queue[j]>queue[k])
                    break;
                SortUtil.swap(queue,j,k);
                k = j;
            }
        }

    }

}

 

SortUtil:

package org.rut.util.algorithm;

import org.rut.util.algorithm.support.BubbleSort;
import org.rut.util.algorithm.support.HeapSort;
import org.rut.util.algorithm.support.ImprovedMergeSort;
import org.rut.util.algorithm.support.ImprovedQuickSort;
import org.rut.util.algorithm.support.InsertSort;
import org.rut.util.algorithm.support.MergeSort;
import org.rut.util.algorithm.support.QuickSort;
import org.rut.util.algorithm.support.SelectionSort;
import org.rut.util.algorithm.support.ShellSort;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class SortUtil {
    public final static int INSERT = 1;

    public final static int BUBBLE = 2;

    public final static int SELECTION = 3;

    public final static int SHELL = 4;

    public final static int QUICK = 5;

    public final static int IMPROVED_QUICK = 6;

    public final static int MERGE = 7;

    public final static int IMPROVED_MERGE = 8;

    public final static int HEAP = 9;

    public static void sort(int[] data) {
        sort(data, IMPROVED_QUICK);
    }
    private static String[] name={
            "insert","bubble","selection","shell","quick","improved_quick","merge","improved_merge","heap"
    };
   
    private static Sort[] impl=new Sort[]{
            new InsertSort(),
            new BubbleSort(),
            new SelectionSort(),
            new ShellSort(),
            new QuickSort(),
            new ImprovedQuickSort(),
            new MergeSort(),
            new ImprovedMergeSort(),
            new HeapSort()
    };

    public static String toString(int algorithm){
        return name[algorithm-1];
    }
   
    public static void sort(int[] data, int algorithm) {
        impl[algorithm-1].sort(data);
    }

    public static interface Sort {
        public void sort(int[] data);
    }

    public static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

posted @ 2006-08-16 16:06 阿成 阅读(281) | 评论 (0)编辑 收藏
一、一对多映射
1、在映射一对多的双相关联关系时,应该在one方把inverse属性设为true,可以提高应用的性能。
2、建立两个对象的双向关联时,应该同时修改关联两端的对象的应用属性,这样使程序更加健壮,提高业务逻辑层的独立性,使业务逻辑层的程序代码不受hibernate实现的影响;同理,当解除双相关联关系时,也应该修改关联两端的对象的相应属性。
eg://添加
customer.getOrders().add(order);
order.setCustomer(customer);
//删除
customer.getOrders().remove(order);
order.setCustomer(null);
3、在定义一对多映射中“一”的POJO类时,注意要private Set orders = new HashSet();//通常把它初始化为集合实现类的一个实例,这样避免访问取值为null,引发NullPointerException异常,提高健壮性。
二、Session三种检索方法:
1.load():根据给定OID从数据库中加载一个持久化对象,如数据库中没有则抛出net.sf.hibernate.ObjectNotFoundException异常。
2.get():根据给定OID从数据库中加载一个持久化对象,如数据库中没有则返回null。
3.find():按照参数指定的HQL语句加载一个或多个持久化对象,实际是HQL检索方式的一种简写形式。
三、hql查询:
在数组和Collection中的查询:
String hql = "select  u from User u where u in (:users)";
query.setParameterList("users", users);
//括号千万别忘写,否则出现如下错误:
2006-07-07 11:07:35 WARN [org.hibernate.util.JDBCExceptionReporter] - SQL Error: 907, SQLState: 42000
2006-07-07 11:07:35 ERROR [org.hibernate.util.JDBCExceptionReporter] - ORA-00907: 缺失右括号
posted @ 2006-08-16 15:37 阿成 阅读(404) | 评论 (0)编辑 收藏

Java FAQ
 
目录:
Q1.1 什么是Java、Java2、JDK?JDK后面的1.3、1.4版本号又是怎么回事?
Q1.2 什么是JRE/J2RE?
Q1.3 学习Java用什么工具比较好?
Q1.4  学习Java有哪些好的参考书?
Q1.5  Java和C++哪个更好?
Q1.6  什么是J2SE/J2EE/J2ME?
Q2.1  我写了第一个Java程序,应该如何编译/运行?
Q2.2  我照你说的做了,但是出现什么“'javac' 不是内部或外部命令,也不是可运行的
程序或批处理文件。”。
Q2.3  环境变量怎么设置?
Q2.4  我在javac xxx.java的时候显示什么“unreported exception java.io.IOExcepti
on;”。
Q2.5  javac xxx.java顺利通过了,但是java xxx的时候显示什么“NoClassDefFoundErr
or”。
Q2.6  我在java xxx的时候显示“Exception in thread "main" java.lang.NoSuchMetho
dError: main”。
Q2.7  在java xxx的时候显示“Exception in thread "main" java.lang.NullPointerEx
ception”。
Q2.8 package是什么意思?怎么用?
Q2.9 我没有声明任何package会怎么样?
Q2.10 在一个类中怎么使用其他类?
Q2.11 我用了package的时候显示"NoClassDefFoundError",但是我把所有package去掉的
时候能正常运行。
Q2.12 我想把java编译成exe文件,该怎么做?
Q2.13 我在编译的时候遇到什么"deprecated API",是什么意思?
Q3.1 我怎么给java程序加启动参数,就像dir /p/w那样?
Q3.2 我怎么从键盘输入一个int/double/字符串?
Q3.3 我怎么输出一个int/double/字符串?
Q3.4 我发现有些书上直接用System.in输入,比你要简单得多。
Q3.5 我怎么从文件输入一个int/double/字符串?
Q3.6 我想读写文件的指定位置,该怎么办?
Q3.7 怎么判断要读的文件已经到了尽头?
Q4.1  java里面怎么定义宏?
Q4.2  java里面没法用const。
Q4.3  java里面也不能用goto。
Q4.4  java里面能不能重载操作符?
Q4.5  我new了一个对象,但是没法delete掉它。
Q4.6  我想知道为什么main方法必须被声明为public static?为什么在main方法中不能调
用非static成员?
Q4.7  throw和throws有什么不同?
Q4.8  什么是异常?
Q4.9  final和finally有什么不同?
Q5.1  extends和implements有什么不同?
Q5.2  java怎么实现多继承?
Q5.3 abstract是什么?
Q5.4 public,protected,private有什么不同?
Q5.5 Override和Overload有什么不同?
Q5.6 我继承了一个方法,但现在我想调用在父类中定义的方法。
Q5.7 我想在子类的构造方法中调用父类的构造方法,该怎么办?
Q5.8 我在同一个类中定义了好几个构造方法并且想在一个构造方法中调用另一个。
Q5.9 我没有定义构造方法会怎么样?
Q5.10 我调用无参数的构造方法失败了。
Q5.11 我该怎么定义类似于C++中的析构方法(destructor)?
Q5.12 我想将一个父类对象转换成一个子类对象该怎么做?
Q5.13 其实我不确定a是不是B的实例,能不能分情况处理?
Q5.14 我在方法里修改了一个对象的值,但是退出方法后我发现这个对象的值没变!
Q6.1 java能动态分配数组吗?
Q6.2 我怎么知道数组的长度?
Q6.3 我还想让数组的长度能自动改变,能够增加/删除元素。
Q     什么是链表?为什么要有ArrayList和LinkedList两种List?
Q6.5 我想用队列/栈。
Q6.6 我希望不要有重复的元素。
Q6.7 我想遍历集合/Map。
Q6.8 我还要能够排序。
Q6.9 但是我想给数组排序。
Q6.10 我想按不同方式排序。
Q6.11 Map有什么用?
Q6.12 set方法没问题,但是get方法返回的是Object。
Q6.13 ArrayList和Vector有什么不同?HashMap和Hashtable有什么不同?
Q6.14 我要获得一个随机数。
Q6.15 我比较两个String总是false,但是它们明明都是"abc" !
Q6.16 我想修改一个String但是在String类中没找到编辑方法。
Q6.17 我想处理日期/时间。

一、准备篇

Q1.1 什么是Java、Java2、JDK?JDK后面的1.3、1.4版本号又是怎么回事?
答:Java是一种通用的,并发的,强类型的,面向对象的编程语言(摘自Java规范第二版
)。
JDK是Sun公司分发的免费Java开发工具包,正式名称为J2SDK(Java2 Software Develop K
it)。
包括基本的java工具包和标准类库。
到目前(2003年7月)为止,Java有3个主要版本,即1.0,1.1,2.0;
JDK有1.0,1.1,1.2,1.3,1.4五个版本。
从JDK1.2起,Sun公司觉得Java改变足够大而将java语言版本号提升为2.0。
不同的JDK主要在于提供的类库不同。作为学习你可以下载最新的JDK1.4.2。
真正开发时则应考虑向前兼容,比如1.3。下载请去http://java.sun.com
JDK1.5预计将在2004年推出,届时其中将包含若干崭新的特性。

Q1.2 什么是JRE/J2RE?
答:J2RE是Java2 Runtime Environment,即Java运行环境,有时简称JRE。
如果你只需要运行Java程序或Applet,下载并安装它即可。
如果你要自行开发Java软件,请下载JDK。在JDK中附带有JRE。
注意由于Microsoft对Java的支持不完全,请不要使用IE自带的虚拟机来运行Applet,务必
安装一个JRE或JDK。

Q1.3 学习Java用什么工具比较好?
答:作者建议首先使用JDK+文本编辑器,这有助你理解下列几个基础概念:path,classp
ath,package
并熟悉基本命令:javac和java。并且下载和你的JDK版本一致的API帮助。
如果你不确定类或函数的用法,请先查阅API而不是发贴求助。
当你熟悉Java之后,你可以考虑开始使用一个IDE。
作者推荐eclipse,下载网址http://www.eclipse.org。因为eclispe是免费的,插件化的

eclispe的主要缺点是缺乏一个可视化的桌面程序开发工具,
幸运的是IBM在2003年11月已经将部分代码捐给eclipse组织,可以预计这个缺点很快就会
得到弥补。
无论如何,请不要使用Microsoft的VJ++!众所周知Microsoft从来就没有认真支持过Java

最后但并非最不重要,要有一本好的参考书,并且英文要过关。

Q1.4  学习Java有哪些好的参考书?
答:作者首先推荐Thinking in Java,中文名《Java编程思想》,有中文版。
目前的最新版本是第三版。
http://64.78.49.204可以免费下载英文版。
该书第一章介绍了很多面向对象的编程思想,作为新手应当认真阅读。
除此以外,O'relly出版社和Wrox出版社的书也不错。作者本人不喜欢大陆作者的书。
也许你觉得英文太难,但是网上大多数资料都是英文的。另外,你需要经常查阅API,而那
也是英文的。

Q1.5  Java和C++哪个更好?
答:这个问题是一个很不恰当的问题。你应该问:Java和C++哪个更适用于我的项目?
Java的优点和缺点一样明显。
跨平台是Java的主要优点,但代价是运行速度的下降。
VC和Windows平台有良好的集成和足够快的速度,但是也只能局限在Windows平台上。
和C++相比,Java学起来更快,开发人员不会碰到很多容易出错的特性。
但是VB程序员甚至只需要拼装模块就可以了。

Q1.6  什么是J2SE/J2EE/J2ME?
答:J2SE就是一般的Java。
J2ME是针对嵌入式设备的,比如支持Java的手机,它有自己的JRE和SDK。
J2EE是一组用于企业级程序开发的规范和类库,它使用J2SE的JRE。

二、命令篇

Q2.1  我写了第一个Java程序,应该如何编译/运行?
答:首先请将程序保存为xxx.java文件,注意你可能需要修改文件后缀名。
然后在dos窗口下使用javac xxx.java命令,你会发现该目录下多了一个xxx.class文件,

再使用java xxx命令,你的java程序就开始运行了。

Q2.2  我照你说的做了,但是出现什么“'javac' 不是内部或外部命令,也不是可运行的
程序或批处理文件。”。
答:你遇到了path问题。操作系统在一定的范围(path)内搜索javac.exe,但是没能找到。

请编辑你的操作系统环境变量,新增一个JAVA_HOME变量,设为你JDK的安装目录,
再编辑Path变量,加上一项 %JAVA_HOME%\bin。
然后保存并新开一个dos窗口,你就可以使用javac和java命令了。

Q2.3  环境变量怎么设置?
答:请向身边会设的人咨询。

Q2.4  我在javac xxx.java的时候显示什么“unreported exception java.io.IOExcepti
on;”。
答:参见Q4.8以了解java中的异常机制。

Q2.5  javac xxx.java顺利通过了,但是java xxx的时候显示什么“NoClassDefFoundErr
or”。
答:1. 你遇到了classpath问题。java命令在一定的范围(classpath)内搜索你直接或间接
使用的class文件,但是未能找到。
首先请确认你没有错敲成java xxx.class,
其次,检查你的CLASSPATH环境变量,其实你并不需要设置该变量,
但如果你设置了该变量又没有包含.(代表当前目录)的项,
你就会遇到这个问题。请在你的CLASSPATH环境变量中加入一项. 或干脆删掉这个变量。

2. 如果你使用了并非JDK自带的标准包,比如javax.servlet.*包,也会遇到这个问题,请
将相应的jar文件加入classpath。
3. 如果你在java源文件中定义了package,请参见Q2.11。


Q2.6  我在java xxx的时候显示“Exception in thread "main" java.lang.NoSuchMetho
dError: main”。
答:首先,在你的程序中每个java文件有且只能有一个public类,
这个类的类名必须和文件名的大小写完全一样。
其次,在你要运行的类中有且只能有一个public static void main(String[] args)方法

这个方法就是你的主程序。


Q2.7  在java xxx的时候显示“Exception in thread "main" java.lang.NullPointerEx
ception”。
答:在程序中你试图在值为null的对象变量上调用方法,请检查你的程序确保你的对象被恰当的初始化。
参见Q4.8以了解java中的异常机制。


Q2.8 package是什么意思?怎么用?
答:为了唯一标识每个类并分组,java使用了package的概念。
每个类都有一个全名,例如String的全名是java.lang.String,其中java.lang是包名,S
tring是短名。按照java命名惯例,包名是全部小写的,而类名的第一个字母是大写的。
这样,如果你自行定义了同样名字的类String,你可以把它放在mypackage中,
通过使用全名mypackage.String和java.lang.String来区分这两个类。
同时,将逻辑上相关的类放在同一个包中,可以使程序结构更为清楚。
为了定义包,你要做的就是在java文件开头加一行“package mypackage;”。
注意包没有嵌套或包含关系,mypackage包和mypackage.mysubpackage包对JRE来说是并列的两个包(虽然开发者可
能暗示包含关系)。

Q2.9 我没有声明任何package会怎么样?
答:你的类被认为放在默认包中。这时全名和短名是一致的。

Q2.10 在一个类中怎么使用其他类?
答:如果你使用java.lang包或者默认包中的类,不用做任何事。
如果你的类位于mypackage包中,并且要调用同一包中的其他类,也不用做任何事。
如果你使用其他包中的类,在package声明之后,类声明之前使用import otherpackage1.Class
1; 或 import otherpackage2.*; 
这里.*表示引入这个包中的所有类。然后在程序中你可以使用其他类的短名。
如果短名间有重名冲突,必须使用全名来区分。
注意在使用其他包中的类时,你只能使用public的类和接口,参见Q5.4。

Q2.11 我用了package的时候显示"NoClassDefFoundError",但是我把所有package去掉的
时候能正常运行。
答:将你的java文件按包名组织存放。
比如你的工作目录是/work,你的类是package1.Class1,那么将它存放为/work/package1
/Class1.java。
如果没有声明包,那么直接放在/work下。
在/work下执行javac package1/class1.java,再执行java package1.class1,你会发现一
切正常。
另外,如果你的类的个数已经多到了你需要使用包来组织的话,你可以考虑开始使用IDE。

Q2.12 我想把java编译成exe文件,该怎么做?
答:JDK只能将java源文件编译为class文件。
class文件是一种跨平台的字节码,必须依赖平台相关的JRE来运行。Java以此来实现跨平
台性。
有些开发工具可以将java文件编译为exe文件。作者反对这种做法,因为这样就取消了跨平
台性。
如果你确信你的软件只在Windows平台上运行,你可以考虑使用C++/C#来编程。

Q2.13 我在编译的时候遇到什么"deprecated API",是什么意思?
答:所谓deprecated是指已经过时,但是为了向前兼容起见仍然保留的方法。
这些方法可能会在以后取消支持。你应当改用较新的方法。
在API里面会说明你应当用什么方法来代替之。

三、I/O篇

Q3.1 我怎么给java程序加启动参数,就像dir /p/w那样?
答:还记得public static void main(String[] args)吗?这里的args就是你的启动参数

在运行时你输入java package1.class1 arg1 arg2,args中就会有两个String,第一个是
arg1,第二个是arg2。

Q3.2 我怎么从键盘输入一个int/double/字符串?
答:java的I/O操作比C++要复杂一点。如果要从键盘输入,样例代码如下:
BufferedReader cin = new BufferedReader( new InputStreamReader( System.in ) );

String s = cin.readLine();
这样你就获得了一个字符串,如果你需要数字的话再使用:
int n = Integer.parseInt( s ); 或者 double d = Double.parseDouble( s );
来将字符串"534"转换成int或double。

Q3.3 我怎么输出一个int/double/字符串?
答:使用System.out.println(n)或者System.out.println("Hello")等等。

Q3.4 我发现有些书上直接用System.in输入,比你要简单得多。
答:java使用unicode,是双字节。而System.in是单字节的stream。
如果你要输入双字节文字比如中文,请使用作者的做法。

Q3.5 我怎么从文件输入/输出一个int/double/字符串?
答:类似于从键盘输入,只不过换成
BufferedReader fin = new BufferedReader( new FileReader(" myFileName " ) );
PrintWriter fout = new PrintWriter( new FileWriter(" myFileName " ) );
另外如果你还没下载API,请开始下载并阅读java.io包中的内容。

Q3.6 我想读写文件的指定位置,该怎么办?
答:java.io.RandomAccessFile可以满足你的需要。

Q3.7 怎么判断要读的文件已经到了尽头?
答:在Reader的read方法中明确说明返回-1表示流的结尾。

四、 关键字篇

Q4.1  java里面怎么定义宏?
答:java不支持宏,因为宏代换不能保证类型安全。
如果你需要定义常量,可以将它定义为某个类的static final成员。参见Q4.2和Q4.6。


Q4.2  java里面没法用const。
答:你可以用final关键字。例如 final int m = 9。被声明为final的变量不能被再次赋
值。唯一的例外是所谓blank final,如下例所示:
public class MyClass1 {
    private final int a = 3;
    private final int b; // blank final

    public MyClass1() {
        a = 5; // 不合法,final变量不能被再次赋值。
        b = 4; // 合法,这是b第一次被赋值。
        b = 6; // 不合法,b不能被再次赋值。
    }
}
final也可以用于声明方法或类,被声明为final的方法或类不能被继承。
注意const是java的保留字以备扩充。

Q4.3  java里面也不能用goto。
答:甚至在面向过程的语言中你也可以完全不用goto。请检查你的程序流程是否合理。

如果你需要从多层循环中迅速跳出,java增强了(和C++相比)break和continue的功能,
支持label。
例如:
outer :
while( ... )
{
inner :
for( ... )
{
           ...   break inner; ...
           ... continue outer; ...
}
}
和const一样,goto也是java的保留字以备扩充。

Q4.4  java里面能不能重载操作符?
答:不能。String的+号是唯一一个内置的重载操作符。你可以通过定义接口和方法来实现
类似功能。

Q4.5  我new了一个对象,但是没法delete掉它。
答:java有自动内存回收机制,即所谓Garbarge Collection。你不需要删除对象。你再也
不用担心指针错误,内存溢出了。

Q4.6  我想知道为什么main方法必须被声明为public static?为什么在main方法中不能调
用非static成员?
答:声明为public是为了这个方法可以被外部调用,详情见Q5.4。
static是为了将某个成员变量/方法关联到类(class)而非实例(instance)。
你不需要创建一个对象就可以直接使用这个类的static成员,因而在static成员中不能调
用非static成员,因为后者是关联到对象实例(instance)的。
在A类中调用B类的static成员可以使用B.staticMember的写法。
注意一个类的static成员变量是唯一的,被所有该类对象所共享的,在多线程程序设计中尤其要谨慎小心。
类的static成员是在类第一次被JRE装载的时候初始化的。
你可以使用如下方法来使用非static成员:
public class A
{
    private void someMethod() //非static成员
    {}
    public static void main(String args)
    {
         A a = new A();  //创建一个对象实例
         a.someMethod();  //现在你可以使用非static方法了
    }
}


Q4.7  throw和throws有什么不同?
答:throws用于方法声明中,声明一个方法会抛出哪些异常。而throw是在方法体中实际执行抛出异常的
动作。
如果你在方法中throw一个异常,却没有在方法声明中声明之,编译器会报错。
注意Error和RuntimeException的子类是例外,无需特别声明。

Q4.8  什么是异常?
答:异常最早在Ada语言中引入,用于在程序中动态处理错误并恢复。
你可以在方法中拦截底层异常并处理之,也可以抛给更高层的模块去处理。
你也可以抛出自己的异常指示发生了某些不正常情况。常见的拦截处理代码如下:
try
{
......//以下是可能发生异常的代码
        ...... //异常被你或低层API抛出,执行流程中断并转向拦截代码。
        ......
}
catch(Exception1 e) //如果Exception1是Exception2的子类并要做特别处理,应排在前

{
  //发生Exception1时被该段拦截
}
catch(Exception2 e)
{
  //发生Exception2时被该段拦截
}
finally //这是可选的
{
   //无论异常是否发生,均执行此段代码
   //即使在catch段中又向外抛出了新的exception,finally段也会得到执行。
}

Q4.9  final和finally有什么不同?
答:final请见Q4.2。finally用于异常机制,参见Q4.8。

五、 面向对象篇

Q5.1  extends和implements有什么不同?
答:对于class而言,extends用于(单)继承一个类(class),而implements用于实现一个接口(interf
ace)。
interface的引入是为了部分地提供多继承的功能。
在interface中只需声明方法头,而将方法体留给实现的class来做。
这些实现的class的实例完全可以当作interface的实例来对待。
在interface之间也可以声明为extends(多继承)的关系。
注意一个interface可以extends多个其他interface。

Q5.2  java怎么实现多继承?
答:java不支持显式的多继承。
因为在显式多继承的语言例如c++中,会出现子类被迫声明祖先虚基类构造函数的问题,

而这是违反面向对象的封装性原则的。
java提供了interface和implements关键字来部分地实现多继承。参见Q5.1。

Q5.3 abstract是什么?
答:被声明为abstract的方法无需给出方法体,留给子类来实现。
而如果一个类中有abstract方法,那么这个类也必须声明为abstract。
被声明为abstract的类无法实例化,尽管它可以定义构造方法供子类使用。

Q5.4 public,protected,private有什么不同?
答:这些关键字用于声明类和成员的可见性。
public成员可以被任何类访问,
protected成员限于自己和子类访问,
private成员限于自己访问。
Java还提供了第四种的默认可见性,一般称为package private,当没有任何public,protected,private修饰符时,成员
是同一包内可见。
类可以用public或默认来修饰。

Q5.5 Override和Overload有什么不同?
答:Override是指父类和子类之间方法的继承关系,这些方法有着相同的名称和参数类型

Overload是指同一个类中不同方法(可以在子类也可以在父类中定义)间的关系,
这些方法有着相同的名称和不同的参数类型。


Q5.6 我继承了一个方法,但现在我想调用在父类中定义的方法。
答:用super.xxx()可以在子类中调用父类方法。

Q5.7 我想在子类的构造方法中调用父类的构造方法,该怎么办?
答:在子类构造方法的第一行调用super(...)即可。

Q5.8 我在同一个类中定义了好几个构造方法并且想在一个构造方法中调用另一个。
答:在构造方法第一行调用this(...)。

Q5.9 我没有定义构造方法会怎么样?
答:自动获得一个无参数的构造方法。

Q5.10 我调用无参数的构造方法失败了。
答:如果你至少定义了一个构造方法,就不再有自动提供的无参数的构造方法了。
你需要另外显式定义一个无参数的构造方法。
另外一种可能是你的构造方法或者类不是public的,参见Q5.4了解java中的可见性。

Q5.11 我该怎么定义类似于C++中的析构方法(destructor)?
答:提供一个void finalize()方法。在Garbarge Collector回收该对象时会调用该方法。

注意实际上你很难判断一个对象会在什么时候被回收。作者从未感到需要用到该方法。


Q5.12 我想将一个父类对象转换成一个子类对象该怎么做?
答:强制类型转换。如
public void meth(A a)
{
B b = (B)a;
}
如果a实际上并不是B的实例,会抛出ClassCastException。所以请确保a确实是B的实例。


Q5.13 其实我不确定a是不是B的实例,能不能分情况处理?
答:可以使用instanceof操作符。例如
if( a instanceof B )
{
B b = (B)a;
}
else
{
...
}

Q5.14 我在方法里修改了一个对象的值,但是退出方法后我发现这个对象的值没变!
答:很可能你把传入参数重赋了一个新对象,例如下列代码就会造成这种错误:
public void fun1(A a) //a是局部参数,指向了一个外在对象。
{
a = new A(); //a指向了一个新对象,和外在对象脱钩了。如果你要让a作为传出变量,
不要写这一句。
        a.setAttr(attr);//修改了新对象的值,外在对象没有被修改。
}
基本类型也会出现这种情况。例如:
public void fun2(int a)
{
a = 10;//只作用于本方法,外面的变量不会变化。
}

六、java.util篇

Q6.1 java能动态分配数组吗?
答:可以。例如int n = 3; Language[] myLanguages = new Language[n];

Q6.2 我怎么知道数组的长度?
答:用length属性。如上例中的  myLanguages.length 就为 3。

Q6.3 我还想让数组的长度能自动改变,能够增加/删除元素。
答:用顺序表--java.util.List接口。
你可以选择用ArrayList或是LinkedList,前者是数组实现,后者是链表实现。
例如:  List list = new ArrayList(); 或是 List list = new LinkedList();  。

Q    什么是链表?为什么要有ArrayList和LinkedList两种List?
答:请补习数据结构。

Q6.5 我想用队列/栈。
答:用java.util.LinkedList。

Q6.6 我希望不要有重复的元素。
答:用集合--java.util.Set接口。例如:Set set = new HashSet()。

Q6.7 我想遍历集合/Map。
答:用java.util.Iterator。参见API。

Q6.8 我还要能够排序。
答:用java.util.TreeSet。例如:Set set = new TreeSet()。放进去的元素会自动排序

你需要为元素实现Comparable接口,还可能需要提供equals()方法,compareTo()方法,h
ashCode()方法。

Q6.9 但是我想给数组排序。
答:java.util.Arrays类包含了sort等实用方法。

Q6.10 我想按不同方式排序。
答:为每种方式定义一个实现了接口Comparator的排序类并和Arrays或TreeSet综合运用。


Q6.11 Map有什么用?
答:存储key-value的关键字-值对,你可以通过关键字来快速存取相应的值。

Q6.12 set方法没问题,但是get方法返回的是Object。
答:强制类型转换成你需要的类型。参见Q5.12。

Q6.13 ArrayList和Vector有什么不同?HashMap和Hashtable有什么不同?
答:ArrayList和HashMap是多线程不安全的,在多个线程中访问同一个ArrayList对象可能
会引起冲突并导致错误。
而Vector和Hashtable是多线程安全的,即使在多个线程中同时访问同一个Vector对象也不
会引起差错。
看起来我们更应该使用Vector和Hashtable,但是实际上Vector和Hashtable的性能太差,
所以如果你不在多线程中使用的话,还是应该用ArrayList和HashMap。

Q6.14 我要获得一个随机数。
答:使用java.util.Random类。

Q6.15 我比较两个String总是false,但是它们明明都是"abc" !
答:比较String一定要使用equals或equalsIgnoreCase方法,不要使用 == !
==比较的是两个引用(变量)是否指向了同一个对象,而不是比较其内容。

Q6.16 我想修改一个String但是在String类中没找到编辑方法。
答:使用StringBuffer类。
String str = "......."; //待处理的字符串
StringBuffer buffer = new StringBuffer(str); //使用该字符串初始化一个StringBuf
fer
buffer.append("..."); //调用StringBuffer的相关API来编辑字符串
String str2 = buffer.toString(); //获得编辑后的字符串。
另外,如果你需要将多个字符串连接起来,请尽量避免使用+号直接连接,而是使用Strin
gBuffer.append()方法。

Q6.17 我想处理日期/时间。
答:使用java.util.Date类。你可以使用java.text.SimpleDateFormat类来在String和Da
te间互相转换。
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //规
定日期格式
Date date = formatter.parse("2003-07-26 18:30:35"); //将符合格式的String转换为
Date
String s = formatter.format(date); //将Date转换为符合格式的String
关于定义日期格式的详细信息请参见API。
 

J2EE FAQ
 
目录:

一、准备篇
Q1.1   什么是J2EE?它和普通的Java有什么不同?
Q1.2   J2EE好学吗?
Q1.3   J2EE有什么用?
Q1.4   学J2EE有前途吗?
Q1.5   据说J2EE的性能不如.NET好,是真的吗?
Q1.6   听你说了这么多,我想学着玩玩。
Q1.7   学习J2EE该怎么开始?
Q1.8   我下了一个J2EE服务器但是不会配置。
Q1.9   我发现你没有提到Tomcat。

二、 Servlet/JSP篇
Q2.1   什么是Servlet?
Q2.2   我怎么获得Http请求里的参数?
Q2.3   我怎么返回结果?
Q2.4   sendRedirect()和forward()有什么不同?
Q2.5   我写了一个Servlet程序,怎么运行它?
Q2.6   EAR和WAR有什么不同?
Q2.7   EAR格式是怎样的?
Q2.8   WAR格式是怎样的?
Q2.9   我的普通HTML文件/JSP文件应当放在哪里?
Q2.10  我访问不到servlet,甚至连HTML文件都访问不到!
Q2.11  我能访问HTML但是访问不到servlet。
Q2.12  什么是JSP?它和Servlet有什么区别?
Q2.13  我的JSP显示的汉字是乱码。
Q2.14  为什么使用gb18030而不是gb2312?
Q2.15  在JSP里面怎么引用Java Bean。
Q2.16  我想在servlet间传递数据。
Q2.17  怎么调用cookie?
Q2.18  怎么在JSP里面实现文件下载?
Q2.19  怎么实现文件上传?
Q2.20  我想让页面自动刷新,比如聊天室。
Q2.21  我想让用户登录以后才能访问页面。
Q2.22  我想要能注册用户。
Q2.23  怎么在JSP中访问数据库?
Q2.24  什么是JSTL?

一、准备篇

Q1.1  什么是J2EE?它和普通的Java有什么不同?
答:J2EE全称为Java2 Platform, Enterprise Edition。
“J2EE平台本质上是一个分布式的服务器应用程序设计环境——一个Java环境,它提供了

·宿主应用的一个运行基础框架环境。
·一套用来创建应用的Java扩展API。”

Q1.2  J2EE好学吗?
答:J2EE是很多技术的集合体,并且还在成长中。
你会遇到很多专有名词:比如(X)HTML,Servlet/JSP,JDBC,JMS,JNDI,EJB,XML,Web
Service……。
尤其是XML和Web Service正在快速成长。幸运的是,你不需要等到学会所有技术后再开始
编程。
大体上J2EE可以分成3个主要应用方式:Servlet/JSP,EJB,Web Service 和一些支撑技术
例如JDBC和JNDI。
你可以一个一个的学。

Q1.3 J2EE有什么用?
答:用来建设大型的分布式企业级应用程序。或者用更时髦的名词说就是“电子商务”应
用程序。
这些企业可能大到拥有中心数据库服务器,Web服务器集群和遍布全国的办公终端,也可能
小到只不过想做一个网站。但是你肯定听过“杀鸡焉用牛刀”的古训。

Q1.4 学J2EE有前途吗?
答:在这一市场目前只有一种技术可以和J2EE竞争,那就是Microsoft的.NET。
相对来说.NET要“新”一些而J2EE要“老”一些。这也意味着.NET更易用一点而J2EE更成
熟一点。
但是.NET只能用于Windows平台(Microsoft声称要开发C#在Linux上的虚拟机但是尚未兑现
该诺言)。
在过去几年,.NET的市场份额并不理想。不过Microsoft还有Longhorn这一杀手锏,鹿死谁
手还很难说。

Q1.5 据说J2EE的性能不如.NET好,是真的吗?
答:在Sun公司提供的样例程序Pet Store上,Microsoft声称不如相同的.NET程序好。
而Sun公司反驳说这一程序不能真正体现J2EE的性能,并且指责Microsoft在数据库上做了
优化。
作者没有学习过.NET因而不能妄下断言。
无论如何,大型分布式程序中的性能瓶颈通常首先来自于错误的设计。

Q1.6 听你说了这么多,我想学着玩玩。
答:除非你想靠它当饭吃或者作为技术储备,否则请不要浪费你的时间。
Flash要好玩得多。计算机游戏就更加好玩了。

Q1.7 学习J2EE该怎么开始?
答:首先,下载一个免费的J2EE服务器。其次,去java.sun.com下载J2EE的API。第三,找
一本好的参考书。最后,找一个顺手的IDE。
J2EE服务器。你可以用Sun的J2EE SDK(免费),或者Weblogic(性能最好,但是太大,而
且作者不推荐盗版行为),
或者JBoss(免费,就是文档太少),或者JRun(开发版免费,作者用这个)。
参考书作者感觉Wrox的《J2EE服务器端高级编程》不错,但是太老(作者手头的是2001年
中文版)。
(似乎很多人不喜欢这本书......所以你得自己判断它是否适合你。)
你还需要去下载一些最新的技术资料(当然肯定是英文的)。
IDE如果你的机器配置够好(内存至少512M以上,256M或以下请勿考虑),可以用IBM的WS
AD,不然就继续用Eclipse或者其他。
你也可以经常去水木清华的Java版逛逛,但是在发贴前先看看精华区里有没有你要的答案

Q1.8 我下了一个J2EE服务器但是不会配置。
答:请认真阅读随机指导文档,不同的服务器的配置都不一样,作者爱莫能助。

Q1.9 我发现你没有提到Tomcat。
答:Tomcat只是一个Web服务器,更准确地说主要只是一个Web Container。
如果你想要学习EJB的话,Tomcat无法满足你的需要。

二、 Servlet/JSP篇

Q2.1 什么是Servlet?
答:一个Servlet是一个Java类。它处理Http(s)请求并作出响应,包括返回一个HTML页面
或转交给其他URL处理。
Servlet必须运行在一个Web Container例如Tomcat中。
Servlet必须是javax.servlet.http.HttpServlet的子类,
你可以继承doGet()或者doPost()方法,两者分别对应于Http(s)中的Get请求和Post请求。


Q2.2 我怎么获得Http请求里的参数?
答:HttpRequest的getParameter()方法。例如:String paramValue = request.getPara
meter("paramName");

Q2.3 我怎么返回结果?
答:你可以利用相关API打开一个输出流,并向流中直接写入一个HTML页面。
但是作者完全不赞成这样做。一方面这样做会很罗嗦。
另一方面从Model-View-Controller模式(在《J2EE核心模式》中被归为Front Controlle
r模式)的观点来看,
你应当提供一些HTML或者JSP作为视图(view),而Servlet则根据请求参数决定转到哪一
个视图。
你可以利用response.sendRedirect(...)方法或request.getDispatcher(...).forward()
方法来实现。

Q2.4 sendRedirect()和forward()有什么不同?
答:sendRedirect()是向浏览器发送一个redirect通知,浏览器向新的URL发送一个新的请
求。
而forward是在服务器端直接将请求转到新的URL,对于浏览器是透明的。
换而言之,sendRedirect()应当将共享数据放在session中,forward应当将共享数据放在
request中(当然你也可以放在session中,但放在request中可以有效减小session中的数
据量,从而改善性能)。
前者浏览器的地址栏显示的是新的URL,后者浏览器的地址栏显示的是Servlet的URL。
因而当刷新目标URL时,两者会造成一些差别。

Q2.5 我写了一个Servlet程序,怎么运行它?
答:开发J2EE程序有一个部署(deploy)的概念,实际上是开发——部署——运行的三部
曲。
大多数服务器支持Hot deploy。你只需要在相应的Application目录(具体路径依赖于服务
器)下面
建立一个符合WAR或EAR格式(参见Q2.7,Q2.8)的目录,启动服务器,就可以通过浏览器
访问了。
特别的,你的Servlet的class文件应当放在/WEB-INF/classes目录中。
注意J2EE SDK不支持Hot deploy,你需要通过它的deploy tool来部署。
Tomcat只支持WAR格式。

Q2.6 EAR和WAR有什么不同?
答:EAR是一个完整的J2EE应用程序,包括Web部分和EJB部分。
WAR只是其中的Web部分。

Q2.7 EAR格式是怎样的?
答:一个EAR可以包含任意多个WAR或EJB JAR,并且包含一个META-INF的目录。
在/META-INF中包含了一个application.xml,其中描述了这个EAR包含哪些模块,以及安全
性配置。
细节请看参考书。

Q2.8 WAR格式是怎样的?
答:一个WAR包含一个WEB-INF的目录,这个目录下包含classes目录,lib目录和web.xml。

/WEB-INF/classes存放按package组织的class文件,/WEB-INF/lib目录存放jar文件,
web.xml描述了很多东西,请读参考书。

Q2.9 我的普通HTML文件/JSP文件应当放在哪里?
答:放在除了/WEB-INF以外的其他地方。

感谢antegg网友对于安全性的提醒:
如果你想直接用http://url/***.jsp的方式来访问,就要像上面说得那样放。
但是这样的做法是不安全的,安全的做法是把所有的JSP页面放在/WEB-INF目录下面,并且

通过WEB-CONTAINER来访问。

作者意见:
我更喜欢用filter来做安全性检查。
在MVC模式中,JSP只是一个视图而已,一般无需特别担忧安全性。和普通的html放在一起
也利于维护。

Q2.10 我访问不到servlet,甚至连HTML文件都访问不到!
答:
第一你没启动服务器。
第二你敲错了端口。
第三你没有正确配置context-path。
第四你的服务器不支持auto reload或者你关闭了这一选项,你得重启服务器或重新部署W
AR。
第五确认你没有把HTML放在/WEB-INF目录下,那是访问不到的。

Q2.11 我能访问HTML但是访问不到servlet。
答:请检查你的web.xml文件。确保你正确定义了<servlet>和<servlet-mapping>元素。

前者标识了一个servlet,后者将一个相对于context-path的URL映射到一个servlet。
在Tomcat中你可以通过/context-path/servlet/package/servletname的形式访问servlet

但是这只是Tomcat的便捷访问方式,并不是正式规范。
细节请看参考书。

Q2.12  什么是JSP?它和Servlet有什么区别?
答:你可以将JSP当做一个可扩充的HTML来对待。
虽然在本质上JSP文件会被服务器自动翻译为相应的Servlet来执行。
可以说Servlet是面向Java程序员而JSP是面向HTML程序员的,除此之外两者功能完全等价

Q2.13  我的JSP显示的汉字是乱码。
答:在你的JSP开头加上一行 <%@ page contentType="text/html; charset=gb18030"%>

如果你已经声明了page我想你知道该怎么修改。

Q2.14  为什么使用gb18030而不是gb2312?
答:gb18030是继gb2312之后的下一代汉字编码标准,最终将过渡到Unicode。

Q2.15  在JSP里面怎么引用Java Bean。
答:首先,确认你要引用的类在/WEB-INF/classes下或在/WEB-INF/lib的某个jar内。
其次,在JSP里加一行 <jsp:useBean id="..." scope="..." class="..."/>
具体解释请看参考书。

Q2.16  我想在servlet间传递数据。
答:利用session。在Servlet/JSP中,你可以在4个地方保存数据。
1) page,本页面。
2) session,用来存放客户相关的信息,比如购物车,对应接口为javax.servlet.http.H
ttpSession。
session机制实际上是cookie和URL Rewriting的抽象,服务器会自动使用cookie或URL Re
writing来实现。
3) request,可以在forward()时传递信息,对应接口为javax.servlet.http.HttpReques
t。
4) application,或称context,存放全局信息,对应接口为javax.servlet.ServletCont
ext。

Q2.17  怎么调用cookie?
答:作者建议使用session,你总是会遇到某些禁用cookie的用户。这时session会自动使
用URL重写来实现。

Q2.18  怎么在JSP里面实现文件下载?
答:实际上这是一个HTML的问题。答案是一个超链接<a>。

Q2.19  怎么实现文件上传?
答:客户端是HTML问题,在form中设置method为post,enctype为multi-part/form-data,
加一个<input type="file">。
而在接收的servlet中只是一个I/O问题,你可以使用jakarta的file-upload库。

Q2.20  我想让页面自动刷新,比如聊天室。
答:这是一个HTML问题,在<head>部分中加一条<meta http-equiv="refresh" content="
5" url="...">。
这是所谓的Client-pull,客户端刷新技术。
相对的还有Server-push,服务器端刷新技术,但是这一技术由于要占用服务器端资源而会
在大量访问时出现瓶颈现象,参见http://216.239.33.104/search?q=cache:autUfoakirY
J:www.kfunigraz.ac.at/edvndwww/books/books/javaenterprise/servlet/ch06_03.htm+
server-push+servlet&hl=zh-CN&ie=UTF-8

Q2.21  我想让用户登录以后才能访问页面。
答:使用声明式安全措施。
你只需要在web.xml中定义安全角色(Role),并定义受保护的URL集合只能由特定Role访
问。
大多数服务器支持基于数据库的用户映射,你只要在相应数据库中建立两张表并配置服务
器就可以了。
注意J2EE SDK不支持基于数据库的用户映射。
细节请看参考书和服务器文档。
不过在商业环境中,J2EE所提供的声明式安全措施仍然偏弱。一般商业程序会使用数据库
存储user-role-privilege模型来达到安全性要求,细节请询问你的构架设计师。

Q2.22  我想要能注册用户。
答:参看Q2.21。在接受注册请求的Servlet中执行写入数据库操作即可。

Q2.23  怎么在JSP中访问数据库?
答:标准做法是使用DAO模式,定义一个Java bean来访问数据库并在JSP中使用。
然而,当你的数据库模式很简单时,你可以使用JSTL中的<sql:query>标签来快速访问。

在一般的J2EE项目中,JSP处于表示层(展现层),需要先后通过业务层和集成层才会访问
到数据库,所以这个问题确实只会在很小的程序中才会遇到。

Q2.24  什么是JSTL?
答:JSTL是Jsp Standard Tag Library的缩写。这是一组通用标签并将成为JSP 2.0的一部
分。
其中包含赋值<c:set>,分支<c:if>,循环<c:forEach>,查询数据库<sql:query>,更新数
据库<sql:update>
等。目前你需要像添加自定义标签库一样来添加JSTL,但是可以预计JSP 2.0会将JSTL作为
组成部分。
标签库可以在http://jakarta.apache.org下载。注意JSTL需要在支持JSP 1.2或更高版本
的容器下运行。
帮助文件可以阅读sun的JSTL正式规范
posted @ 2006-08-16 14:43 阿成 阅读(249) | 评论 (0)编辑 收藏
(转自:转自:http://cutelife.bokee.com/blog/3474380.html
前言:该文章只是简单介绍一下hsql的入门内容,如果想仔细了解的话,参考官方帮助文档最为有用。

一、简介:
hsql数据库是一款纯Java编写的免费数据库,许可是BSD-style的协议,如果你是使用Java编程的话,不凡考虑一 下使用它,相对其他数据库来说,其体积小,才563kb。仅一个hsqldb.jar文件就包括了数据库引擎,数据库驱动,还有其他用户界面操作等内容。 在Java开源世界里,hsql是极为受欢迎的(就Java本身来说),JBoss应用程序服务器默认也提供了这个数据库引擎。由于其体积小的原因,又是 纯Java设计,又支持SQL99,SQL2003大部分的标准,所以也是作为商业应用程序展示的一种选择。请到以下地址下载hsql: http://prdownloads.sourceforge.net/hsqldb/hsqldb_1_7_3_3.zip?download

二、使用hsql数据库:
1、hsql数据库引擎有几种服务器模式:常用的Server模式、WebServer模式、Servlet模式、Standlone模式、Memory-Only数据库。
2、最为常用的Server模式:
1)首先却换到lib文件夹下,运行java -cp hsqldb.jar org.hsqldb.Server -database.0 db/mydb -dbname.0 xdb
执行命令后,将会在db文件夹下创建一个数据库mydb,别名(用于访问数据库)是xdb,如果存在mydb数据库,将会打开它。
2)运行数据库界面操作工具:java -cp hsqldb.jar org.hsqldb.util.DatabaseManager
在Type 选项里选上相应的服务器模式,这里选择HSQL Database Engine Server模式;Driver不用修改;URL修改为jdbc:hsqldb:hsql://localhost/xdb (主要这里xdb就是上面我们设置的别名);user里设置用户名,第一次登录时,设置的是管理员的用户名,password设置密码。然后点击Ok。
3)第一次运行数据库引擎,创建数据库完毕。好了,你可以打开db文件夹,会发现里面多了几个文件。
mydb.properties文件:是关于数据库的属性文件。
mydb.script:hsql主要保存的表(这里按hsql的说法是Memory表,就是最为常用的),里面的格式都是文本格式,可以用文本查看,里面的语句都是sql语句,熟悉sql语句的话,你也可以手动修改它。每次运行数据库引擎的话都是从这里加载进内存的。
mydb.lck表示数据库处于打开状态。
其他的请参看hsqldb包里的手册。

3、WebServer模式和Server运行模式基本一样,只是支持了Http等协议,主要用于防火墙,默认端口是9001。启动Server,java -cp hsqldb.jar org.hsqldb.WebServer ...剩余的和上面的一致。

4、Servlet模式可以允许你通过Servlet容器来访问数据库,请查看hsqlServlet.java的源代码,和WebServer类似。

5、 另一个值得思考的模式是Standalone模式:不能通过网络来访问数据库,主要是在一个JVM中使用,那样的话,访问的速度会更加快。虽然文档里面提 到主要是用于开发时使用,但是我们可以假设一下,该方法不需要一个引擎类的东西,而类似于打开文件的方式,返回一个Connection对象:
Connection c = DriverManager.getConnection("jdbc:hsqldb:file:mydb", "sa", "");
将 会在当前目录找到mydb数据库相关文件,打开并返回一个Connection对象。该方式有点好处就是可以不使用引擎,在需要的时候操作数据。所以那些 对数据库不是特别有要求的,但又需要一个操作数据库的方式的话,可以使用这种方法。对于那些不想额外在数据库引擎花费金钱的话,可以使用这种方法。但是不 推荐使用该方法。记得Hibernate里SessionFactory可以使用openSession(Connecttion c)来获得一个Session对象的,因此,在测试或者实际应用的话都可以这样使用。

6、Memory-Only 数据库:顾名思义,主要是内存中使用,不用于保存数据。可以用于在内存中交换数据。

三、具体的链接与操作的话,和一般的JDBC操作一样。而相应的Server模式的话,连接地址主要你运行数据库界面操作工具时,在URL一栏时默认已经设好了,自己实习一下,对比其中参数。

这篇文章介绍大致内容很详细,不过也大都是从Hsql的帮助上翻译的,我有必要加入点新鲜的血液。
这篇文章美中不足的是缺少实战性,往往初学者第一步都走不出来,比如我。
我在实践中遇到的问题是打开数据库管理器怎么也连接不上数据库,总是说
java.sql.sqlException Socket create error
搞了一个晚上,到第二天早上清醒一下,想起来这个数据库应该在创建库之后,保持那个cmd窗口,在此过程中连接。
果然好用,也迈出了开拓Hsql的第一步。

另外不用在互联网上搜索别的介绍,Hsql自带的guide就已经很详细了。

posted @ 2006-08-16 14:24 阿成 阅读(299) | 评论 (0)编辑 收藏

1.如何调试.jsp文件
  现在.jsp文件的前一个.java文件设端点,再在.jsp文件设端点,debug下先停在.java文件的断点处,执行到下一断点,即.jsp文件中。

尽管这样,有时用jdeveloper在jsp里设置断点还是不太管用。

2.如何显示原文件的改变
对 于模板元素的改变(html和javascript)只需要保存,刷新页面即可;对于脚本元素、jsp标签的改变要先make再刷新页面;如果不行的话就 重新run项目;再不行就设断点,一步一步走过改变的代码;再不行就把class文件夹全部删掉,让他重新编译;再不行就重启机器。对于html中引用的 图片或是script函数,修改后很可能还显示原来的,这是可能是在某个临时文件夹存有原来的文件,以上方法无效,这时要把定义函数的名字和引用函数的名 字都改变,使电脑不得不找临时文件以外的文件,这样才会显示改变,对于图片则是改变文件名称。

3.如何run和debug
run或debug之前都要把之前的run或debug先terminate,这样才能避免错误。

4.本机调试时用户名如果为"acheng"会变成"jazn/acheng",所以取用户名一定要先过滤掉 "jazn/",这样在本机调试和服务器调试时都不会龃?
username = remoteUserName.substring(remoteUserName.indexOf("/") + 1, remoteUserName.length());

5.确定网站入口:打开图形化的struts_config.xml,右键单击想作为入口的.do或.jsp文件,选择“set as default run target”选项,即可。struts_config.xml中的welcome标签就没用了。

6. 建立自定义库:右键单击某项目,选择project properties -> properties -> libaries -> new... 则打开creat libary对话框,单击add entry把该库向关的所有jar包选中,再添上此库名称以后即可用了。

7.引入已有的项目
对于.war或.ear文件可以File -> Import -> 选择相关的加入方式。
对于已经解压的文件夹(以Struts书上的addressbook为例)
  a.先建立空工作区addressbook,建立空项目addressbook,新建struts。
  b.把源文件根目录的图片和.jsp文件拷贝到新文件public_html下。
  c.用源文件WEB-INF替换新文件public_html下WEB-INF。
  d.用源文件src替换新文件src。
  e.把新文件WEB-INF下classes中的.properties文件拷贝到src相应位置,后删除classes文件夹。

8.制作oracle portlet只能在jdeveloper10.12上进行,并且portlet上的链接根目录必须如下表示:(不可以)
<%
    String server=null;
    StringBuffer buff = new StringBuffer();
    buff.append(request.getScheme()).append("://");
    buff.append(request.getServerName()).append(":");
    buff.append(request.getServerPort());
    buff.append(request.getContextPath());
    server = buff.toString();
%>
<a href="<%=server%>/login/login.jsp">login.jsp</a>
<!--a href="login/login.jsp">login.jsp</a--><!--这样写不行,可能portlet找不到这样的位置-->

posted @ 2006-08-16 14:14 阿成 阅读(594) | 评论 (0)编辑 收藏

1。插件安装有三种方法:

    a、是将文件靠到eclipse的根目录,如文件夹取名为chajian,下层文件夹为eclipse,下层文件夹为     features和plugins,再在eclipse的根目录建links文件夹,内部建chajian.link,编辑为path=    chajian (或者c:/eclipse/chajian,即绝对和相对路径皆可),就ok了(多个插件可以定义一个        pluge.link,一个path=***一行;或者定义多个.link文件,每个包含一个path)。

    b、是把插件包内的plugins和features内的文件拷贝到本目录下plugins和 features中。

    c、通过Help->Software Update->Find and Instal直接安装

2.打包成jar文件时,需要根据自定义的文件生成MANIFEST.MF,其中每行的冒号后面都有一个空格,否则出错。例:Manifest-Version: 1.0(1.0前有空格,其他行也是如此)

3.由数据库中的表自动建立.java和.hbm.xml文件

    a.建立项目:打开带HibernateTools插件的eclipse,建立一个名为“test”的java project,内部新   建一个名字为src的source folder。

    b. 建立hibernate配置文件:新建“hibernate configuration file”,输出路径选择“test项目的src目录”,然后的对话框填写配置文件(包括database dialect,driver class,connection url,username,password,creat a console configuration),下一个对话框先填写name(即console configuration name),再点“add external jars”,选择数据库驱动的jar文件,看到src中有“hibernate.cfg.xml”就是配置文件建立成功。

    c. 建立目标文件:点工具栏hibernate图标,选择“hibernate code generation...”,在弹出的对话框中点击左侧“新建”,把名字改为“test”,console configuration选刚才建立的console configuration name,package填想生成的包结构,点reveng.xml的“setup”,接下来对话框选择test的src目录,然后导入需要的数据库表(有关联的就要导入,即外键的表也要导入),然后点“finish”;选择main右边的exporters,选中generate domain code,generate mappings三项,run,刷新项目,看到包中生成的.java和.hbm.xml文件,成功,把它们拷入myeclipse的相应项目里。

hbm文件的主键有一条<generator class="assigned"/>表示用程序来设置主键,一般改为"increment"表示递增生成主键。 

  d.删除Console Configuration:打开Hibernate Console的透视图(perspective),在左侧Hibernate Configuration的视图(view)中右键单击,就可以删除。
删除Hivernate Code Generation:点击工具栏Hibernate图标,左侧即可删除。


4.eclipse 中程序代码做了改变但服务器上的代码没有同步改变,先看其他项目是否也如此(我上次遇到这问题其他项目可以同步改变,故不是eclipse的问题,应该是这个项目的问题);我用尽各种方法都不行,最后把项目从workspace中考出,运行eclpse关闭,再考进去项目,运行,就好了(为什么我也不清楚,可能保存了默认的一些错误设置吧);后来又遇到这种问题,action中的代码改了不起作用,上面方法也不行,删除workspace中代码,再 checkout,就ok了。看来遇到不能同步的问题应该在workspace中删除程序,再checkout就好了。

5.CVS的bug

    在用MyEclipse的CVS时发现,如果项目里其他人新建了文件夹,自己同步代码时就会出错。就算自己也新建了那个文件夹也不行,难道是个bug?还是使用方法的不当。

6.显示列号方法:eclipse的preferences
    a)General -> Editors -> Text Editors -> Show Line Number(java代码行号)
    b)MyEclipse -> Editors => Common Editor Preferences -> Show Line Number(jsp加行号)
都选中

7、按ctrl+t会列出接口的实现类列表

8、页面和java文件的缩进宽度
MyEclipse -> Editors => Common Editor Preferences 的 Displayed tab width可以调整jsp页面的缩进宽度
windows->java->Code Style->Formatter->Edit

9、查看某个具体文件或类,变量等
F3或按住crtl点名字

posted @ 2006-08-16 14:10 阿成 阅读(1285) | 评论 (0)编辑 收藏
仅列出标题
共10页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last