随笔-13  评论-6  文章-0  trackbacks-0
  2006年2月9日
1:
java.sql.Timestamp a = new java.sql.Timestamp(System.currentTimeMillis());

2:
java.util.Date a = new java.util.Date();

3:
java.util.Date a;
a.setTime(System.currentTimeMillis());
posted @ 2006-03-24 09:41 java之海 阅读(4989) | 评论 (0)编辑 收藏

J2EE1.4 新特性之JSP 2.0的新特性

作者:务实工作室 发文时间:2003.10.27

SUN 的新版J2EE1.4提供了在J2EE中开发Web Service的基础,对开发工具做了一些重要的增强,在应用程序部署和服务器管理方面也提供了新的标准,在集成性和安全性方面有所增强,提升了J2EE 开发Web应用程序的能力;在编程模型方面的重要变化包括JSP表达式语言、简化的标记库等;EJB 2.1中提供了新的timer服务,查询语言(QL)也有所增强;Jdbc3.0 API把通常的Jdbc API与扩充API结合起来;J2EE Connectors规范和独立于消息类型的EJB提供了对双向通信的支持。下面给大家重点介绍J2EE1.4中包含的JSP2.0 Servlet2.4Jdbc3.0以及EJB2.1方面的新特性。


一、JSP 2.0的新特性



JSP 2.0
属于J2EE 1.4平台,它在JSP 1.2基础之上增加了新的功能。它保证了向下兼容,原先使用的JSP技术在JSP 2.0中都可以支持。JSP 2.0的新功能主要包括下面几部分:

(
)运行环境变化

1
web.xml格式变化

我们知道JSP 1.2可以在Java 2标准版1.3版本运行,而JSP 2.0要求使用Java 2标准版1.4或更新版本,JSP 2.0使用由Servlet 2.4规定的Web程序部署描述格式。

Web程序描述文件web.xml中需要使用xml schema打头的格式。在web.xml中主要的变化是所有有关JSP的设置信息要放在标记中。下面程序例1显示了一个web.xml大致的样子。

1




    .......



    http://www.icconcept.com/ics/sample-taglib


    /WEB-INF/jsp/sample-taglib.tld


    ........


    For config the ICW sample application

JSPConfiguration
/jsp/datareset.jsp
true<
el-ignored>
ISO-8859-1
true
/jsp/prelude.jspf
/jsp/coda.jspf





2
JSP设置

在标记提供了Web程序中JSP程序的设置信息。包括和两类元素。定义了Web程序使用的custom tag,它的用法和以前JSP 1.2中的用法相同。定义了一组JSP的特性。这些特性实际上对应JSPpage directive定义的特性。通过只不过可以方便地对多个具有相同属性的JSP统一定义。

定义一个或多个URL样式,在中定义的属性会适用于匹配这些URL样式的所有JSP文件。在中的属性可以定义以下设置:

(1)
允许或禁止使用表达式语言(EL)

在中可以设定是否允许对应的JSP使用JSTL表达式语言(EL)。如果属性标记被设定为falseJSP中的EL表达式会被处理;如果是trueWeb容器会在转换JSP时忽略EL表达式。

(2)
允许或禁止使用scripting

属性可以允许或禁止使用JSP的脚本语言(scripting)。如果这个属性标记对应为 true,即scripting元素被禁止,则JSP中不能使用scriptletscripting表达式和declaration,否则会有转换错 误。当这个属性标记为false时,JSP可以像在1.2版本之前那样使用脚本语言。

(3)
声明JSP编码

通过标记可以设置对应的JSP网页的编码。这个属性对应每个JSP中的pageEncoding属性,Web容器将根据这个属性对JSP内容进行编码。

(4)
对应隐含包括(Implicit Includes)

在中可以在对应JSP中加入抬头(preludes)和结尾(coda),使用和属性可以设定在JSP网页中包括的preludescodajspf文件。这些文件的位置相对于当前Web程序的context。当有超过一个preludescoda元素在中时,JSP会按照其顺序加入到内容中。

(
)引入表达式语言(EL)

JSP 2.0
的一个主要特点是它支持表达语言(expression language)JSTL表达式语言可以使用标记格式方便地访问JSP的隐含对象和JavaBeans组件,JSTL的核心标记提供了流程和循环控制 功能。自制标记也有自定义函数的功能,因此基本上所有seriptlet能实现的功能都可以由JSP替代。在JSP 2.0中,建议尽量使用EL而使JSP的格式更一致。

web.xml的中可以控制一组JSP是否使用EL,在每个JSP中也可以指定是否该JSP使用EL。在page directive中的isELIgnored属性用来指定是否忽略。格式为:


<%@ page isELIgnored "true|false"%>



如果设定为真,那么JSP中的表达式被当成字符串处理。比如下面这个表达式

${2000 % 20}

isELIgnored"true"时输出为${2000 % 20},而isELIgnored"false"时输出为100Web容器默认isELIgnored"false"

虽然JSP 2.0可以使JSP中完全使用表达语言而避免scriptlet,在实际编程中,应该根据程序的功能要求和编程人员的自身条件选择合适的方式。使用表达语 言的JSP比较方便规整,但是由于需要将标记进行转换,在第一次被调用时会比较慢;有些编程人员由于对Java比较了解,因而更习惯JSP 1.2之前的编程方式,因此,在使用中应因地制宜地选择适用的编程方法。

(
)SimpleTag

