176142998

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  116 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

#

分析:EOFException表示输入过程中意外地到达文件尾或流尾的信号,导致从session中获取数据失败。异常是tomcat本身的问题,由于tomcat上次非正常关闭时有一些活动session被持久化(表现为一些临时文件),在重启时,tomcat尝试去恢复这些session的持久化数据但又读取失败造成的。此异常不影响系统的使用。
解决办法:将tomcat5.5\work\Catalina\localhost\peam\SESSIONS.ser删除。如果正常关闭服务端,该文件是自动删除的。
posted @ 2008-07-09 22:59 飞飞 阅读(202) | 评论 (0)编辑 收藏

当增加Hibernate Capabilites后增加Struts Capabilites,运行项目时,控制台报错信息:
/----------------------------------------------org.apache.commons.collections.SequencedHashMap
......
/----------------------------------------------
解决方案:
下载commons-beanutils-1.7.0.zip;
将其中commons-beanutils.jar文件替换Tomcat6.0下WEB-INF/lib/commons-beanutils-1.7;
解决问题.

这个错误可能是myeclipse6.0版本的一个问题,就是在整合web层和struts层出现的问题

解决方法如下:

1)下载6.0.1版本的myeclipse开发

2)下载最新的org.apache.commons.collections,讲原来的去掉就行了,然后讲最新的加进去

posted @ 2008-07-09 20:53 飞飞 阅读(776) | 评论 (0)编辑 收藏

<html:messages>
Action 中 :
        ActionMessages message = new ActionMessages();
        message.add(" 消息句柄 ",new ActionMessage(" 资源文件中 Key 值 ",String 类型描述信息 ));
        this.addMessages(request,message);
        return ActionForward;
JSP 页面中 :
        <html:messages id=" 指定使用消息的标识 " property=" 消息句柄 " message="true|false">
           <bean:write name=" 以上所指 ID 标识 "/>
        </html:messages>

例如:

Action方法中:
saveMessage(request,"页面要显示的消息");

Action的调用的方法,可以写真Action实现类的父类 BaseDispatchAction :

public ActionMessages saveMessage(HttpServletRequest request, String key) {
      ActionMessages messages = new ActionMessages();
      return saveMessage(messages, request, key);
}

protected ActionMessages saveMessage(ActionMessages messages,
       HttpServletRequest request, String key) {

      messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(key));
      saveMessages(request, messages);
      return messages;
}

页面:

<html:messages id="msg" message="true"><bean:write name="msg"/></html:messages>

 

<html:errors>
Action 中 :
        ActionMessages message = new ActionMessages();
        message.add(" 消息句柄 ",new ActionMessage(" 资源文件中 Key 值 ",String 类型描述信息 ));
        this.saveErrors(request,message);
        return ActionForward;
JSP 页面中 :
        <html:errors property=" 消息句柄 "/>

如果Action中这样设定(false),页面的提示信息将不从资源文件里读取:
        ActionMessages message = new ActionMessages();
        message.add("消息句柄",new ActionMessage("String类型描述信息));",false));
        this.saveErrors(request,message);
        return ActionForward;
JSP页面:
        <html:errors/>或<html:errors property="消息句柄"/>

posted @ 2008-07-09 17:21 飞飞 阅读(330) | 评论 (0)编辑 收藏

源码下载:http://ishare.iask.sina.com.cn/cgi-bin/fileid.cgi?fileid=2857703

1. 准备

工具:MyEclipse 6.0.1 GAmysql-connector-java-5.0.4-bin.jarMySql GUI Tools 5.0(便于管理MySql数据库,不是必须)

环境:Tomcat 5.5MySql 5.0

1.1. 新建工程

操作:[Menu] File/New/Web Project

工程名:login

2. Struts 部分


2.1. 添加 Struts 功能支持

操作:[Menu] MyEclipse/Project Capabilities/Add Struts Capabilities

 

2.2. 创建 ActionForm 类

操作:[Ctrl+N] MyEclipse/Web-Struts/Struts 1.2 Form

类名:LoginForm

在 “Form Properties” 选项卡为 loginForm 新增两个属性:username、password;

在 “JSP” 选项卡钩选 “Create JSP form” 选项,将新建路径改为 “/login.jsp”(login.jsp文件将被自动创建)。

2.3. 创建 Action 类

操作:[Ctrl+N] MyEclipse/Web-Struts/Struts 1.2 Action

类名:LoginAction

在 “Form” 选项卡的 “Name” 项选择 “loginForm”,”Input Source” 项输入 “/login.jsp”。

2.4. 创建 index.jsp 文件

如果没有,创建 index.jsp 文件,并添加一个指向 login.jsp 的链接:<a href=”login.jsp”>Login</a>

2.5. 创建Forword类

操作:[Ctrl+N] MyEclipse/Web-Struts/Struts 1.2 Forword

类名:indexForword

“Name” 项输入 “indexForword” ,”Path” 项输入 “/index.jsp” 。

2.6. 修改 LoginAction.java 文件

修改 LoginAction 类的 execute 方法:

public class LoginAction extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;
String username=loginForm.getUsername();
String password=loginForm.getPassword();
if(username.equals(”test”)||password.equals(”test”)){
return mapping.findForward(”indexForword”);
}else{
return mapping.getInputForward();
}
}
}

2.7. 修改 login.jsp 文件

修改 <html:form> 标签:<html:form action=”/login”>

2.8. 测试

操作:[Menu] Run/Run,选择 MyEclipse Server Application 方式运行

要正常执行Run操作,需先安装 Tomcat5.5 。

点击 index.jsp 页面的 “Login” 链接,跳转到 login.jsp 页面。在 login.jsp 页面输入 “test/test”,应该会登录成功,然后跳转到 index.jsp 页面;输入 “test/123″ ,应该保持在 login.jsp 页面。

如果测试成功,证明 Structs 运行正常。

