posts - 39,  comments - 44,  trackbacks - 0
 
关于RSS

RSS是站点用来和其他站点之间共享内容的一种简易方式(也叫聚合内容)

在门户网站大行其道,人们已经习惯通过搜索引擎来获取新闻资讯的今天,一种全新的资讯传播方式已经悄悄地来到我们身边,仔细观察一些网站,你可能注意到一些被标记为"XML"或"RSS"的橙色图标。

面对扑面而来的新闻,不用再花费大量的时间冲浪和从新闻网站下载,只要通过下载或购买一种小程序,这种技术被称为简易信息聚合(RSS:Really Simple Syndication)。RSS会收集和组织定制的新闻,按照你希望的格式、地点、时间和方式,直接传送到你的计算机上。新闻网站和那些在线日记作者已体会到了RSS提要带来的乐趣,这也使读者可以更容易跟踪RSS提要

RSS是一个缩写的英文术语,在英文中被认为有几个不同的源头,并被不同的技术团体做不同的解释。它既可以是"Rich Site Summary"(丰富站点摘要),或"RDF Site Summary"(RDF站点摘要),也可以是"Really Simple Syndication"(真正简易聚合)。现在已有的有Netscape, 1.0 (RSS-DEV版本),和 0.9x and 2.0 (UserLand Software版本) 0.9x和2.0。不过几乎所有能支持RSS的程序都可以浏览不同版本的RSS。

RSS是基于文本的格式。它是XML(可扩展标识语言)的一种形式。通常RSS文件都是标为XML,RSS files(通常也被称为RSS feeds或者channels)通常只包含简单的项目列表。一般而言,每一个项目都含有一个标题,一段简单的介绍,还有一个URL链接(比如是一个网页的地址)。其他的信息,例如日期,创建者的名字等等,都是可以选择的。

RSS是站点用来和其他站点之间共享内容的一种简易方式(也叫聚合内容),通常被用于新闻和其他按顺序排列的网站,例如Blog。一段项目的介绍可能包含新闻的全部介绍,Blog post等等。或者仅仅是额外的内容或者简短的介绍。这些项目的链接通常都能链接到全部的内容。网络用户可以在客户端借助于支持RSS的新闻聚合工具软件(例如NewzCrawler、FeedDemon),在不打开网站内容页面的情况下阅读支持RSS输出的网站内容。网站提供RSS输出,有利于让用户发现网站内容的更新。

RSS如何工作?首先您一般需要下载和安装一个RSS阅读器,然后从网站提供的聚合新闻目录列表中订阅您感兴趣的新闻栏目的内容。订阅后,您将会及时获得所订阅新闻频道的最新内容。 对于一般用户来说,用RSS订阅新闻可以像使用Outlook Express收取订阅的邮件一样简单;而对于Web应用程序的开发者而言,RSS的工作过程也不是那么复杂,至少比大多数其他常见的Web技术都更容易被理解和被实现。 有人认为,RSS的初衷似乎是为了给邮件列表订阅服务以致命的打击,若从RSS的应用方式来看,这几乎是不可避免的。但从实际效果来看,RSS最火爆的应用并非是商业信息的集中订阅,而是个人通过Web实现的信息聚合,一个典型的例子就是各国的网志作者(Blogger)首先成为最普遍的RSS应用人群。
posted @ 2008-04-01 19:42 矿矿 阅读(96) | 评论 (0)编辑 收藏
create database hy
on primary --默认就属于primary主文件组
(
--主数据文件的具体描述
 name='hy_data', --主数据文件的逻辑名
 filename='E:\temp1\hy_data.mdf', --主数据文件的物理名
size=3mb,--主数据文件的初始大小
maxsize=100mb,--主数据文件的增长最大值
filegrowth=10%--主数据文件的增长率
),(
  --次数据文件的具体描述,具体参数含义同主数据文件的含义
 name='hyn_data',
 filename='E:\temp1\hyn_data.ndf',
size=3mb,
maxsize=100mb,
filegrowth=10%
)
log on
(
--日志文件的具体描述,各参数的含义同主数据文件各参数含义
 name='hylog_log1',
 filename='E:\temp1\hylog1_log.ldf',
size=1mb,
filegrowth=10%
),(
--次日志文件的具体描述,具体各参数含义同上
name='hylog_log2',
 filename='E:\temp1\hylog2_log.ldf',
size=1mb,
filegrowth=10%
)
use hy
go
create table 忍者派别表   --创建忍者派别表
(
  编号 int,--编号
  称号 Nvarchar(20) not null --称号
)
go
 create table 师傅表--创建师傅表
(
 编号 int,--编号
 姓名 Nvarchar(20) not null,--姓名
 称号 int--称号
)
go
create table 忍者信息表--创建忍者信息表
(
编号 int identity(1,1),--编号
姓名 Nvarchar(20) not null,--姓名
性别 char(2),--性别
攻击力 int,--攻击力
派别 int not null,--派别
师傅 int not null--师傅
)
go
 --为忍者派别表添加约束