JSP 2.0
中加入了新的创建自制标记的APIjavax.servlet.jsp.tagext.SimpleTag定义了用来实现简单标记的接口。和 JSP 1.2中的已有接口不同的是,SimpleTag接口不使用doStartTag()doEndTag()方法,而提供了一个简单的doTag()方 法。这个方法在调用该标记时只被使用一次。而需要在一个自制标记中实现的所有逻辑过程、循环和对标记体的评估等都在这个方法中实现。从这个方面来讲, SimpleTagIterationTag可以达到同等的作用。但SimpleTag的方法和处理周期要简单得多。在SimpleTag中还有用来设 置JSP内容的seUspBody()getJspBody()方法。Web容器会使用setJspBody()方法定义一个代表JSP内容的 JspFragment对象。实现SimpleTag标记的程序可以在doTag方法中根据需要多次调用getJspBody().invoke()方法 以处理JSP内容。

例如,程序例2 SimpleTag根据指定的次数(times)进行循环并输出当前序号(sequence)。程序的结构比较简单,所有逻辑都在doTag方法中实现。

2


package ICW.taglib;
  import javax.servlet.jsp.JspException;
  import javax.servlet.jsp.tagext.SimpleTagSupport;
  import java.util.HashMap;
  import java.io.IOException;
  public class IterationSimpleTag extends SimpleTagSupport{
  private int times;
public void setTimes(int_times){
    this.times=_times;
        }
    public void doTag() throws JspException,IOException{
    HashMap params=new HashMap();
    for(int i=0; i



这个标记的TLD文件内容如下,它使用了XML schcma定义标记的使用方法。

程序例3如下:





1.0
Jwad book simple tag
/JwadSimpleTag
Simple Tag Handler

iteration
ICW.taglib.IterationSimpleTag
scriptless
Iteration Tag

Current iterationnumber
sequence


times
true
true





程序例4中的JSP使用上面例3中定义的IterationSimpleTag,它根据Web请求参数中给定的“times”的值进行一定次数的循环。在每次循环中将输出"sequence"的值。

4


<%@ taglib prefix="ictag" uri="/WEB-INF/ics-jsp2.tld" %>




Interation Simple Tag

 





Reminder:




    This is the ${sequence} Of ${times} times of reminder




(
)使用JSP fragment

JSP 2.0
中的一个主要功能是JSP fragment,它的基本特点是可以使处理JSP的容器推迟评估JSP标记属性。我们知道一般JSP是首先评估JSP标记的属性,然后在处理JSP标记 时使用这些属性,而JSP fragment提供了动态的属性。也就是说,这些属性在JSP处理其标记体时是可以被改变的。JSP需要将这样的属性定义为 javax.servlet.jsp.tagext.JspFragment类型。当JSP标记设置成这种形式时,这种标记属性实际上的处理方法类似于标 记体。在实现标记的程序中,标记属性可以被反复评估多次。这种用法称为JSP fragmentJSP fragment还可以定义在一个SimpleTag处理程序中使用的自制标记动作。像前面例子说明的,getJspBody返回一个 JspFragment对象并可以在doTag方法中多次使用。需要注意的是,使用JSP fragmentJSP只能有一般的文本和JSP action,不能有scriptletscriptlet表达式。

我们可以简单地认为JSP fragment是一段可以重复使用的JSP。一段JSP fragment可以被传递到另一个JSP中并被使用。与JSP include概念不同的是,JSP fragment一般功能比较短小简单而且重复使用率高。

JSP fragment
一般在标记体内或标记体内定义。每次当含有JSP fragment的标记被使用时,Web容器生成一个JspFragment对象,这个对象和当前JSPpage scope联系起来。同时,这个JspFragment对象和包含它的父标记建立联系。JspFragment对象可以有两种调用方式:使用Java编写 的标记处理程序,或者使用标记文件(tag file)。标记文件可以使用,或者动作使用JSP fragment JSP标记文件可以和JSP fragment共同工作。CustomTag都是以编程方式实现的。JSP标记文件是用文本文件格式(JSP语法)实现自制标记,这也是JSP 2.0的一个主要新功能。一个标记文件可以对应一个标记,可以不需tld文件定义该标记的方法。这样,即使编程人员不熟悉Java,也可以使用JSP语法 定义自己的标记。标记文件一般使用.tag为后缀并放在Web程序的/WEB-INF目录下。

程序例5中的taskstatus.jsp使用了两个JSP fragment。这个JSP的功能是显示一组Task的名称和完成日期,它通过定义了两段JSPfragment(名称为onSeheduledelayed)。在标记内的JSP就是JSPfragment,而标记被一个包围。这个标记是一个通过标记文件定义的自制标记,它的定义文件在/WEB-INF/tags目录下。标记文件的名称和标记名称一致为“listTasks.tag"。这个标记会使用到前面定义的两个JSP fragment

5:


<%@ taglib prefix="ictag" tagdir="/WEB-INF/tags" %>




JSP Fragment Sample Using Tag Files

 


 

Tasks





Name:${name}

Date:${date}

Name:${name}

Plan: ${pianDate}
Actural:${actDate}



(
)其他特性

JSP2.0
还有一些其他特性变化,比如严格修正了I18N的语法规则,改进JSP对应XML语法从而允许使用namespaces等。这些并不是核心功能,大家可以参照java.sun.com的有关资料了解功能的细节,这里就不再阐述。

posted @ 2006-03-23 09:54 java之海 阅读(439) | 评论 (0)编辑 收藏

简单的表达式语言


Sun Microsystems 在 1997 年下半年推出了 Servlet API,将它定位为 CGI 开发人员使用的一种功能强大的工具,这些开发人员正在寻找比 CGI(通用网关接口)编程更高效和轻便的优秀解决方案。但是,开发人员很快就发现 Servlet API 有其自身的缺点,从代码的可维护性和可扩展性方面来看,该解决方案难以实施。在某种程度上,这种缺点促使团队开发一种允许在 HTML 中嵌入 Java 代码的解决方案 — JavaServer Pages (JSP) 因此而出现。

不久以后,开发人员意识到将表达与商务逻辑混合在一起的复杂 JSP 页不易于理解和维护。不能编写 scriplet 的页面制作人员所面临的另一个问题是由于标准标记集而带来的 JSP 限制。这些限制使得难点变成利用 JSP 实施自定义标记的机制来创建 JSP 自定义标记。

JSP 标准标记库 (JSTL) 是自定义标记库的集合,它将许多 JSP 应用程序通用的核心功能封装为简单的标记。它不再需要使用 JSP scriptlet
和表达式,而使用表达式的更高级语法。它还实现了通用目的的功能,如迭代和条件化、数据管理格式化、XML 操作、数据库访问、国际化和对本地化信息敏感的格式化标记以及 SQL 标记。JSTL 1.0 推出了 EL 的概念,但只限于 JSTL 标记。在 JSP 2.0 中,您可以使用带模板文本的 EL,甚至可以通过 javax.servlet.jsp.el 获得编程方式的访问。

在我们了解 JSTL 如何适应环境以及与 JSTL 表达式语言相关的限制以后,我们来看 JSP 2.0 的重要优点之一 — JSP 表达式语言 (EL)。我们将特别涉及到以下内容:

JSP 表达式语言定义
在无脚本的 JSP 页面中支持 EL 的机制
表达式语言语法
JSP EL 中有效的表达式
使用 EL 表达式

JSP 表达式语言定义

表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法。它是一种简单的语言,基于可用的命名空间(PageContext 属性)、嵌套属性和对集合、操作符(算术型、关系型和逻辑型)的访问符、映射到 Java 类中静态方法的可扩展函数以及一组隐式对象。

EL 提供了在 JSP 脚本编制元素范围外使用运行时表达式的功能。脚本编制元素是指页面中能够用于在 JSP 文件中嵌入 Java 代码的元素。它们通常用于对象操作以及执行那些影响所生成内容的计算。JSP 2.0 将 EL 表达式添加为一种脚本编制元素。

脚本编制元素具有三个从属形式:

  • 声明
  • Scriptlet
  • 表达式。

    让我们来看代码中的这三种从属形式:

    <%! int i = 1; %> <% -- Declaration --%>
    <% for (int i =0; i < 10; i++) { %> <% -- Scriptlets --%>
    table.getColumn( ) <% -- Expression --%>

    在将 EL 添加到 JSP 工具包以后,可以使用更简单的语法来编写以上的代码,而获得与以上 JSP 元素相同的结果。EL 表达式的另一个优势是,可以在不允许使用上述任何脚本编制元素从属形式的无脚本的 JSP 页中使用它。但是必须注意,可以不使用三种脚本编制元素从属形式中的任一种来编写 JSP 页,而对 JSP 页是否应该为无脚本形式的选择则完全基于应用程序的需求。如果您希望明确分开表达与商务逻辑,则还可以选择将页面强制为无脚本形式。通过强制成为无脚本页 面,必须通过其他元素(如 JavaBean、EL 表达式、自定义操作和标准标记库)提供 JSP 页的动态行为。

    在无脚本的 JSP 页中支持 EL 的机制

    有两种机制可以确保页面不包含任何脚本编制元素。每种机制还提供在无脚本的 JSP 页中支持 EL 的方法。

    • 使用页面指示:

      在使用页面指示时,您可以通过将 isELEnabled 指示的值相应地设为“true”或“false”,指定是否支持 EL,如下所示:

      <%@ page isScriptingEnabled="true|false" isELEnabled="true|false"%>
    • 使用部署描述符的元素:

      当使用部署描述符的元素时,您可以通过在 标记间包含布尔值“true”或“false”,指定是否支持 EL,如下所示:
      ...


      *.jsp
      true
      true


      ....

    表达式语言语法

    JSP 表达式语言允许页面制作人员使用简单语法访问组件,如:


    ${expr}

    在以上的语法中,expr 代表有效的表达式。必须注意,该表达式可以与静态文本混合,还可以与其他表达式结合成更大的表达式。

    JSP EL 中的有效表达式

    有效表达式可以包含文字、操作符、变量(对象引用)和函数调用。我们将分别了解这些有效表达式中的每一种:

    文字

    JSP 表达式语言定义可在表达式中使用的以下文字:

  • 文字文字的值

    Boolean

    true 和 false

    Integer

    与 Java 类似。可以包含任何正数或负数,例如 24、-45、567

    Floating Point

    与 Java 类似。可以包含任何正的或负的浮点数,例如 -1.8E-45、4.567

    String

    任何由单引号或双引号限定的字符串。对于单引号、双引号和反斜杠,使用反斜杠字符作为转义序列。必须注意,如果在字符串两端使用双引号,则单引号不需要转义。

    Nullnull

    让我们来看一些使用文字作为有效表达式的示例:

    ${false} <%-- evaluates to false --%>
    ${3*8)

    操作符

    JSP 表达式语言提供以下操作符,其中大部分是 Java 中常用的操作符:

    术语定义

    算术型

    +、-(二元)、*、/、div、%、mod、-(一元)

    逻辑型

    and、&&、or、||、!、not

    关系型

    ==、eq、!=、ne、、gt、<=、le、>=、ge。可以与其他值进行比较,或与布尔型、字符串型、整型或浮点型文字进行比较。

    空操作符是前缀操作,可用于确定值是否为空。

    条件型A ?B :C。根据 A 赋值的结果来赋值 B 或 C。

    让我们来看一些使用操作符作为有效表达式的示例:

    ${ (6 * 5) + 5 } <%-- evaluates to 35 --%>
    ${empty name}

    隐式对象

    JSP 表达式语言定义了一组隐式对象,其中许多对象在 JSP scriplet 和表达式中可用:

    术语定义

    pageContext

    JSP 页的上下文。它可以用于访问 JSP 隐式对象,如请求、响应、会话、输出、servletContext 等。例如,${pageContext.response} 为页面的响应对象赋值。

    此外,还提供几个隐式对象,允许对以下对象进行简易访问:

    术语定义

    param

    将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (String name) 获得)。getParameter (String) 方法返回带有特定名称的参数。表达式 $(param.name) 相当于 request.getParameter (name)。

    paramValues

    将请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (String name) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式 ${paramvalues.name) 相当于 request.getParamterValues(name)。

    header

    将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(String name) 获得)。表达式 ${header.name} 相当于 request.getHeader(name)。

    headerValues

    将请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String) 获得)。它与头隐式对象非常类似。表达式 ${headerValues.name} 相当于 request.getHeaderValues(name)。

    cookie将 cookie 名称映射到单个 cookie 对象。向服务器发出的客户端请求可以获得一个或多个 cookie。表达式 ${cookie.name.value} 返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 ${headerValues.name} 表达式。
    initParam将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。

    除了上述两种类型的隐式对象之外,还有些对象允许访问多种范围的变量,如 Web 上下文、会话、请求、页面:

    术语定义

    pageScope

    将页面范围的变量名称映射到其值。例如,EL 表达式可以使用 ${pageScope.objectName} 访问一个 JSP 中页面范围的对象,还可以使用 ${pageScope.objectName.attributeName} 访问对象的属性。

    requestScope

    将请求范围的变量名称映射到其值。该对象允许访问请求对象的属性。例如,EL 表达式可以使用 ${requestScope.objectName} 访问一个 JSP 请求范围的对象,还可以使用 ${requestScope.objectName.attributeName} 访问对象的属性。

    sessionScope

    将会话范围的变量名称映射到其值。该对象允许访问会话对象的属性。例如:

    <% session.put (name", "John Doe"); %>
    $sessionScope.name} <%-- evaluates to John Doe --%>
    <%= session.get("name"); %> <%-- This is an equivalent scripting expression --%>

    applicationScope

    将应用程序范围的变量名称映射到其值。该隐式对象允许访问应用程序范围的对象。

    必须注意,当表达式根据名称引用这些对象之一时,返回的是相应的对象而不是相应的属性。例如:即使现有的 pageContext 属性包含某些其他值,${pageContext} 也返回 PageContext 对象。

    使用 EL 表达式

    EL 表达式可用于两种情况:

    • 作为标准操作和自定义操作中的属性值

    • 在 JSP 文件的模板文本中,如 HTML 或非 JSP 元素 — 在这种情况下,模板文本中的表达式被赋值并插入到当前的输出中。但是,必须注意,如果标记的主体被声明为与标记相关,则不会对表达式赋值。
    posted @ 2006-03-23 09:51 java之海 阅读(623) | 评论 (0)编辑 收藏
    <action path="/articleEdit" attribute="articleForm" input="/ArticleEdit.jsp" name="articleForm"                                          type="com.xianeizhu.struts.action.ArticleEditAction">
    <forward name="articleList" path="/articleList.do" redirect="true" />
    </action>

    redirect="true"造成错误
    Cannot find bean blacktags in any scope
    posted @ 2006-03-21 16:06 java之海 阅读(612) | 评论 (0)编辑 收藏
    使用MyEclipse开发web项目,所生成的web.xml头部如下:
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    等到要在web.xml加入taglib
        <taglib>
            <taglib-uri>/WEB-INF/tiles.tld</taglib-uri>
            <taglib-location>/WEB-INF/tiles.tld</taglib-location>
        </taglib>
    始终会报错
    后来把头部改为
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app
      PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">

    <web-app>
    ......
    </web-app>
    终于可以加taglib了,但原来的filter又报错,最后把
    filter和filter-mapping放在最前面,终于ok.

    posted @ 2006-03-14 16:02 java之海 阅读(4992) | 评论 (6)编辑 收藏
    推荐一个java GUI设计的极品网站

    look and feel: http://www.javootoo.com/
    java开源: http://www.open-open.com/

  • 3D Look And Feel
  • Audio Look And Feel
  • Kunststoff Look&Feel
  • Metouia Look & Feel
  • NextStep Look And Feel
  • Teknolust Look And Feel
  • xp look and feel

  • posted @ 2006-03-07 09:46 java之海 阅读(301) | 评论 (0)编辑 收藏
     

    Table of ASCII Characters

    This table lists the ASCII characters and their decimal, octal and hexadecimal numbers. Characters which appear as names in parentheses (e.g., (nl)) are non-printing characters. A table of the common non-printing characters appears after this table.

    Char  Dec  Oct  Hex | Char  Dec  Oct  Hex | Char  Dec  Oct  Hex | Char Dec  Oct   Hex
    -------------------------------------------------------------------------------------
    (nul) 0 0000 0x00 | (sp) 32 0040 0x20 | @ 64 0100 0x40 | ` 96 0140 0x60
    (soh) 1 0001 0x01 | ! 33 0041 0x21 | A 65 0101 0x41 | a 97 0141 0x61
    (stx) 2 0002 0x02 | " 34 0042 0x22 | B 66 0102 0x42 | b 98 0142 0x62
    (etx) 3 0003 0x03 | # 35 0043 0x23 | C 67 0103 0x43 | c 99 0143 0x63
    (eot) 4 0004 0x04 | $ 36 0044 0x24 | D 68 0104 0x44 | d 100 0144 0x64
    (enq) 5 0005 0x05 | % 37 0045 0x25 | E 69 0105 0x45 | e 101 0145 0x65
    (ack) 6 0006 0x06 | & 38 0046 0x26 | F 70 0106 0x46 | f 102 0146 0x66
    (bel) 7 0007 0x07 | ' 39 0047 0x27 | G 71 0107 0x47 | g 103 0147 0x67
    (bs) 8 0010 0x08 | ( 40 0050 0x28 | H 72 0110 0x48 | h 104 0150 0x68
    (ht) 9 0011 0x09 | ) 41 0051 0x29 | I 73 0111 0x49 | i 105 0151 0x69
    (nl) 10 0012 0x0a | * 42 0052 0x2a | J 74 0112 0x4a | j 106 0152 0x6a
    (vt) 11 0013 0x0b | + 43 0053 0x2b | K 75 0113 0x4b | k 107 0153 0x6b
    (np) 12 0014 0x0c | , 44 0054 0x2c | L 76 0114 0x4c | l 108 0154 0x6c
    (cr) 13 0015 0x0d | - 45 0055 0x2d | M 77 0115 0x4d | m 109 0155 0x6d
    (so) 14 0016 0x0e | . 46 0056 0x2e | N 78 0116 0x4e | n 110 0156 0x6e
    (si) 15 0017 0x0f | / 47 0057 0x2f | O 79 0117 0x4f | o 111 0157 0x6f
    (dle) 16 0020 0x10 | 0 48 0060 0x30 | P 80 0120 0x50 | p 112 0160 0x70
    (dc1) 17 0021 0x11 | 1 49 0061 0x31 | Q 81 0121 0x51 | q 113 0161 0x71
    (dc2) 18 0022 0x12 | 2 50 0062 0x32 | R 82 0122 0x52 | r 114 0162 0x72
    (dc3) 19 0023 0x13 | 3 51 0063 0x33 | S 83 0123 0x53 | s 115 0163 0x73
    (dc4) 20 0024 0x14 | 4 52 0064 0x34 | T 84 0124 0x54 | t 116 0164 0x74
    (nak) 21 0025 0x15 | 5 53 0065 0x35 | U 85 0125 0x55 | u 117 0165 0x75
    (syn) 22 0026 0x16 | 6 54 0066 0x36 | V 86 0126 0x56 | v 118 0166 0x76
    (etb) 23 0027 0x17 | 7 55 0067 0x37 | W 87 0127 0x57 | w 119 0167 0x77
    (can) 24 0030 0x18 | 8 56 0070 0x38 | X 88 0130 0x58 | x 120 0170 0x78
    (em) 25 0031 0x19 | 9 57 0071 0x39 | Y 89 0131 0x59 | y 121 0171 0x79
    (sub) 26 0032 0x1a | : 58 0072 0x3a | Z 90 0132 0x5a | z 122 0172 0x7a
    (esc) 27 0033 0x1b | ; 59 0073 0x3b | [ 91 0133 0x5b | { 123 0173 0x7b
    (fs) 28 0034 0x1c | < 60 0074 0x3c | \ 92 0134 0x5c | | 124 0174 0x7c
    (gs) 29 0035 0x1d | = 61 0075 0x3d | ] 93 0135 0x5d | } 125 0175 0x7d
    (rs) 30 0036 0x1e | > 62 0076 0x3e | ^ 94 0136 0x5e | ~ 126 0176 0x7e
    (us) 31 0037 0x1f | ? 63 0077 0x3f | _ 95 0137 0x5f | (del) 127 0177 0x7f
    ASCII Name Description C Escape Sequence
    nul null byte \0
    bel bell character \a
    bs backspace \b
    ht horizontal tab \t
    np formfeed \f
    nl newline \n
    cr carriage return \r
    vt vertical tab
    esc escape
    sp space
    posted @ 2006-03-07 09:45 java之海 阅读(343) | 评论 (0)编辑 收藏
    mysql error number 1005 can't create table errno: 150

    这是建外键的列与要关联的列类型不匹配造成的。
    一个表用powerdesigner导入的整型长度为11
    另一个直接再mysql中建立的表默认整型长度是10

    造成不能建立外键
    posted @ 2006-03-03 17:09 java之海 阅读(1276) | 评论 (0)编辑 收藏

    Tomcat服务器配置参考

    Host容器

    概述

    Host元素代表一个虚拟主机,虚拟主机将服务器的网络名(比如www.mycompany.com)和运行Catalinade的某个特定服务器联系起来。为了生效,网络名称必须在管理你所在的Internet域的DNS服务器进行登记---请联系你的网络管理员。

    在许多情况下,系统管理员可能希望为同一个虚拟主机或应用关联多个网络名称(比如www.mycompany.com和company.com)。这可以利用下面讨论的Host Name Alias特征来完成。

    在Engine元素中可以嵌套一个或多个Host元素。在Host元素中可以嵌套context元素。在与每个Engine相关联的所有Host中,必须有一个Host的名称与Engine的defaultHost属性匹配。

    以下的描述使用变量$CATALINA_HOME来指Tomcat 5安装的目录。大多数的相对路径都是以该目录为基准。但是,通过设置CATALINA_BASE目录,可以运行多个Tomcat 5实例,这时你应该使用$CATALINA_BASE来作为目录基准,而不是使用$CATALINA_HOME。

    属性
    公共属性

    所有Host的实现必须支持如下属性:

    属性 描述
    appBase

    虚拟主机的Applicaton Base目录。这是在该虚拟主机上发布web应用的目录路径。你可以指定绝对路径,或者使用相对于$CATALINA_HOME的路径。有关web应用的自动识别和发布的更多信息,请参考应用自动发布。

    autoDeploy

    这个标志表示,在Tomcat运行的时候,放到appBase目录下的新的web应用是否自动发布。缺省为true。这方面的更多信息参考应用自动发布

    backgroundProcessorDelay

    这个值代表在该host及其子容器(包括所有的wrappers)上调用backgroundProcess方法的延时,以秒为单位。如果延时值非负,子容器不会被调用,这意味着子容器使用自己的处理线程。如果该值为正,会创建一个新的线程。在等待指定的时间以后,该线程在Host及其子容器上调用backgroundProcess方法。Host使用后台处理进行与web应用实时发布有关的操作。如果没有指定,缺省值是-1,说明host依赖其所属的Engine的后台处理。

    className

    实现的Java类名。该类必须实现org.apache.catalina.Host接口。如果没有指定,使用标准实现(在下面定义)

    deployOnStartup

    这个标志表明这个host的web应用是否由host configurator 自动发布。缺省为true。这方面的更多信息参考自动应用发布。

    name

    虚拟主机的网络名称,也就是在DNS服务器上注册的名称。嵌套在Engine的所有Host中,必须有一个Host的名字与Engine的defaultHost属性相同。如果想为同一个虚拟主机指定多个网络名称,参考主机名别名。

     

    标准实现

    Host的标准实现是org.apache.catalina.core.StandardHost。它还支持如下的附加属性

    属性 描述
    debug

    与Engine相关联的Logger的调试信息的详细程度。数字越大,输出越详细。如果没有指定,缺省值为0。

    deployXML

    如果不想使用Context XML配置文件来发布web应用,设为false。同时也失去了利用manager应用程序安装web应用或者“.war”文件的能力(这些web应用或.war文件不在Host的配置基准目录$CATALINA_HOME/conf/[engine_name]/[host_name]下面)

    web应用使用catalina的安全许可发布,如果需要让不可信的用户管理web应用,这个值可以设为false。缺省为true。

    errorReportValveClass

    Host使用的错误报告valve的Java类名。这个valve的责任是输出错误报告。设置这个值可以定制Tomcat产生的错误页面的格式。这个类必须实现org.apache.catalina.Valve接口。如果没有指定,使用缺省值

    og.apache.catalina.valvees.ErrorReportValve.

    unpackWARs

    如果希望将位于appBase目录下的WAR文件解压缩成对应的目录结构,设为true。如果希望直接从WAR文件运行web应用,设为false。更多信息参考应用自动发布。

    workDir

    Host的web应用使用的临时目录的路径。每个应用都有自己的子目录,用于临时的读写。如果在Context中设置了workDir属性,它将会覆盖Host的workDir属性。如Servlet Specification中所述,通过servlet context的属性javax.servlet.context.tempdir,这个目录可以被servlet使用。如果没有指定,使用$CATALINA_HOME/work下面的合适的目录。

    嵌套组件

    可以在Host元素中嵌套一个或者多个Context元素,每个Context元素代表这个虚拟主机下的一个不同的web应用。同时,你可以嵌套一个DefaultContext元素,用来定义后续发布的web应用的缺省值

    可以在Host元素中选择嵌套一个DefaultContext元素,用来定义自动发布的web应用的缺省特性。

    下列元素可以嵌套在Host元素中,但至多只能嵌套一个实例:

    • Logger - 配置一个logger,用来接收和处理Host的所有日志消息,以及这个Host的所有Context的日志消息(除非被低一级的Logger配置覆盖)
    • Realm -配置一个realm,Realm的用户数据库以及用户角色被这个Host的所有Context共享(除非被低一级的Realm配置覆盖)
    专有特征
    访问日志

    正常情况下,运行web服务器会生成访问日志。访问日志以标准格式为每个请求输出一行信息。Catalina包含一个可选的Valve实现,可以用标准格式生成日志,还可以使用任意定制的格式。

    通过在Engine,Host或者Context中嵌套一个Valve元素,Catalina会为该容器处理的所有请求创建访问日志,如下所示:

    <Host name="localhost" ...>
      ...
      <Valve className="org.apache.catalina.valves.AccessLogValve"
             prefix="localhost_access_log." suffix=".txt"
             pattern="common"/>
      ...
    </Host>
    
    参考Access Log Valve,以获得更多配置属性的信息;
    应用自动发布

    如果使用标准的Host实现,当Catalina第一次启动时,如果deployOnStartup属性为true,tomcat会自动采取如下的步骤:

    • 假定$CATALINA_HOME/conf/[engine_name]/[host_name]目录中的任何XML文件都包含一个Context元素(以及它的相关的子元素),通常情况下,这个<Context>的docBase属性指向一个web应用目录的绝对路径,或者是WAR文件的绝对路径。
    • 如果WAR文件对应的目录不存在,则这个WAR文件会被自动展开,除非unpackWARs属性设为false。在重新发布更新后的WAR文件时,重新启动Tomcat之前一定要删除展开后的目录,这样更新后的WAR文件才会被重新展开(如果使能了auto deployer,它会自动完成这项工作)
    • application base目录下的任何子目录,如果包含/WEB-INF/web.xml文件,Tomcat认为这个一个展开后的web应用,会为这个目录自动产生一个Context元素,即使这个目录没有在conf/server.xml文件中出现。产生的Context会使用DefaultContext中的属性来配置。自动产生的Context的context路径是“/”后面跟上目录名,除非目录名是ROOT,这种情况下context路径是空字符串(“”);

    除了启动时候的自动发布以外,在Tomcat运行的时候,当新的XML 配置文件,WAR文件或者子目录(包含新的web应用)放到appBase目录下,或者当XML配置文件放到$CATALINA_HOME/conf/[engine_name]/[host_name]目录)的时候,该web应用被自动发布。auto deployer也负责跟踪web应用的如下变化:

    • 如果更新了WEB-INF/web.xml文件,会触发web应用的重载;
    • 如果WAR文件被更新,并且WAR文件已经展开,首先删除展开的web应用,然后发布更新的WAR文件;
    • 如果XML配置文件被更新,首先删除该应用(但是不删除任何展开以后的目录),然后发布相关的web应用
    主机名别名

    在许多服务器环境中,多个网络名称可能指向同一个IP地址(比如,www.mycompany.com和company.com都指向192.168.1.1)。正常情况下,每个网络名称应该在conf/server.xml中对应一个Host元素,每个Host元素有自己的一套web应用。

    但是,有些情况下,可能希望两个或者更多网络名称解析到同一个虚拟主机上,运行相同的一套web应用。这种情况的典型用途是公司网站。用户可以使用www.mycompany.com和company.com访问同样的内容和应用。

    通过在Host元素中嵌套一个或者多个Alias元素,可以完成上述功能。

     

    <Host name="www.mycompany.com" ...>
      ...
      <Alias>mycompany.com</Alias>
      ...
    </Host>
    

    为了使这个策略生效,所有的网络名称必须在DNS服务器登记,指向运行Catalina实例的同一台计算机。

     

    生命期Listeners

    如果一个Java对象需要知道Context什么时候启动,什么时候停止,可以在这个对象中嵌套一个Listener元素。该Listener元素必须实现了org.apache.catalina.LifecycleListener接口,在发生对应的生命期事件的时候,通知该Listener。可以按照如下的格式配置这样的Listener:

    <Host name="localhost" ...>
      ...
      <Listener className="com.mycompany.mypackage.MyListener" ... >
      ...
    </Host>
    
    注意,一个listener可以具有任意多的附加属性。属性名与JavaBean的属性名相对应,使用标准的属性命名方法。
    请求过滤器
    对每个发送到Engine,Host或者Context的请求,可以要求Catalina检查IP地址或主机名称。Catalina使用一系列配置好的“接受”或者“拒绝”过滤器对客户端的地址或者主机名进行检查,过滤器是按照正则表达式语法定义的,由Jakarta Regexp正则表达式库支持。不被接受的请求会返回一个HTTP“Forbidden”错误。下面是过滤器的定义。
    <Host name="localhost" ...>
      ...
      <Valve className="org.apache.catalina.valves.RemoteHostValve"
             allow="*.mycompany.com,www.yourcompany.com"/>
      <Valve className="org.apache.catalina.valves.RemoteAddrValve"
             deny="192.168.1.*"/>
      ...
    </Host>
    

     

    如果想知道过滤器支持的更多选项的信息,参考Remote Address Filter和Remote Host Filter

    单次登录(Single Sign On

    在许多环境尤其是门户环境下,对特定虚拟主机上的一套web应用,只希望对用户进行一次认证。这可以在Host元素中嵌套如下的元素完成:

    <Host name="localhost" ...>
      ...
      <Valve className="org.apache.catalina.authenticator.SingleSignOn"
             debug="0"/>
      ...
    </Host>
    

    单次登录根据如下规则运作:

    • 这个虚拟主机的所有web应用必须共享同一个Realm。在实际情况中,这意味着你可以在这个Host元素中嵌套Realm元素(或者是Engine元素),但不能在web应用对应的Context中嵌套Realm元素
    • 如果用户只访问这个虚拟主机上任意web应用的没有加保护的资源,他们不会被要求认证;
    • 一旦用户访问这个虚拟主机下的任意web应用的保护资源,用户会被要求认证。使用正在访问的web应用的login方法;
    • 一旦认证通过,与这个用户相关联的角色决定了它对所有的web应用的访问控制权限;而不需要对每个应用单独认证;
    • 一旦用户从某个web应用注销(比如,如果使用了基于表单的login,对应的session过期或者无效),用户在所有web应用的session都会失效;任何后续的对保护资源的访问会要求对用户重新认证;
    • 单次登录特征使用HTTP cookies传输令牌,将每个请求和用户身份联系起来,因此客户端必须支持cookies;
    用户Web应用

    许多web服务器会自动将以"~"和用户名开始的URI映射到用户主目录下的某个目录(通常为public_html)。在Catalina中,通过使用特殊的Listener元素,可以完成上述功能

    在利用/etc/password来标识有效用户的Unix系统下使用如下配置:

    <Host name="localhost" ...>
      ...
      <Listener className="org.apache.catalina.startup.UserConfig"
                directoryName="public_html"
                userClass="org.apache.catalina.startup.PasswdUserDatabase"/>
      ...
    </Host>
    

    在不使用/etc/password的服务器上,可以要求Catalina将指定的基准目录下的所有目录(比如c:\homes)看成是用户主目录:

    <Host name="localhost" ...>
      ...
      <Listener className="org.apache.catalina.startup.UserConfig"
                directoryName="public_html"
                homeBase=c:\Homes"
                userClass="org.apache.catalina.startup.HomesUserDatabase"/>
      ...
    </Host>
    

    如果某个名为craigmcc的用户的主目录已经设置好,通过使用如下URL,可以浏览它的内容:

    http://www.mycompany.com:8080/~craigmcc
    

     

    使用这个特征需要注意如下几个问题:

    • 每个用户web应用会使用该Host的DefaultContext元素定义的特征发布;
    • 包含多个Listener元素的实例也是有效的。但是,这只在你希望配置多个homeBase目录情况下才有意义;
    • 执行Catalina的用户名对每个用户的web应用目录以及它的所有内容必须有读的权限;
    posted @ 2006-02-16 17:05 java之海 阅读(3034) | 评论 (0)编辑 收藏

    首先在数据访问层读取一条记录并返回该类的Form

       if ("request".equals(mapping.getScope())) {

        request.setAttribute(mapping.getAttribute(), articleForm);
       } else {

        session.setAttribute(mapping.getAttribute(), articleForm);
       }
    上面的代码把Form放入Request并返回给客户端

    在界面显示的jsp中有如下声明

      <html:form action="/articleEdit" name="articleForm" type="com.xianeizhu.struts.form.ArticleForm" scope="request">
    ....
    <html:text property="title" />
    显示该Form的title属性


    scope="request"如果漏掉,会造成数据显示为空

    posted @ 2006-02-15 11:51 java之海 阅读(344) | 评论 (0)编辑 收藏
    CREATE TABLE <<table name>> AS SELECT * from <<old table>>
    posted @ 2006-02-14 09:19 java之海 阅读(190) | 评论 (0)编辑 收藏
    延迟初始化错误(ERROR LazyInitializer)是如何产生的?

    选自<<精通Hibernate:Java对象持久化技术详解>> 作者:孙卫琴 来源:www.javathinker.org
    如果转载,请标明出处,谢谢


    延迟初始化错误是运用Hibernate开发项目时最常见的错误。如果对一个类或者集合配置了延迟检索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它。如果在游离状态时才初始化它,就会产生延迟初始化错误。

    下面把Customer.hbm.xml文件的<class>元素的lazy属性设为true,表示使用延迟检索策略:

    <class name="mypack.Customer" table="CUSTOMERS" lazy="true">

    当执行Session的load()方法时,Hibernate不会立即执行查询CUSTOMERS表的select语句,仅仅返回Customer类的代理类的实例,这个代理类具由以下特征:

    (1) 由Hibernate在运行时动态生成,它扩展了Customer类,因此它继承了Customer类的所有属性和方法,但它的实现对于应用程序是透明的。
    (2) 当Hibernate创建Customer代理类实例时,仅仅初始化了它的OID属性,其他属性都为null,因此这个代理类实例占用的内存很少。
    (3) 当应用程序第一次访问Customer代理类实例时(例如调用customer.getXXX()或customer.setXXX()方法),Hibernate会初始化代理类实例,在初始化过程中执行select语句,真正从数据库中加载Customer对象的所有数据。但有个例外,那就是当应用程序访问Customer代理类实例的getId()方法时,Hibernate不会初始化代理类实例,因为在创建代理类实例时OID就存在了,不必到数据库中去查询。

    提示:Hibernate采用CGLIB工具来生成持久化类的代理类。CGLIB是一个功能强大的Java字节码生成工具,它能够在程序运行时动态生成扩展Java类或者实现Java接口的代理类。关于CGLIB的更多知识,请参考:http://cglib.sourceforge.net/。

    以下代码先通过Session的load()方法加载Customer对象,然后访问它的name属性:

    tx = session.beginTransaction();
    Customer customer=(Customer)session.load(Customer.class,new Long(1));
    customer.getName();
    tx.commit();

    在运行session.load()方法时Hibernate不执行任何select语句,仅仅返回Customer类的代理类的实例,它的OID为1,这是由load()方法的第二个参数指定的。当应用程序调用customer.getName()方法时,Hibernate会初始化Customer代理类实例,从数据库中加载Customer对象的数据,执行以下select语句:

    select * from CUSTOMERS where ID=1;
    select * from ORDERS where CUSTOMER_ID=1;

    当<class>元素的lazy属性为true,会影响Session的load()方法的各种运行时行为,下面举例说明。

    1.如果加载的Customer对象在数据库中不存在,Session的load()方法不会抛出异常,只有当运行customer.getName()方法时才会抛出以下异常:

    ERROR LazyInitializer:63 - Exception initializing proxy
    net.sf.hibernate.ObjectNotFoundException: No row with the given identifier exists: 1, of class:
    mypack.Customer

    2.如果在整个Session范围内,应用程序没有访问过Customer对象,那么Customer代理类的实例一直不会被初始化,Hibernate不会执行任何select语句。以下代码试图在关闭Session后访问Customer游离对象:

    tx = session.beginTransaction();
    Customer customer=(Customer)session.load(Customer.class,new Long(1));
    tx.commit();
    session.close();
    customer.getName();

    由于引用变量customer引用的Customer代理类的实例在Session范围内始终没有被初始化,因此在执行customer.getName()方法时,Hibernate会抛出以下异常:

    ERROR LazyInitializer:63 - Exception initializing proxy
    net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

    由此可见,Customer代理类的实例只有在当前Session范围内才能被初始化。

    3.net.sf.hibernate.Hibernate类的initialize()静态方法用于在Session范围内显式初始化代理类实例,isInitialized()方法用于判断代理类实例是否已经被初始化。例如:

    tx = session.beginTransaction();
    Customer customer=(Customer)session.load(Customer.class,new Long(1));
    if(!Hibernate.isInitialized(customer))
    Hibernate.initialize(customer);
    tx.commit();
    session.close();
    customer.getName();

    以上代码在Session范围内通过Hibernate类的initialize()方法显式初始化了Customer代理类实例,因此当Session关闭后,可以正常访问Customer游离对象。

    4.当应用程序访问代理类实例的getId()方法时,不会触发Hibernate初始化代理类实例的行为,例如:

    tx = session.beginTransaction();
    Customer customer=(Customer)session.load(Customer.class,new Long(1));
    customer.getId();
    tx.commit();
    session.close();
    customer.getName();

    当应用程序访问customer.getId()方法时,该方法直接返回Customer代理类实例的OID值,无需查询数据库。由于引用变量customer始终引用的是没有被初始化的Customer代理类实例,因此当Session关闭后再执行customer.getName()方法,Hibernate会抛出以下异常:

    ERROR LazyInitializer:63 - Exception initializing proxy
    net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

    posted @ 2006-02-09 16:39 java之海 阅读(194) | 评论 (0)编辑 收藏