3. Spring 部分


3.1. 添加 Spring 功能支持

操作:[Menu] MyEclipse/Project Capabilities/Add Spring Capabilities

Spring 版本( Spring version )选择 “Spring 1″;

开发包(libraries)选择 “Spring 1.2 AOP Libraries、Spring 1.2 Core Libraries、Spring 1.2 Persistence Core Libraries、Spring 1.2 Persistence JDBC Libraries” 四项;

JAR Library Installation 选择 “copy checked…” ,”Library Folder” 项选择 “/WebRoot/WEB-INF/lib”(这样的话所需的类库都将拷贝到项目目录,方便以后的布署)。

点击 “下一步(Next)” 创建配置文件,修改文件路径(Folder)到 “WebRoot/WEB-INF” 目录(以便和Struts配置文件一起管理),文件名称为默认的”applicationContext.xml”。

点击 “完成(Finish)” 。

3.2. 配置 struts-config.xml 文件

添加 Spring 插件(在 <message-resources> 标签后面添加):

<plug-in className=”org.springframework.web.struts.ContextLoaderPlugIn”>
<set-property property=”contextConfigLocation” value=”/WEB-INF/applicationContext.xml” />
</plug-in>

修改 LoginAction 的配置(只需修改 type 属性):

<action-mappings >
<action
attribute=”loginForm”
input=”/login.jsp”
name=”loginForm”
path=”/login”
scope=”request”
type=”org.springframework.web.struts.DelegatingActionProxy” />

</action-mappings>

绿色字体部份为被修改过的内容,这里将使用 spring 的代理器 DelegatingActionProxy 来对 Action 进行控制。

3.3. 修改 Spring 配置文件 applicationContext.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”>

<beans>
<bean name=”/login” class=”com.login.struts.action.LoginAction” singleton=”false”></bean>
</beans>

绿色字体是关于接受和处理 Action 控制权的配置内容,”com.login.struts.action.LoginAction” 即为原 struts 里的配置。

3.4. 测试

同上一次测试。测试成功证明 Spring 运行正常。

4. Hibernate 部分

下面开始 Hibernate 部分,将原例修改为使用数据库进行用户名/密码验证。

4.1. 创建 mysql 数据库和表

添加表的代码如下:

CREATE TABLE user_table(
ID int NOT NULL auto_increment,
USERNAME varchar(45) NOT NULL default ”,
PASSWORD varchar(45) NOT NULL default ”,
PRIMARY KEY (ID)
)

再添加一条记录:

insert into user_table (USERNAME,PASSWORD) values (’test’,'test’)

4.2. 创建 MyEclipse 数据库驱动(DB Driver)

操作:[Menu] MyEclipse/Prefrences/MyEclipse/Database Explorer/Database Driver/DB Brower

在 DB Brower 的菜单中选择 “New” ,”Driver Name” 项输入 “login-conn” ,”Connection URL” 项输入 “jdbc:mysql://localhost:3306/test” ,然后输入正确的用户名(User Name)和密码(Password)按实际情况输入;

在 “Driver JARs” 项添加 “mysql-connector-java-5.0.4-bin.jar” (可从网上下载),在 “Driver classname” 里选择 “com.mysql.jdbc.Driver” ,其它自选。

点击 “完成(Finish)”。

4.3. 添加 Hibernate 功能支持

操作:[Menu] MyEclipse/Project Capabilities/Add Hibernate Capabilities

Hibernate 版本(Hibernate Specification)选择 “Hibernate 3.1″ ,开发包(libraries)选择 Hibernate 3.1 Core Libraries 一项;

JAR Library Installation 选择 “copy checked…” ,”Library Folder” 选择 “/WebRoot/WEB-INF/lib” 。

点击 “下一步(Next)” 设置配置文件,选择 “Spring configuration file (applicationContext.xml)” 。

“下一步(Next)” 设置 Spring-Hibernate,选择 “Existing Spring configuration file” ,”SessionFactory ID” 项输入 “sessionFactory” 。

 

“下一步(Next)” 创建数据源对象,在 Bean Id 中输入 dataSource,”DataSource” 项选择 “Use JDBC Dirver” ,DB Driver 项选择 “login-conn” ,其余项会自动填充;

记得选中 “Copy DB driver jar(s) to project and add to buidpath” 项,以便将数据连接的库文件复制到项目,方便以后的布署。

“下一步(Next)” 创建 SessionFactory 类,”Java package” 项设置为 “com.login.Hibernate” (没有则点击”New”按钮添加),”Class name” 项修改为”SessionFactory” ,Java Compliance Level选择和创建项目时选择的Java版本。(本例中并没有用到SessionFactory类,留作今后扩展)

点击 “完成(Finish)”。

4.4. 创建对象关系映射(ORM)的相关文件

操作:[Menu] Window/Open Perspective/MyEclipse Database Explorer

选中 user_table 表,点击右键,在出现的菜单中选择 “Hibernate Reverse Engnieering” 。

在弹出的窗口中保持 “Java package” 项为 “com.login” ;

选中 “Hibernate mapping file (*.hbm.xml) for each databases table” ,并保持 “Update hibernate…” 项选中;

选中 “Java Data Object” 项,并保持 “Create abstract class” 选中;

“Base persistent class” 项留空;

取消 “Java Data Access Object…” 项和 “Use custom templates” 项。

点击 “下一步(Next)” ,再点击 “下一步(Next)” ,在 “Configure reverse engineering details” 页选中 “user_table” 表,在右边出现的 “Class Name” 项中输入 “com.login.User”,其它不变。

点击 “完成(Finish)”。

完成此操作,会在 “com.login” 包下创建三个文件:AbstractUser.java、User.java、User.hbm.xml。

4.5. 创建 UserDAO.java 接口和 UserDAOImpl.java 类

UserDAO 和 UserDAOImpl 通过 Hibernate 访问数据库。

UseDAO.java 内容如下:

package com.login;

public interface UserDAO {
public abstract boolean isValidUser(String username, String password);
}

UserDAOImpl.java 内容如下:

package com.login;

import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {
private static String hql = “from User u where u.username=? “;

public boolean isValidUser(String username, String password) {
// 验证用户
List userList = this.getHibernateTemplate().find(hql, username);
if (userList.size() > 0) {
return true;
}
return false;
}
}

4.6. 修改 LoginAction.java 文件

使用 UseDAO 对象来验证:

package com.login.struts.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.login.struts.form.LoginForm;
import com.login.UserDAO;

public class LoginAction extends Action {
private UserDAO userDAO;

public UserDAO getUserDAO() {
return userDAO;
}

public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}

public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {

LoginForm loginForm = (LoginForm) form;
String username=loginForm.getUsername();
String password=loginForm.getPassword();

if( userDAO.isValidUser( username, password ) ){
return mapping.findForward( “indexForword” );
}else{
return mapping.getInputForward();
}
}
}