alter table 忍者派别表
add constraint pk_编号 primary key (编号)
go
--为师傅表添加约束
alter table 师傅表
add constraint pk_ 编号 primary key (编号)
称号 int not null
go
--为忍者信息表添加约束
alter table 忍者信息表
add constraint pk_ 编号 primary key (编号)
add constraint df_性别
default ('男') for 性别
攻击力 int check(攻击力>0)
派别 int references 忍者派别表(编号)
师傅 int not null references 师傅表(编号)
go
--为忍者派别表添加数据
insert into 忍者派别表(编号,称号)values(1,'木叶下忍')
insert into 忍者派别表(编号,称号)values(2,'木叶中忍')
insert into 忍者派别表(编号,称号)values(3,'木叶上忍')
insert into 忍者派别表(编号,称号)values(4,'砂隐下忍')
insert into 忍者派别表(编号,称号)values(5,'砂隐中忍')
insert into 忍者派别表(编号,称号)values(6,'砂隐上忍')
insert into 忍者派别表(编号,称号)values(7,'雨隐下忍')
insert into 忍者派别表(编号,称号)values(8,'雨隐中忍')
insert into 忍者派别表(编号,称号)values(9,'雨隐上忍')
insert into 忍者派别表(编号,称号)values(10,'音隐下忍')
insert into 忍者派别表(编号,称号)values(11,'音隐中忍')
insert into 忍者派别表(编号,称号)values(12,'音隐上忍')
insert into 忍者派别表(编号,称号)values(13,'岩隐下忍')
insert into 忍者派别表(编号,称号)values(14,'岩隐中忍')
insert into 忍者派别表(编号,称号)values(15,'岩隐上忍')
insert into 忍者派别表(编号,称号)values(16',云隐下忍')
insert into 忍者派别表(编号,称号)values(17',云隐中忍')
insert into 忍者派别表(编号,称号)values(18',云隐上忍')
insert into 忍者派别表(编号,称号)values(19',雾隐下忍')
insert into 忍者派别表(编号,称号)values(20',雾隐中忍 ')
insert into 忍者派别表(编号,称号)values(21',雾隐上忍')
insert into 忍者派别表(编号,称号)values(22',晓')
insert into 忍者派别表(编号,称号)values(23',逃之忍')
insert into 忍者派别表(编号,称号)values(24',火影 ')
insert into 忍者派别表(编号,称号)values(25',风影 ')
insert into 忍者派别表(编号,称号)values(26',雨影')
insert into 忍者派别表(编号,称号)values(27',音影')
insert into 忍者派别表(编号,称号)values(28',岩影')
insert into 忍者派别表(编号,称号)values(29',未知')
insert into 忍者派别表(编号,称号)values(99',三忍')
go
--为师傅表添加数据
insert into 师傅表(编号,姓名,称号)values(1,'旗木卡卡西',3)
insert into 师傅表(编号,姓名,称号)values(2,'依鲁卡',2)
insert into 师傅表(编号,姓名,称号)values(3,'自来也',99)
insert into 师傅表(编号,姓名,称号)values(4,'夕日红',3)
insert into 师傅表(编号,姓名,称号)values(5,'阿斯玛',3)
insert into 师傅表(编号,姓名,称号)values(6,'阿凯',3)
insert into 师傅表(编号,姓名,称号)values(7,'猿飞',24)
insert into 师傅表(编号,姓名,称号)values(8,'马基',6)
insert into 师傅表(编号,姓名,称号)values(9,'未知',29)
go
--为忍者信息表添加约束
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('漩涡鸣人','男',100,1,1)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('日向雏田','男',100,1,5)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('春野樱','女',60,1,1)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('犬冢牙','男',100,1,4)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('犬冢牙','男',100,1,4)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('山中井野','女',100,1,4 )
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('奈良鹿丸','男',150,2,5)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('宇智波佐助','男',200,1,1)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('秋道丁次','男',100,1,5)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('我爱罗','男',160,25,9)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('勘九郎','男',100,4,9)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('手鞠','女',110,4,9)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('白','男',120,20,9)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('桃地再不斩','男',180,23,9)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('干柿鬼鲛','男',250,22,9)
insert into 忍者信息表(编号,姓名,性别,攻击力,派别,师傅)values('药师兜','男',120,11,9)
go
--查询数据
select * from 忍者派别表
select * from 师傅表
select * from 忍者信息表



posted @ 2008-03-23 21:02 矿矿 阅读(141) | 评论 (0)编辑 收藏

一、三层体系架构

1.表示层(USL):主要表示Web方式,也可以表示成WINFORM方式。如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务。

2.业务逻辑层(BLL):主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理。如果说数据层是积木,那逻辑层就是对这些积木的搭建。

3.数据访问层(DAL):主要是对原始数据(数据库或者文本文件等存放数据的形式)的操作层,而不是指原始数据,也就是说,是对数据的操作,而不是数据库,具体为业务逻辑层或表示层提供数据服务。



二、具体区分

1.表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。

2.业务逻辑层:主要负责对数据层的操作,也就是说把一些数据层的操作进行组合。

3.数据访问层:主要看你的数据层里面有没有包含逻辑处理,实际上他的各个函数主要完成各个对数据文件的操作,而不必管其他操作。


三、总结

三层结构是一种严格分层方法,即数据访问层只能被业务逻辑层访问,业务逻辑层只能被表示层访问,用户通过表示层将请求传送给业务逻辑层,业务逻辑层完成相关业务规则和逻辑,并通过数据访问层访问数据库获得数据,然后按照相反的顺序依次返回将数据显示在表示层。

posted @ 2008-01-20 01:51 矿矿 阅读(147) | 评论 (0)编辑 收藏

 

一、 引言

  JMX(Java管理扩展)提供了一组工具用来管理本地和远程应用程序、系统对象、设备等。本文将解释如何使用JMX(JSR 160)来远程控制Web应用程序,并将解释应用程序中可用于JMX客户的代码,同时将展示使用如MC4J和jManage等的不同客户如何连接到支持JMX的应用程序。此外,我们还将详细地讨论使用RMI协议和JNDI来保护通讯层。
       首先我们要分析一个简单的web应用程序,它监控已经登陆的用户数目并通过一个安全的JMX服务来显示该项统计。我们还将运行这个应用程序的多个实例并且从所有的运行实例中跟踪这个统计数字。当然,你可以下载这个示例web应用程序。它需要你安装J2SE 5.0 SDK并且你的JAVA_HOME环境变量指向基安装目录。J2SE 5.0实现了1.2版本的JMX API和JMX 1.0版本的Remote API。同时还需要一个支持Servlet的容器;我使用的是Apache Tomcat 5.5.12。另外,我还使用Apache Ant来构建这一示例应用程序。

  二、 建立示例应用程序

  首先,你要下载示例应用程序并且使用ant war(更多的细节见build.XML中的注释)来创建一个WAR文件。把jmxapp.war复制到Tomcat的webapps目录。假定Tomcat正在运行于你的本地机器的端口8080,那么该应用程序的URL将是:

http://localhost:8080/jmxapp

  如果你看到一个提示你输入名字和口令的登陆屏幕,那么一切已经就绪了。

  三、 跟踪一些有意义的数据

  本文中的应用程序使用Struts框架来提交登录表单。一旦提交结束,即执行LoginAction.execute(..)方法-它将简单地检查是否用户的ID为"hello"以及是否其口令为"world"。如果二者都正确,那么登录成功并且控制被导向login_success.JSP;如果不正确,那么我们返回到登录表单。根据登录成功与否决定调用incrementSuccessLogins(HttpServletRequest)方法还是incrementFailedLogins(HttpServletRequest)方法。现在,让我们先分析一下incrementFailedLogins(HttpServletRequest):

private void incrementFailedLogins(HttpServletRequest request) {
 HttpSession session = request.getSession();
 ServletContext context =session.getServletContext();
 Integer num = (Integer) context.getAttribute( Constants.FAILED_LOGINS_KEY);
 int newValue = 1;
 if (num != null) { newValue = num.intValue() + 1; }
 context.setAttribute( Constants.FAILED_LOGINS_KEY, new Integer(newValue));
}

  这个方法增加一个在应用程序范围存储的FAILED_LOGINS_KEY变量。这个incrementSuccessLogins(HttpServletRequest)方法是以相似的方法实现的。该应用程序追踪有多少人成功地登录和有多少人认证失败。这真不错,但是我们该如何存取这些数据?这就是引入JMX的原因。

  四、 创建JMX MBeans

  MBeans基础知识及其适于JMX架构的方面超出了本文所讨论的范围。我们将为我们的应用程序简单地创建、实现、暴露和保护一个MBean。我们所感兴趣的是暴露相应与下列两个方法的两种数据。下面是我们的简单MBean接口:

public interface LoginStatsMBean {
 public int getFailedLogins();
 public int getSuccessLogins();
}

  这两个方法简单地返回成功和失败登陆的数目。LoginStatsMBean的实现-LoginStats,为上面两种方法提供了一种具体的实现。让我们分析一下getFailedLogins()实现:

public int getFailedLogins() {
 ServletContext context = Config.getServletContext();
 Integer val = (Integer) context.getAttribute( Constants.FAILED_LOGINS_KEY);
 return (val == null) ? 0 : val.intValue();
}

  该方法返回一个存储在ServletContext中的值。getSuccessLogins()方法是以相似的方式实现的。

  五、 创建和保护一个JMX代理

  管理应用程序的JMX相关方面的JMXAgent类有以下几个责任:

  1. 创建一个MBeanServer。

  2. 用MBeanServer注册LoginStatsMBean。

  3. 创建一个JMXConnector以允许远程客户进行连接。

   o 包含对JNDI的使用。

   o 也必须有一个RMI注册运行。

  4. 使用一个用户名和口令保护JMXConnector。

  5. 分别在应用程序启动和停止时,启动和停止JMXConnector。

  JMXAgent的类轮廓是:

public class JMXAgent {
public JMXAgent() {
//初始化JMX服务器
}
public void start() {
//启动JMX服务器
}
//在应用程序结束时调用
public void stop() {
//停止JMX服务器
}
}

  让我们理解在该构造器的这部分代码-它能够使得客户远程地监控该应用程序。

  用MBeans创建一个MBeanServer

  我们首先创建一个MBeanServer对象。它是JMX基础结构的核心组件,它允许我们暴露我们的MBeans作为可管理的对象。MBeanServerFactory.createMBeanServer(String)方法使得这一任务极为轻松。所提供的参数是服务器的域。可以把它当作这个MBeanServer的唯一的名字。然后,我们用MbeanServe来注册LoginStatsMBean。MBeanServer.reGISterMBean(Object,ObjectName)方法使用的参数有两个:一个是MBean实现的一个实例;另一个是类型ObjectName的一个对象-它用于唯一地标识该MBean;在这种情况下,DOMAIN+":name=LoginStats"就足够了。

MBeanServer server = MBeanServerFactory.createMBeanServer(DOMAIN);
server.registerMBean(new LoginStats(),new ObjectName(DOMAIN+ ":name=LoginStats"));
六、 创建JMXServiceURL

  到现在为止,我们已经创建了一个MBeanServer并且用它注册了LoginStatsMBean。下一步是使得该服务器对客户可用。为此,我们必须创建一个JMXServiceURL-它描述了客户将用来存取该JMX服务的URL:

JMXServiceURL url = new JMXServiceURL("rmi",null,
Constants.MBEAN_SERVER_PORT,
"/jndi/rmi://localhost:" +Constants.RMI_REGISTRY_PORT +"/jmxapp");

  让我们细致地分析一下上面一行代码。该JMXServiceURL构造器使用了四个参数:

  1. 在连接时使用的协议(rmi,jmxmp,iiop,等等)。

  2. JMX服务的主机。用localhost作为参数就足够了。然而,提供null强制JMXServiceURL找到可能是最好的主机名。例如,在这种情况下,它将把null翻译成zarar-这是我的计算机的名字。

  3. JMX服务使用的端口。

  4. 最后,我们必须提供URL路径-它指示怎样找到JMX服务。在这种情况下,它会是/jndi/rmi://localhost:1099/jmxapp。

  其中,/jndi部分是指,客户必须为JMX服务做一下JNDI查询。rmi://localhost:1099指示,存在一个运行于本机的端口1099的RMI注册。这里的jmxapp是在RMI注册中唯一标识这个JMX服务的。在JMXServiceURL对象上的一个toString()产生下列结果:

service:jmx:rmi://zarar:9589/jndi/rmi://localhost:1100/jmxapp

  上面是客户将最终使用来连接到该JMX服务的URL。J2SE 5.0文档有关于这个URL结构的更为详细的解释。

  (一) 保护服务

  J2SE 5.0提供了一种有利于JMX用一种容易的方式进行用户认证的机制。我创建了一个简单的文本文件-它存储用户名和口令信息。文件的内容是:

zarar siddiqi
fyodor dostoevsky

  用户zarar和fyodor被分别通过口令siddiqi和dostoevsky认证。下一步是创建并保护一个JMXConnectorServer,它暴露了该MbeanServer。username/password文件的路径被存储在该键下的一个映射中-jmx.remote.x.password.file。这个映射在以后创建JMXConnectorServer时使用。

ServletContext context = Config.getServletContext();
//得到存储jmx用户信息的文件
String userFile =context.getRealPath("/")+"/Web-INF/classes/"+Constants.JMX_USERS_FILE;
//创建authenticator并且初始化RMI服务器
Map<string> env = new HashMap<string>();
env.put("jmx.remote.x.password.file", userFile);
现在,让我们创建JMXConnectorServer。下面一行代码完成这一功能:
connectorServer = JMXConnectorServerFactory.
newJMXConnectorServer(url, env, server);

  这个JMXConnectorServerFactory.newJMXConnectorServer(JMXServiceURL,Map,MBeanServer)方法使用我们刚创建的三个对象作为参数-它们是JMXServiceURL,存储认证信息的映射和MBeanServer。其中,connectorServer实例变量允许我们分别在应用程序启动和停止时,分别用start()和stop()来启动和停止JMXConnectorServer。

  提示 尽管JSR 160的J2SE 5.0实现相当有力;但是另外的实现,例如MX4J,也提供了一些类-它们提供了方便的特性,例如口令混淆,也就是PasswordAuthenticator类。

  七、 启动RMI注册

  在早些时候,我提到RMI注册并且指出当访问服务时执行一个JNDI查询。然而,现在我们没有一个正运行的RMI注册,因此一个JNDI查询将失败。一个RMI注册的启动可以用手工方式或编程方式来实现。

  (一) 使用命令行

  在你的WindowsLinux命令行上,输入下列一名来启动一个RMI注册:

rmiregistry &

  这将启动你的默认主机和端口(分别是localhost和1109)的RMI注册。然而,对于我们的web应用程序来说,我们不可能依赖一个在应用程序启动时可用的RMI而宁愿用编程方式来实现之。

  (二) 以编程方式启动RMI注册

  为了以编程方式启动RMI注册,你可以使用LocateRegistry.createRegistry(int port)方法。该方法返回类型注册的一个对象。当我们想在应用程序一端终止这个注册时,我们保存这个参考。就在我们启动我们的在JMXAgent.start()中的JMXConnectorServer之前,我们首先启动RMI注册,使用下列代码行:

registry = LocateRegistry.createRegistry(Constants.RMI_REGISTRY_PORT);

  在应用程序一端,在JMXAgent.stop()中停止JMXConnectorServer之后,调用下列方法来终止该注册:

UnicastRemoteObject.unexportObject(registry,true);

  注意,StartupListener类触发了应用程序开始和结束任务。