绿色字体为修改部分。

4.7. Spring 的最终配制文件 applicationContext.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”>

<beans>

<bean id=”dataSource”
class=”org.apache.commons.dbcp.BasicDataSource”>
<property name=”driverClassName” value=”com.mysql.jdbc.Driver”></property>
<property name=”url” value=”jdbc:mysql://localhost:3306/test”></property>
<property name=”username” value=”root”></property>
<property name=”password” value=”root”></property>
</bean>

<!– 配置sessionFactory, 注意这里引入的包的不同 –>
<bean id=”sessionFactory” class=”org.springframework.orm.hibernate3.LocalSessionFactoryBean”>
<property name=”dataSource”>
<ref local=”dataSource” />
</property>
<property name=”mappingResources”>
<list>
<value>com/login/User.hbm.xml</value>
</list>
</property>
<property name=”hibernateProperties”>
<props>
<prop key=”hibernate.dialect”>org.hibernate.dialect.MySQLDialect</prop>
<prop key=”hibernate.show_sql”>true</prop>
</props>
</property>
</bean>

<bean id=”transactionManager” class=”org.springframework.orm.hibernate3.HibernateTransactionManager”>
<property name=”sessionFactory”>
<ref local=”sessionFactory” />
</property>
</bean>

<bean id=”userDAO” class=”com.login.UserDAOImpl”>
<property name=”sessionFactory”>
<ref local=”sessionFactory” />
</property>
</bean>

<bean id=”userDAOProxy” class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”>
<property name=”transactionManager”>
<ref bean=”transactionManager” />
</property>
<property name=”target”>
<ref local=”userDAO” />
</property>
<property name=”transactionAttributes”>
<props>
<prop key=”insert*”>PROPAGATION_REQUIRED</prop>
<prop key=”get*”>PROPAGATION_REQUIRED,readOnly</prop>
<prop key=”is*”>PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>

<bean name=”/login” class=”com.login.struts.action.LoginAction” singleton=”false”>
<property name=”userDAO”>
<ref bean=”userDAOProxy” />
</property>
</bean>

</beans>

4.8. 测试

同第一次测试。 

posted @ 2008-07-09 14:13 飞飞 阅读(3464) | 评论 (2)编辑 收藏

在spring2.0中,bean没有“singleton”这个属性,而是在“scope”中对它进行设定。“scope”可以设定为“singleton”和“prototype”默认情况下是“singleton”即和原先的“singleton=true”性质一样,如果要实现单例模式则将“scope”设定为“prototype”,即和原先版本的“singleton=false”一样。参考文档链接地址:http://www.springframework.org/schema/beans/spring-beans-2.0.xsd



根据用户名和密码进行校验的方法
 public boolean verify(String userName, String userPwd) {
  final String HQL="FROM UserTable u where u.userName=? and u.userPwd=?";
  String[] hqlParameter=new String[2];
  hqlParameter[0]=userName;
  hqlParameter[1]=userPwd;
  List list=this.getHibernateTemplate().find(HQL,hqlParameter);
  if(list.size()>0){
   return true;
  }
  
  return false;
 }
posted @ 2008-07-09 13:03 飞飞 阅读(2957) | 评论 (0)编辑 收藏

mysql-administrator的安装与使用(图文)
  
准备工作
在D盘建立一个mysql-software的目录,把刚才下载的 mysql-administrator-1.0.19-win-noinstall.zip 复制到这个子目录中,解压,得到一个 MySQL Administrator 1.0 的目录。
同样如此操作 mysql-query-browser-1.1.5-win-noinstall.zip,得到一个 MySQL Query Browser 1.1 的目录。
  
启动服务
·
双击D:mysql-softwareMySQL Administrator 1.0 目录下的 MySQLSystemTrayMonitor.exe,这时会在任务栏右侧出现一个图标。点击“Start Instance”,运行MySQL。

·
然后双击 D:mysql-softwareMySQL Administrator 1.0 目录中的 MySQLAdministrator.exe,或者直接点击上面右键菜单中的“MySQL Administrator ”:

·
创建一个连接名,可以随便填,这里是“mxj”,用户名:root,密码空着。这是因为mysql默认有一个没有密码的root帐号。点击“OK”,出现管理窗口:

这没什么好说的,英文也很简单。只谈谈上面勾选的两项。
更改密码

好了,我的root帐号的密码设置为:javamxj    最后,点击“Apply Change”。
● 初始的

数据库



上图可以看到,初始有两个

数据库

,mysql库中含有各种配置信息,不要在这个库中进行表操作。
test库初始是空的。另外,建立表时,不要和mysql库中的表名取名相同,以免冲突。
数据创建与查询(兼谈谈字符编码)
·
现在来到查询浏览器,还是右击右下角“MySQL System Tray Monitor”图标,从中选择“MySQL Query Browser”,因为已经更改过root的密码,所以要填入新密码。

·
进入主界面,右击test

数据库

,创建一个新表。

·
如下简单创建一个表

·
切换到“Table Options”:

如果了解

数据库

的话,这些应该是很熟悉的,不多说了。注意字符设置默认是“Latin1”(保存改变,再次切换到这一栏,就能看到了)。
·
填入一些测试数据:

·
关闭“MySQL Query Browser”,再重新打开它,切换到testtable表,看到了没有?刚才输入的中文变成了“??????”,为什么呢? 再次切换到“Table Options”:

知道为什么了吧,原来默认字符是“latin1”,因为MySQL是瑞典一家公司的产品。中国人看来要努力了!
● 解决方法:
·
停止MySql服务,关闭所有与MySql相关的程序,打开Windows的系统安装目录下的 my.ini 文件,如下修改:
E:WINDOWSmy.ini

[WinMySQLAdmin]
  
Server

=D:/mysql/bin/mysqld-nt.exe
  
[mysqld]
  
basedir
=D:/mysql
  
datadir
=D:/mysql-data/data
  
default-character-set
=gbk
  
[client]
  
default-character-set
=gbk
添加的两条语句的含义是在客户端和服务端都使用GBK字符集进行编码。
保存后,重新激活 MySql 服务,打开“MySQL Query Browser”,再次创建一个表,输入中文,一切OK!

备份时会出错,以下日志:
----------------------------------------
2008-07-03 14:18 - Backup started.
Preparing backup for for profile mysql.
Connections loaded from file C:\Documents and Settings\Administrator\Application Data\MySQL\mysqlx_user_connections.xml.
Connection NewConnection selected.
Cannot connect to MySQL Server. Access denied for user 'root'@'localhost' (using password: NO) (Error Number 1045)

在mysqlx_user_connections.xml.文件中加个密码进去
<?xml version="1.0"?>
<user_connections>
  <last_connection>0</last_connection>
  <password_storage_type>2</password_storage_type>
  <user_connection>
    <connection_name>NewConnection</connection_name>
    <username>root</username>
    <hostname>127.0.0.1</hostname>
    <port>3306</port>
    <schema>test</schema>
    <advanced_options/>
    <storage_path></storage_path>
    <notes></notes>
    <connection_type>0</connection_type>
    <storage_type>1</storage_type>
    <password_storage_type>2</password_storage_type>
    <password>root</password>
  </user_connection>
</user_connections>

但是在备份的时候还是会出现错误

根据提示选择open options 选择 password storage
OK
电脑每次自己启动MySQLSystemTrayMonitor 就会在定制的时间备份数据库

Your account information:
Name: fei zhao
Email: feifeixia2003@yahoo.com.cn
Password: nehaifrowa
You can log in to your new account and edit your profile options at:
  http://www.mysql.com/login.php
posted @ 2008-07-03 13:54 飞飞 阅读(10045) | 评论 (1)编辑 收藏

http://www.net.cn/static/customercare/support/demo/outlook/outlook.htm
fei.zhao@centralsoft.com.cn
211.155.226.126
posted @ 2008-07-02 09:22 飞飞 阅读(968) | 评论 (0)编辑 收藏

有些事情现在已经很容易被忘记了,但是在开发原创的 Mac OS 的时候,业界到处出现新的图形用户接口(GUI),人们所做的工作差别相当小。Macintosh 的设计团队在很多事情上是正确的,这很大程度上是因为他们在自己正在干什么这个问题上付出了难以想像的思考。虽然我要为 Internet Developer(英特网开发者)书写一些脚本方面的集体思想,但我还是想去看一些过去的 Macintosh 人机界面指南,并且看看这些指导原则如何才能用到 Web 界面上,我认为这是很值当的。我很少去找可以拷贝的具体部件,而更多地寻找这个以友好闻名的界面后面隐藏的设计原则。

原则之一就是无模式。这个原则打动了我,因为它特别适合于 Web。正如 Mac 的设计者描述的那样,模式界面(在这种界面下,您能做什么取决于您当前处于什么模式下)会“把用户锁定在一个操作上,用户在该操作完成之前不允许进行其它任何操作”。使用单纯的老版本HTML时,从某种意义上看,所有界面都是模式的,进行任何修改都需要装载一个新的页面。举例来说,假定您在填充一个表单时需要一些帮助,则您必须转到包含帮助信息的新页面,然后再回到原来的页面,以完成表单的填写。

换句话说,您或者处于“帮助”模式,或者处于“表单填写”模式。这凸显了 Web 的两个主要的限制:无态(即当点击帮助连接时,您在表单中已经输入的信息将会丢失)和迟延(即您必须等待页面装载)。因此我决定写一点脚本来帮助处理这些问题。这些脚本通过动态 HTML (DHTML)技术在您点击连接时弹出一个带有帮助信息的方框。在我的演示中,就是使用它们来弹出与表单填写相关的上下文帮助信息。这些脚本也可以用在别的地方,比如弹出一篇论文的术语定义。上述的两种情况都以合理的方式给出了上下文相关的信息,即无模式的方式。同时,这个解决方案也避免了无态和迟延的问题。

实际上,我写的这些基本函数可以用在任何需要在页面上移动和改变对象可视性的地方。我做了一个快速下拉菜单的实例,就是为了演示同样这些代码的另外一种使用方式,您可能会用得到。

您可能会担心有人还在使用版本比较老的浏览器,对此,我们可以相当轻松地使这些脚本自然地回退到原来的状态,使那些使用老版本浏览器的用户可以简单地从一个单独的页面上获得信息。我将在下面的“如何使用脚本”的部分中解释如何实现这个目标。

脚本的目标