八、 访问我们的JMX服务

  我们可以有好几种方法来存取JSR 160服务。为此,我们可以通过编程或通过使用一个GUI来实现。

  (一) 使用MC4J连接

  通过把jmxapp.war复制到Tomcat的Webapps目录来发布该应用程序。下载并且安装MC4J。一旦安装完,创建一新的类型JSR 160的服务器连接并且指定该服务器URL-它在应用程序启动时在应用程序服务器日志中打印。在我的示例中,它是:

service:jmx:rmi://zarar:9589/jndi/rmi://localhost:1100/jmxapp

  提供用户名和口令,MC4J分别把它们参考为"Principle"和"Credentials"。点击Next将把你带到一个屏幕-在此你可以定制你的classpath。默认设置应该工作正常,并且你可以点击"Finish"来连接到该JMX服务。一旦建立连接,浏览如图1所示的MC4J树结构,直到你找到LoginStats MBean实现的"Properties"选项。


图1.MC4J视图

  点击Properties显示统计,如图2所示:


图2.属性窗口

  (二) 使用jManage连接到一个"簇"

  通过把jmxapp.war复制到Tomcat的webapps目录发布该应用程序。请注意一下在应用程序启动时所打印的URL。接下来,发布这个应用程序的另一个实例-通过改变Constants类中的RMI_REGISTRY_PORT并且MBEAN_SERVER_PORT变量,这样该应用程序的第二个实例就不会试图使用已经在使用的端口了。改变在build.XML文件中的app.name属性,以便新的实例将被发布到一个不同的上下文(例如,jmxapp2)。用ant创建一个清理的war文件-它将在其目录下创建jmxapp2.war。把jmxapp2.war复制到Tomcat的webapps目录。该应用程序将要发布,而且现在你有相同应用程序的两个实例在运行了。我再次提醒你注意在启动时所打印的URL。

  下载和安装jManage。一旦安装了,使用jManage的web接口来创建一个JSR 160应用程序-通过使用主页中的"添加新应用程序"链接。"添加应用程序"页面显示在图3中:


图3."添加应用程序"页面

  为要发布的第二个应用程序重复前面的步骤并再次使用适当的用户名、口令和URL。。一旦你创建了这两个应用程序,你必须通过遵循在主页中找到的"添加新应用程序簇"链接来创建一个簇。现在,把这两个已经创建的应用程序添加到你的簇上,如图4所示:


图4.添加应用程序簇页面


  好了,我们已经完成了!从主页上,点击簇中的一个应用程序,然后点击"Find More Objects"按钮。你将看到name=LoginStats MBean;点击它,则你就会看到我们已经暴露的FailedLogins和SuccessLogins属性。点击在该同一页面上的"Cluster View"链接将显示与图5相类似的一个页面-其中,你可以看到两个应用程序的运行计数统计:


图5.针对jmxapp和jmxapp2的簇视图

  试着登录到两个应用程序(http://localhost:8080/jmxapp和http://localhost:8080/jmxapp2)并且观察这些数字是怎样改变的。

  九、 结论

  现在你已经知道了怎样使你的新的和现有web应用程序支持JMX并且安全地管理它们-使用MC4J和jManage。尽管J2SE 5.0提供了JMX说明书的一个有力的实现,但是另外的开源工程例如XMOJO和MX4J还提供了另外的特征,例如经由web接口甚至更多的方式的连接。如果有兴趣的读者想了解更多地有关JMX的知识,你可以看一下J. Steven Perry写的《Java Management Extensions》一书。如果你对远程应用程序管理感兴趣的话,Jeff Hanson写的《Connecting JMX客户and Servers》将是很有阅读价值的,其中提供了许多真实世界的例子。

posted @ 2008-01-20 01:47 矿矿 阅读(227) | 评论 (0)编辑 收藏
          J2SE 5.0中的Java.util.concurrent程序包提供了一个新的线程框架组件,这个框架组件处理了与建立、执行和管理线程相关的很多低层细节信息。在本文中我们将细致地了解一下它的重要特性。

  如果你使用C、C++或Java先前的版本进行多线程编程,就知道在代码中管理线程是多么头疼的事情。在单线程程序中,代码中引起应用程序失败的bug每次都在同一个点出现。但是在多线程程序中,只有某些原因遇到一起的时候才会出现失败。由于预见可能引发应用程序失败的所有条件是非常困难的,所以多线程编程是有挑战性的。有些程序员从根本上避免这种挑战,而另外一些--聪明的解决问题的人员--则一直坐在他们的计算机面前直到问题解决。

  J2SE 5.0平台包含了一个新的并发工具程序包。这个程序包中的类替并发类(concurrent classe)或并发设计中使用的应用程序建立阻塞(blocking)。该并发工具包含下面一些内容:

  · 高性能的、灵活的线程池

  · 异步执行事务的框架组件

  · 为并发访问优化过的集合类宿主(host)

  本文介绍了J2SE 5.0框架组件类和它们的重要特性。本文的下载代码提供了一些简单的、容易使用的示例,它演示了所有的新线程框架组件类。你在阅读文章内容之后运行这些示例可以使自己对这些特性有更好的理解。

  Executor(执行器)框架组件

  Executor框架组件提供了一个简单的、标准的、可扩充的类,它提供了一些有用的功能,如果没有这些功能,我们要手工实现这些它们,会觉得十分单调和困难。该框架组件使调用、调度和执行的操作标准化了。它通过一组执行策略为控制异步事务提供了支持。

  Executor接口执行已提交的可以运行的事务。它提供了一条途径,允许我们把事务提交从事务执行机制中分离出来。程序员通常使用Executor代替显式地(explicitly)建立线程。Executor接口也提供事务的同步和异步执行。

  对于同步执行,使用下面的命令:

Class MySynExecutor implements Executor{
 public void execute(Runnable r) {
  r.run();
 } 
}

  对于异步执行,使用下面的命令:

Class MyASynExecutor implements Executor{
 public void execute(Runnable r) {
  new Thread(r).start();
 }
}

  ExecutorService(执行器服务)类

  ExecutorService类为管理一个或多个异步事务的终止和跟踪事务执行的过程提供了方法。代码下载中的MyExecutorService.java文件演示了管理事务终止的过程。它初始化了大小为三个的线程池,然后依次添加了线程。当线程的数量达到线程池的大小限制时,它调用关闭(shutdown)方法。在调用shutdown()方法之后,这个线程池不再接受新事务的执行。在等待十秒以后,该线程池调用shutDownNow()。这个方法会尽最大的努力来终止所有运行中的事务。在示例中,应用程序试图终止运行中的线程失败了。

  ScheduledExecutorService(调度执行器服务)

  ScheduledExecutorService类是我的最喜欢的类。它对于调度那些周期性执行的事务非常方便,而周期性执行的事务对于清除工作(例如清除你的应用程序建立的临时文件等等)尤其有用。下载代码中的MyScheduledExecutorService.java文件通过每五秒钟发出"嘟嘟"一声演示了调度的过程:

final Runnable beeper = new Runnable() {
 public void run() { System.out.println("beep"); }
};
final ScheduledFuture beeperHandle =scheduler.scheduleAtFixedRate(beeper, 1, 5, SECONDS);
posted @ 2008-01-20 01:43 矿矿 阅读(2374) | 评论 (3)编辑 收藏
        首先说一说进入计算机专业的目的,我个人是因为十分喜欢IT业,很喜欢折腾电脑,所以在填报志愿是毫不犹豫的在报了的所有的学校都填写的计算机专业,梦想着进入计算机专业后能遇见很多高手,能交到几个知己,谁之进来后却大失所望。计算机专业的学生有很多以前对计算机不怎么了解,而且还有部分人进大学前连计算机摸都没摸过,对计算机很熟悉的很少,高手更是凤毛麟角,大多数人是服从了父母之命,显而易见,目前社会最热的行业是IT业,工资最高的也是IT业,抱着这个因素,大多数考生的父母都让自己的孩子进入了计算机专业,而大多数学生也天真的认为从计算机专业毕业后就能够像电视里演的大多数白领一样每天只用坐在办公室里和同事们聊聊天,和老板吃吃饭,每天签几个字然后就有高工资等着你去拿。

   进校后他们发现其实他们在专业课方面什么都听不懂,自己也一点兴趣都没有,没有兴趣那就没有学习的动力,而且这个专业是要靠悟性的,而兴趣是培养悟性的第一步,然后他们会发现越往后学专业课越难,也越听不懂,好一点的就会狠下心来,硬着头皮苦学一通,有可能也就能走出一片路来,而不好的就会就此放弃,只需要混着考试通过,混毕业,找个单位安心上班。有些人上了几年学连自己上哪些课都不知道;拿个程序他分不清是用C语言写的还是用PASCAL写的;不小心进了DOS不知道怎么再回到WINDOWS。但说起游戏来头头是道,好像每个都是职业玩家一样,有的每天只知道泡在网吧。这就是中国计算机人才下一代的悲哀!

   再说现在计算机专业大学生的学习和生活。大多数计算机专业的学生对本专业的发展及前景一无所知,每天都是看小说、玩游戏、看电影、打牌、喝酒、睡觉等等很有"前途"的事情。偶尔看见一两个同学看看与计算机专业有关的书,跑去拿来一看,全是什么"游戏攻略"、"黑客秘技"等此类书籍。还有的人连C语言和C++谁是谁都还没搞清楚,就拿本VC的书"刻苦钻研",真不知他们看懂了没有。好多学生都买了电脑,但用处都是游戏机+碟机+音响,每天都在用电脑玩着各种流行的游戏、看着最新的大片、听着时尚的音乐,就是不用电脑学习。有的学生甚至问我电脑除了玩游戏还能干什么,我问他你为什么这么问,他告诉我他觉得电脑只能用来玩游戏,不知道还能不能干干别的什么。据我了解,近几年在国内好几所高校的计算机专业的毕业生的毕业设计竟然是做网页,在大学了四年,学完了《数据结构》、《软件工程》、《C语言》等专业课后,竟然交了一个没有学过计算机的人自学一两天就能做好的东西!

  这就是大多数计算机专业的学生,在我在大学玩了两年之后,我突然明白该为自己的未来打算打算了,但还有许多人仍然还什么都不明白,所以就有了这篇文章。
如果你是以上我说的那种受父母之命来学计算机的学生,如果你看了《计算机应用文摘》第15期的《写给想当程序员的朋友》一文后,发现自己没有当程序员的欲望,那么我这里有几条路给你选择:
1、**页制作,将来去网站工作!
2、学习3D MAX等软件,去作动画!
3、学习美术设计!
4、网络,将来考个CCNA,去专业组网!
5、在保证能顺利毕业的前提下,去疯狂玩游戏,做个职业玩家或做一个或几个网络游戏的GM。(我身边就有这样的人)
6、以上五条都与计算机有关,要有一定的专业知识,但比起你的专业课简单多了。如果你看到这里还不觉得有适合你干的,那这条最适合你:在你们学校去修双学位,修一个自己感兴趣的专业,计算机真的不适合你!
如果以上几条有适合你的,那么你就努力去做适合你的那一片天地,去看杂志的下一篇文章,下面的文字你看了只会浪费你的时间。


   如果你是计算机专业的在校大学生,而且想当软件设计师,那么请往下看:
1、大学生活丰富多彩,会令你一生都难忘,但难忘有很多种,你可以学了很多东西而难忘,也会因为什么都没学到而难忘!
2、计算机专业是一个很枯燥的专业,但即来之、则安之,只要你努力学,也会发现其中的乐趣的。
3、记住:万丈高楼平地起!基础很重要,尤其是专业基础课,只有打好基础才能学得更深。
4、C语言是基础,很重要,如果你不学好C语言,那么什么高级语言你都学不好。
5、C语言与C++语言是两回事。就象大熊猫和小熊猫一样,只是名字很像!
6、请先学习专业课《数据结构》、《计算机组成原理》,不要刚开始就拿着一本VC在看,你连面向对象都搞不清楚,看VC没有任何用处。
7、对编程有一定的认识后,就可以学习C++了。(是C++而不是VC,这两个也是两码事!C++是一门语言,而VC教程则是讲解如何使用MFC类库,学习VC应建立在充分了解C++的基础之上。看VC的书,是学不了C++语言的。)
8、学习编程的秘诀是:编程,编程,再编程;
9、认真学习每一门专业课,那是你的吃饭碗。
10、在学校的实验室就算你做错一万次程序都不会有人骂你,如果你在公司你试试看!所以多去实验室上机,现在错的多了,毕业后就错的少了。
11、从现在开始,在写程序时就要养成良好的习惯。
12、不要漏掉书中任何一个练习题--请全部做完并记录下解题思路。
13、你会买好多参考书,那么请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码。
14、VC、C#、.NET这些东西都会过时,不会过时的是数据结构和优秀的算法!
15、记住:书到用时方恨少。不要让这种事发生在你身上,在学校你有充足的时间和条件读书,多读书,如果有条件多读原版书,你要知道,当一个翻译者翻译一本书时,他会不知不觉把他的理念写进书中,那本书就会变得像鸡肋!
16、我还是强调认真听专业课,因为有些课像《数据结构》、《编译原理》、《操作系统》等等,这种课老师讲一分钟能让你明白的内容,你自己看要看好几个月,有的甚至看了好几年都看不明白。
17、抓住在学校里的各种实践的机会,要为自己积累经验,就业时经验比什么都有用。
18、多去图书馆,每个学校的图书馆都有很多好书等你去看!
19、编程不是技术活,而是体力活。
20、如果你决定了要当一个好的软件设计师,那么请你放弃游戏,除非你是那种每天只要玩游戏就能写出好程序的天才!
21、你要有足够的韧性和毅力!有个高手出了一道题测试你的韧性和毅力:找个10000以内的素数表,把它们全都抄下来,然后再检查三遍,如果能够不间断地完成这一工作,你就可以满足这一条。
22、找到只属于你自己的学习方法!不要盲目的追随别人的方法,适合自己的才是最好的!
23、请热爱软件设计这项工作!
以上的话有些是我的经验,有些是我从高手那里直接COPY来的,但他们都很有用,记住他们,并遵守他们,那你们一定会成功!

   对于大多数初学者来说,好多人有这种问题存在:我到底先学什么?学C/C++?还是学VC?还是学Borland C++ Builder呢?还是Delphi?哪一个更好呢?学习程序设计和学习程序设计语言究竟是怎么一个关系?初学者究竟应该如何取舍呢?就这些问题,我从一个高手那里看了一下的这段话,可以帮助在这方面有问题的人:学习程序设计就好比学习射击,而程序设计语言就对应射击中的气枪、手枪、步枪等各种枪械。学习射击必须要选择一种枪械,不可能没有枪还能学好射击的,也不可能同时学会使用所有的枪械。但是,如果掌握一种枪械的射击,再学别的也就触类旁通了。因为在熟悉一种枪械的同时,也学习了射击技术本身。再学其他的,自然事半功倍。学习程序设计也是一样,必然要从学习一门程序设计语言开始入手。在学会系统的编程理念之后,用什么工具都一样!

   之所以写这篇文章呢是因为自己眼看身边那么多的同学一个个都"不务正业",荒废了学业,心急如焚,自己也荒废了好几年,眼看微软的Windows从3.X到现在的2003 Server,而中国的软件业还是在原地踏步,难道我们真要每年等微软给他的操作系统换一次名字,我们给他交一次钱吗?这么大的利润为什么不留给我们自己,为什么不让别的国家给我们交钱呢?这是广大中国软件工程师的一个共同的梦,要实现这个梦的人是现在还在大学里的"软件设计师"们,他们是中国软件明天的希望!希望广大计算机业的大学生看到这篇文章后,睡觉的能醒来,玩游戏的能停下来,在网吧的能出来,一起拿起课本,坐在电脑前,用程序写出中国软件业明天的辉煌!

附: 虽然非常的现实,对有些同学来说有点残酷,但是的是一针见血!!!!! 
posted @ 2008-01-20 01:38 矿矿 阅读(446) | 评论 (1)编辑 收藏
前段时间考过了SUN CERTIFIED JAVA PROGRAMMER ,考完后一直很忙,现在闲下来,和大家分享一下考试的经验 。

  1 ) JAVA 2 PLAT FORM 考试科目是310-025 ,有59题,及格线是61%,即答对36题。考试时间是90 分钟。特别令人厌恶的是考试前有个AGREEMENT,连你读它的时间也被计算在内。小弟开始不知道,还在慢慢读,突然发现已经用了3分钟,赶紧开始作题。估计 AGREEMENT 没有什么重要的东西,可以直接跳过。时间勉强够用,我大概花了60分钟作完题,剩下20多分钟检查,居然又给我发现了3-5 题错误,都是一时疏忽,落入题目设下的圈套,所以一定要留时间检查。可惜我剩下10 题左右没有时间检查 。

  2)考试范围非常窄。基本上都是基本语言知识,象SWING,JSP,SERVLET,JDBC,BEANS等等都不涉及。大家可以到SUN 网站上下载考试大纲。考试范围窄不意味着容易,相反,一些很基本的东西被翻来覆去,变着花样考,反而更难 。

  3)考试只有选择题,包括单选和复选。多数复选题明确指明有几个答案,不会搞错。

  4)印象中几乎所有的考题都涉及2-3个以上的知识点,几乎没有可以一眼就看出答案的题目。70%的考题是给你一段程序,然后问运行结果变量的值。这种题目非常容易落入陷阱,一不小心就被费了。还有20%的题目是给你几个陈述句,选正确的。这些陈述句都是考很偏很偏的东西,也不太好答。基本上我的经验是:如果一个题目马上能看出答案,请你在仔细研究一下题目,多数情况是你落入陷阱了。如果一个题目你能很明确的看出来他要考你什么知识点,那这个题目就完成一半了。最惨的是知道题目要考你什么,但是忘记了或没有复习相关知识细节,只好胡猜答案了。

  5)考试的一个重点是INNER CLASS。印象中一半以上的题目和他有关。都是大CLASS套小CLASS 等。我复习时花了很多时间在这上面,以为自己很懂了,结果考试是还是有问题。一定要透彻理解相关定义,语法,特别是各种各样的MODIFIER 的用法。有很多很特殊的MODIFER 规则。这些规则一定要熟练掌握并牢记在心。

  6)考试的另一个重点是循环语句。我考,我自以为对循环控制语句很熟悉了,结果考试考一些很偏很特别的用法,虽然慢慢作都能作出来,但浪费太多时间在这上面,实在可惜。大家好好看看书。

  7)其它的象:CASTING ,IO ,LAYOUT ,EVEN HANDLING,AWT,THREAD,GARBAGECOLLECTION,MATH CLASS 等等,都有若干考题。

  8)考试题目几乎完全不体现实际应用。如果我有一个JAVA 编译器在身边,几乎所有的考题都可以轻松解决。我感觉SUN 希望考生能象JAVA 编译器一样熟悉JAVA 的特殊语法和特殊规则。这实际是完全没有必要的。

  9)我收集了很多模拟考题和BRAINDUMP ,有近千题。奇怪的是只有不到10 题出现在考试中,看来SUN 的考试题库实行的可能是动态题库,考背BRAINDUMP 是没有什么希望通过了。而且程序考题只有稍微改动一个符号,结果就完全不同,BRAINDUMP 很多题目靠不住。所以大家一定要在一定实际经验的基础上,好好看透一本辅导书,多作题,多分析题,多思考,才能比较容易通过考试。

  10)不管大家如何评价认证考试,反正考多几个证书不是坏事。起码加薪找工比较方便。 I have:SCJP, MCSE, MCSD, MCDBA, MCSE+Internet.haha...It is better than nothing.Don't trust the people who sell SCJP questions online!It is very useless and a lot of errors!Work on your own experience!