这个脚本将创建动态菜单和弹出式对象。它包括一些跨浏览器的基本函数,用于移动和改变DHTML对象的可视性。在 Netscape 4.x 中,一个 DHTML 对象是一个通过绝对位置定位的 DIV,而对 Safari,Internet Explorer 4 和 5,或者 Netscape 6 来说,则是任何 HTML 元素。这些函数可以被用在大量的 DHTML 应用中;这里还给出的两个实例,向您演示如何创建一个弹出式的提示(tip)和下拉式菜单。脚本中的主要函数如下:

  • changeObjectVisibility,用来翻转一个 DHTML 对象的可视性。
  • moveObject,用来在浏览器窗口中把一个 DHTML 对象移动到特定的位置上。
  • getStyleObject,这个函数通过获得一个风格对象的引用简化了跨浏览器的 DTHML,我们可以从这个对象中读取属性,或者进行属性设定,包括位置,可视性,颜色,尺寸,等等。

编码的挑战

遗憾的是,由于长期以来浏览器都是由各个厂商自行实现,所以书写跨浏览器和跨平台的 DHTML 通常是拜占庭式的条件分支。为任何一个浏览器书写这些脚本都是非常轻松的;为了使它们工作在 Netscape 4 及其升级版本,以及工作在 Internet Explorer 4 及其升级版本上,事情就要复杂一些了;而使它们可以回退到比较老版本的浏览器的状态,又增加了更多的复杂度。问题在于各个浏览器在如何寻找和操作 Web 页面上的对象方面都有很多独特之处,虽然我们对这种状态已经比较熟悉了。为了方便,我写了处理这些条件分支的代码。

这些函数中有一些功能不能工作在更老一些的浏览器上,比如 Netscape 3。然而,使这些功能自然地退化并补台困难。您只需进行如下操作:

  • 直接把这些脚本包含在页面上,而不是使用连接的 .js 文件。
  • 只在提供相关支持的浏览器上使用 JavaScript 进行弹出式的 DIV 的输出。实现这个控制的代码大致如下:
    if(document.getElementById || document.all
        || document.layers) {
        // write out div tag with document.write
        }

我发现的最大挑战是必须考虑浏览器处理事件的不同方式。事件发生时(比如 click 或者 mouseover 事件)光标的位置存储在一个事件对象中,而不同浏览器对事件对象的处理有轻微的不同。当事件发生时,Netscape 4 和6都产生一个新的事件对象,您可以把这个对象作为一个参数传递到函数中;而 Internet Explorer 则使用一个独立的全局 window.event 对象。对于这个问题,我在抛弃几个现在看来很草率的解决方案之后,发现把事件对象显式地传递给函数的做法可以适用于这两种浏览器:

<a href="#" onclick="showPopup('popupName',
event);">click</a>

请注意,在事件边上少了引号标识。那是因为它是一个对象,而不是文本。现在,在您的函数中就可以以如下方式使用传入的事件对象了:

function showPopup(nameOfPopup, eventObject) {
alert(eventObject.clientX);
}

一旦把对象传递给函数,您就可以通过读取 pageXpageY 属性(Netscape 4 和 6)或者 clientXclientY 属性(IE 4+)来获得光标的位置。然而请注意,clientXclientY 属性并没有考虑页面可能被滚动的情况,因为这两个坐标是相对于窗口的左上角的,而不是整个文档。为了解决这个问题,我们加上 IE 的 document.body.scrollLeft document.body.scrollTop 属性的值。如果您感兴趣的话,事件对象还有一连串有用的属性,包括一个事件触发对象的引用(在 IE 上是 srcElement,而在 Netscape 上则是 target)。

把事件对象作为参数进行传递的唯一麻烦是在不支持事件对象的老版本浏览器上不能工作。为了绕开这个问题,我们在 popup.js 文件中包含一个函数,该函数为那些不存在事件对象的浏览器创建一个假的对象,在装载文档时运行:

function createFakeEventObj() {
// create a fake event object for older browsers
//to avoid errors in function call when we
//need to pass the event object
if (!window.event) {
window.event = false;
}
}

这个函数把 window.event 设定为 false(假)。这样以后,我们就可以在使用之前进行检测,看看是否存在真正的事件对象。

在 Mac 版的 Internet Explorer 5 上有一个问题,即当弹出层出现在文本的上方时,只有部分内容可以被显示。但是当我移动 DIV 标识,使之成为文档体的第一个元素时,这个问题神秘地消失了。

还是在 Mac 版的 IE 5 上,由于某些原因,document.onclick 事件只有在页面上存在实际文本时才能被触发。为了绕过这个缺陷(以便使您可以通过点击窗口中的任意位置来关闭窗口),我在页面中增加了一个不包含任何内容的,通过绝对位置定位的 DIV,然后用 JavaScript 来改变这个 DIV 的尺寸,使之覆盖整个窗口。相关的代码大致如下:

function resizeBlankDiv() {
// resize blank placeholder div so IE 5
// on mac will get all clicks in window
if ((navigator.appVersion.indexOf('MSIE 5') != -1)
&& (navigator.platform.indexOf('Mac') != -1)
&& getStyleObject('blankDiv')) {
getStyleObject('blankDiv').width =
document.body.clientWidth - 20;
getStyleObject('blankDiv').height =
document.body.clientHeight - 20;
}
}

遗憾的是,如果浏览器的尺寸被改变了,则只有一种方法可以恢复尺寸,即重新装载整个文档(您可能认为,只要用 window.onresize 事件就可以了。然而由于这个事件在窗口的尺寸真正被改变之前就已经发生了,所以采用这种方法最终会产生不必要的滚动条)。为了恢复页面尺寸,我们又写了一个函数,在窗口尺寸被改变的任何时候,该函数可以从 Mac 平台上的 IE5 的缓存中重新装载页面。

在 Mac 版的 Internet Explorer 5 上,当您点击一个连接时,会出现一个绝对大的轮廓,这个轮廓会和将要弹出的内容相重叠。为了解决这个问题,我在连接上增加了一条风格规则:

.popupLink { outline: none }

Netscape 4 在 DIV 的命名上有一些怪异的问题。以数字开头的名称(比如“1div”),以及有些带有下划线的名称(比如“my_div”)不能转化为层,因此我通常都避免这两种情况,把我的 DIV 按类似于 myDiv 或者 div1 的形式来命名。

Netscape 4 还有一个严重的缺陷,即当窗口的尺寸被改变时,所有的风格规则都会丢失。我没有把修复这个缺陷的代码包含进来,因为已经有好几个这样的代码公布出来了,比如 Webmonke 上的这个.

最后,在 Netscape 4 中,如果您把 javascript: 放在 hrefs 中,会导致页面的重新装载,并把函数的返回值当成页面的唯一内容显示出来。因此我们不应该采取下面的方式:

<a href="javascript:myFunction();">clickme</a>

而必须采取象下面的做法:

<a href="#" onclick="myFunction();
return false;">clickme</a>

实际上,这也是确保您的脚本在不能运行这些函数的浏览器上自然退化的好方法。请注意“return false”这行代码,它使浏览器停止装载 href 参数指定的URL。这样,如果浏览器中 JavaScript 被关闭,或者浏览器不能处理 JavaScript,则您可以提供一个不同的页面;但是如果这里的函数可以运行,则连接不会被打开。

在这个演示中,我们讨论的更深一些:

<a href="#" onclick="return
!showPopup('nameFieldPopup', event);">
clickme</a>

我们不去深入到所有的细节,只是大概看看这行代码,它的意思是运行 showPopup 函数,然后返回该函数返回值的非。那样,如果 showPopup 返回 true(意思是它成功显示了弹出层),我们就把 false 返回给连接,这样连接就不会改变页面。另外一方面,如果 showPopup 返回 false(意思是它不能显示弹出层),则我们就继续执行脚本,跟着连接进入到一个独立的页面,该页面具有和弹出层相同的信息。这个逻辑看起来可能有点混淆,但是只要记住一条就可以了:如果您返回 false,连接就不起作用了。

使用脚本

如果要使用这些脚本来实现弹出机制,请按照如下这些步骤来进行:

  • 如果要进行层的弹出,则需要把层工具和实现弹出机制的脚本文件都包含进您的页面。这可以通过把下面两条语句包含到您的文档头部来实现:
     <script src="utility.js"></script>
        <script src="popup.js"></script>
  • 确保有可以被弹出的 DIV。这些 DIV 必须被绝对定位,并且在开始是应该被隐藏。例如:
    <DIV onclick="event.cancelBubble = true;"
        class=popup id=nameOfPopup>
        Popup text goes here.<br>
        <a href="#" onclick="hideCurrentPopup();
        return false;">
        You can include a link like this to
        close the DIV if you like
        </a>
        </DIV>
    确保在DIV中包含onclick="event.cancelBubble = true;"这行代码。它告诉JavaScript在您点击DIV时不要把点击事件传递给页面中的其它对象。如果省略这行代码,则弹出层在被点击时就会关闭(对于大多数浏览器来说),因为我们已经设定了一个关闭弹出层的事件处理函数。把这行代码包含到页面中的基本目的是告诉浏览器“当人们点击除了弹出层自身(或者打开弹出层的原始连接)之外的任何地方时,关闭弹出层”。
  • 如果要改变弹出层的外观,请编辑风格表单中的.popup的风格规则。
  • 在每一个应该触发弹出层的地方调用showPopup函数,把nameOfPopup改为您希望显示的弹出层名称(但是把它放在单引号中):
    <a href="http://url.for.older.browsers"
        onclick="return !showPopup
        ('nameOfPopup', event);">
        clickme</a>
    如果您希望当鼠标在连接上滚动时出发弹出层,则只要修改触发事件就可以了:
    <a href="http://url.for.older.browsers"
        onmouseover="showPopup('nameOfPopup', event);"
        onmouseout="hideCurrentPopup();">clickme
        </a>
  • (可选)修改popup.js文件中的两个变量,这两个变量用来控制弹出层出现的位置,该位置是相对于当前光标位置的:
    var xOffset = 30;
        var yOffset = -5;

下面对相关的函数逐一进行说明:

  • changeObjectVisibility(objectId, newVisibility):调用这个函数时,objectId 应该是您希望显示或者隐藏的对象名称。函数希望这个参数是文本类型的,因此您需要把它包含在引号中。newVisibility 参数的值或者是 visible(可视)或者是 hidden(隐藏)。再次说明一下,这个值是一个字符串类型的,因此需要把它包含在引号中。下面这个实例把一个名为 myBigLayer: 的对象隐藏起来:
    changeObjectVisibility('myBigLayer', 'hidden')
  • moveObject(objectId, newXCoordinate, newYCoordinate):同样的,objectId 应该是您希望移动的对象名称。它是一个文本类型的参数,因此应该放在引号里面。newXCoordinatenewYCoordinate a 是数字类型的(因此没有引号),描述您希望把对象移动到什么地方。因此,如果要把 myBigLayer 对象移动到距离窗口左边 300 p 像素,距离窗口上边10像素的位置,书写如下代码就可以了:
    moveObject('myBigLayer', 300, 10)
  • getStyleObject(objectId):上述两个函数都使用这个函数来把对象的名称转变为属于该对象的风格对象的引用。对于 Netscape 4+ 和 IE 4+ 两款浏览器来说,这个函数都能返回正确的引用,因此您不必担心浏览器在工作方式上的差别。(请注意:有一种情况在 Netscape 4 上处理不了,那就是聚集层,因此您必须避免把层放到其它层上)。

    在您需要改变对象的 CSS 属性的任何时候,您都可以脱离这里描述的上下文来使用这个函数。例如,假定我们要给 myBigLayer 设定一个绿的背景色,可以书写如下代码:

    ar myBigLayerStyleObject =
        getStyleObject('myBigLayer');
        myBigLayerStyleObject.backgroundColor =
        'green';

    Or, for shorthand, you could just do this:

    getStyleObject('myBigLayer').backgroundColor
        = 'green';






    utility.txt

    // Copyright ?2000 by Apple Computer, Inc., All Rights Reserved.
        //
        // You may incorporate this Apple sample code into your own code
        // without restriction. This Apple sample code has been provided "AS IS"
        // and the responsibility for its operation is yours. You may redistribute
        // this code, but you are not permitted to redistribute it as
        // "Apple sample code" after having made changes.
        //
        // ************************
        // layer utility routines *
        // ************************
        function getStyleObject(objectId) {
        // cross-browser function to get an object's style object given its id
        if(document.getElementById && document.getElementById(objectId)) {
        // W3C DOM
        return document.getElementById(objectId).style;
        } else if (document.all && document.all(objectId)) {
        // MSIE 4 DOM
        return document.all(objectId).style;
        } else if (document.layers && document.layers[objectId]) {
        // NN 4 DOM.. note: this won't find nested layers
        return document.layers[objectId];
        } else {
        return false;
        }
        } // getStyleObject
        function changeObjectVisibility(objectId, newVisibility) {
        // get a reference to the cross-browser style object and make sure the object exists
        var styleObject = getStyleObject(objectId);
        if(styleObject) {
        styleObject.visibility = newVisibility;
        return true;
        } else {
        // we couldn't find the object, so we can't change its visibility
        return false;
        }
        } // changeObjectVisibility
        function moveObject(objectId, newXCoordinate, newYCoordinate) {
        // get a reference to the cross-browser style object and make sure the object exists
        var styleObject = getStyleObject(objectId);
        if(styleObject) {
        styleObject.left = newXCoordinate;
        styleObject.top = newYCoordinate;
        return true;
        } else {
        // we couldn't find the object, so we can't very well move it
        return false;
        }
        } // moveObject
        
    popup.txt
    // Copyright ?2000 by Apple Computer, Inc., All Rights Reserved.
        //
        // You may incorporate this Apple sample code into your own code
        // without restriction. This Apple sample code has been provided "AS IS"
        // and the responsibility for its operation is yours. You may redistribute
        // this code, but you are not permitted to redistribute it as
        // "Apple sample code" after having made changes.
        // ********************************
        // application-specific functions *
        // ********************************
        // store variables to control where the popup will appear relative to the cursor position
        // positive numbers are below and to the right of the cursor, negative numbers are above and to the left
        var xOffset = 30;
        var yOffset = -5;
        function showPopup (targetObjectId, eventObj) {
        if(eventObj) {
        // hide any currently-visible popups
        hideCurrentPopup();
        // stop event from bubbling up any farther
        eventObj.cancelBubble = true;
        // move popup div to current cursor position
        // (add scrollTop to account for scrolling for IE)
        var newXCoordinate = (eventObj.pageX)?eventObj.pageX + xOffset:eventObj.x + xOffset + ((document.body.scrollLeft)?document.body.scrollLeft:0);
        var newYCoordinate = (eventObj.pageY)?eventObj.pageY + yOffset:eventObj.y + yOffset + ((document.body.scrollTop)?document.body.scrollTop:0);
        moveObject(targetObjectId, newXCoordinate, newYCoordinate);
        // and make it visible
        if( changeObjectVisibility(targetObjectId, 'visible') ) {
        // if we successfully showed the popup
        // store its Id on a globally-accessible object
        window.currentlyVisiblePopup = targetObjectId;
        return true;
        } else {
        // we couldn't show the popup, boo hoo!
        return false;
        }
        } else {
        // there was no event object, so we won't be able to position anything, so give up
        return false;
        }
        } // showPopup
        function hideCurrentPopup() {
        // note: we've stored the currently-visible popup on the global object window.currentlyVisiblePopup
        if(window.currentlyVisiblePopup) {
        changeObjectVisibility(window.currentlyVisiblePopup, 'hidden');
        window.currentlyVisiblePopup = false;
        }
        } // hideCurrentPopup
        // ***********************
        // hacks and workarounds *
        // ***********************
        // initialize hacks whenever the page loads
        window.onload = initializeHacks;
        // setup an event handler to hide popups for generic clicks on the document
        document.onclick = hideCurrentPopup;
        function initializeHacks() {
        // this ugly little hack resizes a blank div to make sure you can click
        // anywhere in the window for Mac MSIE 5
        if ((navigator.appVersion.indexOf('MSIE 5') != -1)
        && (navigator.platform.indexOf('Mac') != -1)
        && getStyleObject('blankDiv')) {
        window.onresize = explorerMacResizeFix;
        }
        resizeBlankDiv();
        // this next function creates a placeholder object for older browsers
        createFakeEventObj();
        }
        function createFakeEventObj() {
        // create a fake event object for older browsers to avoid errors in function call
        // when we need to pass the event object to functions
        if (!window.event) {
        window.event = false;
        }
        } // createFakeEventObj
        function resizeBlankDiv() {
        // resize blank placeholder div so IE 5 on mac will get all clicks in window
        if ((navigator.appVersion.indexOf('MSIE 5') != -1)
        && (navigator.platform.indexOf('Mac') != -1)
        && getStyleObject('blankDiv')) {
        getStyleObject('blankDiv').width = document.body.clientWidth - 20;
        getStyleObject('blankDiv').height = document.body.clientHeight - 20;
        }
        }
        function explorerMacResizeFix () {
        location.reload(false);
        }
        
    弹出式帮助的实例

    <HTML><HEAD>

    <script src="utility.txt"></script>

    <script src="popup.txt"></script>


    <STYLE>

    .popupLink { COLOR: red; outline: none }

    .popup { POSITION: absolute; VISIBILITY: hidden; BACKGROUND-COLOR: yellow; LAYER-BACKGROUND-COLOR: yellow; width: 200; BORDER-LEFT: 1px solid black; BORDER-TOP: 1px solid black; BORDER-BOTTOM: 3px solid black; BORDER-RIGHT: 3px solid black; PADDING: 3px; z-index: 10 }

    </STYLE>


    <BODY bgcolor="#ffffff">


    <!-- keep the popup divs as the first things on the page or else MSIE 5 on the mac sometimes has trouble rendering them on top of text -->

    <DIV onclick='event.cancelBubble = true;' class=popup id=nameFieldPopup>Hi, [your name here]! We need to know your <b>name</b> so we can address you a bit more personally. [<a class=closeLink href='#' onclick='hideCurrentPopup(); return false;'>close this tip</a>]</DIV>

    <DIV onclick='event.cancelBubble = true;' class=popup id=emailFieldPopup>Well, yeah, you could put in a fake <b>email address</b>, but then we couldn't send you occasional updates. Oh and, um, we promise not to spam you. [<a class=closeLink href='#' onclick='hideCurrentPopup(); return false;'>close this tip</a>]</DIV>


    <!-- begin body of document -->

    <form>
        <p>Fill in the form:</p>


        <P>Name: <input type=text> [<a href="non_js_help.html" class=popupLink onclick="return !showPopup('nameFieldPopup', event);">help</a>]</P>
        <P>Email: <input type=text> [<a href="non_js_help.html" class=popupLink onclick="return !showPopup('emailFieldPopup', event);">help</a>]</P>
    </form>

     


    <!-- leave this blank div in here to make sure you can click anywhere on the document for MSIE 5 mac -->
    <div id="blankDiv" style="position: absolute; left: 0; top: 0; visibility: hidden"></div>


    </BODY></HTML>
    http://www.apple.com.cn/developer/internet/webcontent/hideshow_layer.html