posted @ 2008-01-20 01:32 矿矿 阅读(332) | 评论 (1)编辑 收藏
1.OOP中唯一关系的是对象的接口是什么,就像计算机的销售商她不管电源内部结构是怎样的,他只关系能否给你提供电就行了,也就是只要知道can or not而不是how and why.所有的程序是由一定的属性和行为对象组成的,不同的对象的访问通过函数调用来完成,对象间所有的交流都是通过方法调用,通过对封装对象数据,很大限度上提高复用率。

2.OOP中最重要的思想是类,类是模板是蓝图,从类中构造一个对象,即创建了这个类的一个实例(instance)。

3.封装:就是把数据和行为结合起在一个包中)并对对象使用者隐藏数据的实现过程,一个对象中的数据叫他的实例字段(instance field)。

4.通过扩展一个类来获得一个新类叫继承(inheritance),而所有的类都是由Object根超类扩展而得,根超类下文会做介绍。

5.对象的3个主要特性

behavior---说明这个对象能做什么

state---当对象施加方法时对象的反映

dentity---与其他相似行为对象的区分标志

每个对象有唯一的indentity 而这3者之间相互影响。

6.类之间的关系

use-a:依赖关系

has-a:聚合关系

is-a:继承关系--例:A类继承了B类,此时A类不仅有了B类的方法,还有其自己的方法.(个性存在于共性中)。