posted @ 2008-06-24 17:30 飞飞 阅读(864) | 评论 (0)编辑 收藏

   在怎合struts+hibernate+spring时,Tomcat出现了Error Listenerstart错误码,郁闷的很,在网上找了很多的资料,提问的不少,但都没有很标准的解释以用解决的办法,有的说是jar包的版本冲突,有的说是Tomcat的自身问题,各解释都有,基本上所有的方法我都试过了。就这个问题搞了两天。终于找到了解决的办法:在web.xml时将:

<!-- 使用监听方式载入Spring上下文 -->
<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

改为:

<!-- 使用监听方式载入Spring上下文 -->
<servlet>
   <servlet-name>SpringContextServlet</servlet-name>
   <servlet-class>
    org.springframework.web.context.ContextLoaderServlet
   </servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>
<servlet>
   <servlet-name>SpringLog4jConfigServlet</servlet-name>
   <servlet-class>
    org.springframework.web.util.Log4jConfigServlet
   </servlet-class>
</servlet>
<servlet>
   <servlet-name>web</servlet-name>
   <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
   </servlet-class>
</servlet>

posted @ 2008-06-22 11:46 飞飞 阅读(7564) | 评论 (1)编辑 收藏

一、在Myeclipse软件中部署

1、 Myeclipse中,创建好工程后,在Myeclipse菜单栏中选择 Windows -> Preferences -> Myeclipse -> Tomcat5,选择"Enable";Tomact Home Directory要选择你机器上Tomcat所安装的目录。然后,再Windows -> Preferences -> Myeclipse -> Tomcat5 ->JDK,确保这个是有对应的jdk版本,若没有,则通过"Add"添加其安装路径。ok

2、选择工具栏上的 按钮,在”Project”中选择你要部署的工程,然后”Add”,再选择”Tomcat”Finish

3、 在工具栏上选择 ,启动Tomcat

4、 运行程序。在IE中输入http://localhost:8080/aa/WebRoot/index.jsp(aa为工程名字)

二、在Tomcatserver.xml配置文件中部署

1、在Tomcat下,找到conf文件下的server.xml,打开。

2、在<Host></host>之间加上如下代码:

1 
2 <Context path="/虚拟目录名" docBase="目标目录位置" debug="0" reloadable="true" >
3 </Context>

(严格区分大小写,当path=""时,此时的虚拟目录直接为root--->http://localhost:8080/)
       
参数:

         path:表示在浏览器中输入http://localhost:8080/虚拟目录名

         docBase:表示你的程序包的物理绝对路径,默认的绝对路径是     %tomcat_home%/webapps

         reloadable :为true,则tomcat会自动检测应用程序的/WEB-INF/lib /WEB-INF/classes目录的变化,自动装载新的应用程序,我们可以在不重起tomcat的情况下改变应用程序;为false则不自动加载。

 (我觉得这种部署方法就好在这里,可以不用重新启动Tomcat。不知道前一种方法是不是在哪个地方进行配置即可实现同样的效果。若有,请高人指点!)

示例:

1        
2 <!-- 我的自定义目录-->
3 <Context path="/wess" debug="0" docBase="C:\Documents and Settings\tt\workspace\Welcome_SS\WebRoot" reloadable="true">
4 </Context> 
5 4

3、 启动Tomcat

Myeclipse工具栏上选择 ,启动Tomcat。或者在Tomcat下,找到bin文件下的startup.bat,打开进行启动。

4、 运行程序。在IE地址中输入http://localhost/wess/index.jsp(引用上面示例配置时的情况)

附:

    在lib下的struts-config.xml可以添加下面三句进行主页默认的配置,即在IE中只需输入到主页所在目录,而不必写出主页。如上面的配置就可只输入http://localhost/wess

 <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

 

posted @ 2008-06-22 09:07 飞飞 阅读(391) | 评论 (1)编辑 收藏

仅列出标题
共12页: First 上一页 4 5 6 7 8 9 10 11 12 下一页