7.构造对象使用构造器:构造器的提出,构造器是一种特殊的方法,构造对象并对其初始化。

例:Data类的构造器叫Data

new Data()---构造一个新对象,且初始化当前时间。

Data happyday=new Data()---把一个对象赋值给一个变量happyday,从而使该对象能够多次使用,此处要声明的使变量与对象变量二者是不同的.new返回的值是一个引用。

构造器特点:构造器可以有0个,一个或多个参数

构造器和类有相同的名字

一个类可以有多个构造器

构造器没有返回值

构造器总是和new运算符一起使用

8.重载:当多个方法具有相同的名字而含有不同的参数时,便发生重载.编译器必须挑选出调用哪个方法。

9.包(package)Java允许把一个或多个类收集在一起成为一组,称作包,以便于组织任务,标准Java库分为许多包.java.lang java.util java,net等,包是分层次的所有的java包都在java和javax包层次内。

10.继承思想:允许在已经存在的类的基础上构建新的类,当你继承一个已经存在的类时,那么你就复用了这个类的方法和字段,同时你可以在新类中添加新的方法和字段。

11.扩展类:扩展类充分体现了is-a的继承关系. 形式为:class (子类) extends (基类)。

12.多态:在java中,对象变量是多态的.而java中不支持多重继承。

13.动态绑定:调用对象方法的机制。

(1)编译器检查对象声明的类型和方法名。

(2)编译器检查方法调用的参数类型。

(3)静态绑定:若方法类型为priavte static final 编译器会准确知道该调用哪个方法。

(4)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用x所指向的对象的实际类型相匹配的方法版本。

(5)动态绑定:是很重要的特性,它能使程序变得可扩展而不需要重编译已存代码。

14.final类:为防止他人从你的类上派生新类,此类是不可扩展的。

15.动态调用比静态调用花费的时间要长。

16.抽象类:规定一个或多个抽象方法的类本身必须定义为abstract。

例:public abstract string getDescripition

17.Java中的每一个类都是从Object类扩展而来的。

18.object类中的equal和toString方法。
equal用于测试一个对象是否同另一个对象相等。
toString返回一个代表该对象的字符串,几乎每一个类都会重载该方法,以便返回当前状态的正确表示.
(toString 方法是一个很重要的方法)
19.通用编程:任何类类型的所有值都可以同object类性的变量来代替。
20.数组列表:ArrayList动态数组列表,是一个类库,定义在java.uitl包中,可自动调节数组的大小。
21.class类 object类中的getclass方法返回ckass类型的一个实例,程序启动时包含在main方法的类会被加载,虚拟机要加载他需要的所有类,每一个加载的类都要加载它需要的类。
22.class类为编写可动态操纵java代码的程序提供了强大的功能反射,这项功能为JavaBeans特别有用,使用反射Java能支持VB程序员习惯使用的工具。
能够分析类能力的程序叫反射器,Java中提供此功能的包叫Java.lang.reflect反射机制十分强大.
1.在运行时分析类的能力。
2.在运行时探察类的对象。
3.实现通用数组操纵代码。
4.提供方法对象。

而此机制主要针对是工具者而不是应用及程序。
反射机制中的最重要的部分是允许你检查类的结构.用到的API有:
java.lang.reflect.Field 返回字段
java.reflect.Method 返回方法.
java.lang.reflect.Constructor 返回参数

方法指针:java没有方法指针,把一个方法的地址传给另一个方法,可以在后面调用它,而接口是更好的解决方案。
23.接口(Interface)说明类该做什么而不指定如何去做,一个类可以实现一个或多个interface。
24.接口不是一个类,而是对符合接口要求的类的一套规范。
若实现一个接口需要2个步骤:
1.声明类需要实现的指定接口。
2.提供接口中的所有方法的定义。
声明一个类实现一个接口需要使用implements 关键字

class actionB implements Comparable 其actionb需要提供CompareTo方法,接口不是类,不能用new实例化一个接口。
25.一个类只有一个超类,但一个类能实现多个接口。Java中的一个重要接口:Cloneable

26.接口和回调.编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法。
例:ActionListener 接口监听
类似的API有:java.swing.JOptionPane
java.swing.Timer
java.awt.Tookit
27.对象clone:clone方法是object一个保护方法,这意味着你的代码不能简单的调用它。

28.内部类:一个内部类的定义是定义在另一个内部的类。

原因是:

1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据。
2.对于同一个包中的其他类来说,内部类能够隐藏起来。
3.匿名内部类可以很方便的定义回调。
4.使用内部类可以非常方便的编写事件驱动程序。
29.代理类(proxy):
1.指定接口要求所有代码
2.object类定义的所有的方法(toString equals)
30.数据类型:Java是强调类型的语言,每个变量都必须先申明它都类型,java中总共有8个基本类型.4种是整型,2种是浮点型,一种是字符型,被用于Unicode编码中的字符,布尔型。
 
posted @ 2008-01-08 04:02 矿矿 阅读(242) | 评论 (1)编辑 收藏
由基本概念开始全面认识Java

Java应该怎么学?Java能做什么?什么是Applet?什么是Servlet、Jsp、EJB?还有Webspere、Weblogic又是做什么的等等。之所以学员会有这些疑问,是因为大家普遍对Java相关概念听说的太多而了解的又相对少的缘故。

学通Java语言需要一个过程,所有Java相关的概念都会在学习的过程中逐渐变得清昕。这个过程的开始就是要先学会标准的Java技术(J2SE),然后是学Java的简单Web运用,然后分布式运用,再以后对Java的移动技术运用就很容易理解了。

以下是Java标准技术的一些要点:

一、Java的跨平台性,即一次编译到处运行

简单地说Java的跨平台性就是指,编译后的Java程序可直接在不同的平台上运行而不用重新编译,这一特性使得Java随着Web应用的普及而迅速普及起来。而Java的跨平台性是如何实现的呢?这就要理解Java虚拟机和字节码的概念。

实际上,编译后的Java代码并不是传统的二进制代码(如Windows下的.exe文件),而是Java字节码,这种字节码文件是不能直接在操作系统上执行的。要想在一个操作系统上运行一个Java程序必须有一个中间环节来负责将Java字节码解释成二进制码,这个中间环节就是Java虚拟机(简称JVM)。由于目前大多数操作系统已经实现了JVM,所以Java轻松实现跨平台性。

二、面象对象技术

Java全面支持面象对象技术,这体现在Class(类)是Java程序构成的基本单元,一个Java程序通常由许多Class组成,而且这些Class还会有一定的继承关系,Java支持Class的单继承,从而使类之间的继承关系更明确。继承的结果产生类的多态性,类的多态本质上讲就是可以用父类的引用访问继承类的实现(子类对象),类的这种多态性最终形成了组件对象模型的基础,即通过接口(父类)访问实现(子类)。

三、Java中的I/O操作

Java中以字节流(InputStream和OutputStream)、节符流(Reader和Writer)来分别读写二进制数据和字符数据,使用非常简单有效。Java类库中的File类不仅提供文件操作而且还包含文件夹操作,如下面这几行代码可以列出C盘根目录下的所有文件:

File f=new File("c://");

String [] m_dir= f.list();

for(int i=0;iSystem.out.println(m_dir[i]);

四、Java中的图形及事件处理

可以用awt包或swing包的Java类来进行大部分的Java图形界面设计,下面的几行代码将产生一个200*200像素的窗体:

Frame f=new Frame("Welcome");f.setSize(200,200);f.setVisible(true);


默认情况下,Frame窗体的关闭按钮不起作用,这也是Java初学者迷惑的地方。为了使用户按下关闭按钮时能关闭Frame窗体,需要让这个窗体响应一个WindowEvent事件,具体的做法就是给这个窗体添加一个事件监听器对象,这个事件监听器就是WindowListener接口的实现。在上面的代码中插入如下代码就可以关闭窗体:

f.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}}


这里用到一个无名内部类,无名内部类是Java中内部类的一种灵活运用方式。

五、Java中线程及同步控制

线程概念的引入是为了实现并行处理,从而提高程序的效率。Java中的线程实现非常简单,可以用两种方式来创建线程,一种是实现Runnable接口,另一种是继承Thread类重写run()方法。两种方式唯一的不同就是前者保留了继承一个类的可能(因为Java只支持类的单继承,但接口没有此限制)。

永远都用start()方法来启动一个线程,线程类中的run()可以被直接调用,但决不是启动一个线程,二者有着本质的区别。

用同步控制关键字synchronized来保护线程敏感数据,synchronized块中的内容可以保证同一时刻只能被一个线程访问,所以其中的数据是线程安全的。

用Object类中的wait()和notify()方法可以实现线程间交互,但要记住wait()和notify()方法只有发生在同一个对象上才能真正实现线程间交互。被某一对象wait()方法阻塞的线程需要另外一个调用了同一对象notify()的线程干预才能恢复运行。notify()方法一次唤醒一个被wait()方法阻塞的线程,notifyAll()方法可以一次唤醒所有被wait()方法阻塞的线程。

六、Java本地方法(native方法)的实现

Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。

可以将native方法比作Java程序同C程序的接口,其实现步骤:

1、Java中声明native()方法,然后编译;
2、用javah产生一个.h文件;
3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
4、将第三步的.cpp文件编译成动态链接库文件;
5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。

上述所提及的一些Java技术具有一定的普遍性,它们基本上是在Java各个方面的运用中都需要掌握的术。实际上Java的运用非常广泛,而且每个方面都需要遵循不同的规范。以下是对Java应用的简要介绍。
(一)理解Java SDK的三个版本:
Java SDK Micro Edition (J2ME)
用于开发掌上电脑、手机等移动通信设备上使用的应用程序。并不是所有的移动设备都支持Java,只有具备J2ME运行环境(JVM+J2ME API)的设备才能运行Java程序。J2ME的集成开发工具(通常都有带有一些访真器)有 Sun 的J2ME Wireless Toolkit 、IBM的Visul Age Micro Edition 等。
Java SDK Standard Edition(J2SE)
主要用于开发一般台式机应用程序。我们平时所说的JDK就指J2SE,而我们学Java就是从学习J2SE开始的。
Java SDK Enterprise Edition (J2EE)
用于开发分布式的企业级大型应用程序。其中的核心是Entetprise Java Beans(EJB,分布式Java组件)的开发。
(二)Java小程序 (Applet)
Java小程序是一个继承了Applet类并重写了init()、paint()、stop()等方法的的Java类,它被布署在Web服务器(如IIS)上,当客户端请求Web页时,浏览器从Web服务器上将其下载到本地客户端,然后,浏览器创建该Applet类的实例并调用其init()方法,从安全角度考虑,Applet没有访问本地文件的权限。由于Applet是被浏览器执行的,所以Applet不需要一个main()方法。实际上,除了Java Application之外,所有其它Java应用都不需要一个main()方法。
(三)服务器端Java小程序 (Servlet)
Servlet也是一个Java类,和Applet形成对比,Servlet是运行于服务器端的Java小程序,而且Servlet需要一个单独的Web服务器(如Tomcat)做容器。除此之外,Servlet中用到的一些类(如HttpServlet)并不包含在J2SE API中,所以需要将Servlet.jar(在Tomcat的common\lib文件夹下)加到环境变量中去。下面是一个简单的Servlet例子:

public class Myservlet extends HttpServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response){try{response.setContentType("text/html");PrintWriter out=response.getWriter();out.println("");out.println("");out.println("Hello world");out.println("");out.println("");}catch(IOException e){}}}


将这个Class文件编译后放至Tomcat\webapps\examples\WEB-INF\classes下,然后在浏览器地址栏里输入http://127.0.0.1:8080/examples/servlet/Myservlet即可看到 Hello world出现在浏览器中。
(四)Java Server Page (JSP)
同Servlet相似的是,JSP运行于Web服务器端,并且也需要Tomcat之类的容器。不同的是,由于JSP是将Java代码嵌在html标记里(同ASP一样用),JSP的界面设计同后台开发人员的工作可以有效分离。可以想像让开发人员用Servlet写一个花捎的Web页面有多困难,所以JSP+Servlet混合Web应用是比较理想的选择。
看起来JSP同ASP的实现机制大同小异,其实也存在着本质的区别。所有的ASP页面都是解释运行的,而JSP页在第一次被请求时会被编译,再以后的客户请求都是直接运行服务器上的.class文件(在Tomcat的Work文件夹下),所以JSP要比ASP速度上快许多。
(五)Java Beans
Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。
(六)Enterprise Java Beans (EJB)
Java Bean实际上相当于微软COM模型中的本地进程内COM组件,它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM,即分布式组件。它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理,EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。
这种模型很像COM+管理器,其实EJB容器正是起到COM+管理器的作用,只是EJB组件相对COM组件来说更易用、更安全。
总的说来,Java作为面象对象技术的一个代表,在当今商业应用中更容易开发出高效的、多层的分布式应用程序,而且,由于Java技术有很强的健壮性和易用性,加上同UML应用的结合,开发一个商业应用软件的周期会大大缩短,所以Java会有不错的前景。

 

------------------
posted @ 2008-01-08 04:01 矿矿 阅读(204) | 评论 (0)编辑 收藏
仅列出标题
共4页: 上一页 1 2 3 4