JSP使用

<jsp:useBean>元素使用全解

一. JSP动作元素useBean语法:

    <jsp:useBean
        id="beanInstanceName"
        scope="page | request | session | application"
        {
            class="package.class" |
            type="package.class" |
            class="package.class" type="package.class" |
            beanName="{package.class | <%= expression %>}"
type="package.class"
        }
        {
            /> |
            > other elements </jsp:useBean>
        }

二. JSP动作元素useBean使用示例:

<jsp:useBean id="cart" scope="session" class="session.Carts" />
<jsp:setProperty name="cart" property="*" />

<jsp:useBean id="checking" scope="session" class="bank.Checking" >
<jsp:setProperty name="checking" property="balance" value="0.0" />
</jsp:useBean>


三. JSP动作元素useBean执行步骤:

    <jsp:useBean>元素用来定位或初始化一个JavaBeans组件。<jsp:useBean>首
先会尝试定位Bean实例,如果其不存在,则会依据class名称(class属性指定)或序
列化模板(beanName属性指定)进行实例化。

    进行定位或初始化Bean对象时,<jsp:useBean>按照以下步骤执行。

步骤1: 尝试在scope属性指定的作用域使用你指定的名称(id属性值)定位Bean对
象;
步骤2: 使用你指定的名称(id属性值)定义一个引用类型变量;
步骤3: 假如找到Bean对象,将其引用给步骤2定义的变量。假如你指定类型(type
属性),赋予该Bean对象该类型;
步骤4: 假如没找到,则实例化一个新的Bean对象,并将其引用给步骤2定义的变
量。假如该类名(由beanName属性指定的类名)代表的是一个序列化模
板(serialized template),该Bean对象由java.beans.Beans.instantiate初始
化;
步骤5: 假如<jsp:useBean>此次是实例化Bean对象而不是定位Bean对象,且它有体
标记(body tags)或元素(位于<jsp:useBean>和</jsp:useBean>之间的内容,则执
行该体标记。

<jsp:useBean>和</jsp:useBean>之间经常包含<jsp:setProperty>,用来设置该
Bean的属性值。正如步骤5所描述的,该元素仅在<jsp:useBean>实例化Bean对象时
处理。假如Bean对象早已存在,<jsp:useBean>是定位到它,则体标记毫无用处。

我们可以使用<jsp:useBean>元素来定位或实例化一个JavaBean对象,但不能是
EJB。对于EJB,我们可以通过创建自定义标记来直接调用彧采用其它方式。

四. <jsp:useBean>元素各属性解析:

1. id="beanInstanceName"
       
        一个用来标识你指定作用域的变量。可以在JSP文件的表达式或脚本小应
        用程序中使用该变量名称。
       
        该名称大小写敏感,必须符合JSP页面中脚本语言的命名规则。假如你使
        用的是Java语言,则该名称遵守的是Java命名规范。假如该Bean对象已由
        其它<jsp:useBean>元素创建,则该值必须和实例化该Bean对象
        的<jsp:useBean>元素id属性值一致,才能实现定位到该Bean对象。
       
2. scope="page | request | session | application"
       
        Bean对象存在的作用范围,默认值为 page. 不同作用域解释如下:
       
       
        1) page: 你可以在<jsp:useBean>元素所在JSP页面或其静态包含页面使
        用该JavaBean对象,直到该页面发送响应回客户端或跳转(forwards)至其
        它页面。
               
        2) request: 你可以在处理同一个请求的任意一个页面使用该JavaBean对
        象,直到该页面发送响应回客户端或产生新的请求。你可以使用request
        对象访问该JavaBean对象,示例:
           request.getAttribute(beanInstanceName).
               
   3) session: 你可以在同一次会话的任意一个页面使用该JavaBean对象,该
JavaBean对象在整个会话期间一直存在。使用<jsp:useBean/>创建JavaBean对象的
页面的<%@page %>指令元素的session属性值必须设置为true;
               
   4) application: 你可以在创建该JavaBean对象的同一个应用的任意一个页面
使用该JavaBean对象,该JavaBean对象在整个应用期间一直存在。应用中任意一个
页面均可使用它。

3. class="package.class"
       
       
        从一个class实例化Bean对象,使用new关键字调用class的构造方法完
        成。
        该 class 必须不能是抽象,必须有一个 public、无参的构造器。包名和
        类名称大小写敏感。
       
4. type="package.class"

    用来指定该Bean对象的数据类型,假如既没有指定 class 或 beanBean, 没
有Bean对象能被实例化。包和类名称大小写敏感。

5. class="package.class" type="package.class"
       
       
        使用class属性指定的类实例化JavaBean对象,并声明其数据类型为type
        属性指定的类型;type属性值可和class属性值同,或为其超类、接口。
       
        class属性中所指定类名称必须不能为抽象的,必须包含有public,无参的
        构造方法。class和type属性所指定的包名,类名均大小写敏感。

6. beanName="{package.class | <%= expression %>}" type="package.class"

   使用java.beans.Beans.instantiate方法实例化beanName属性指定的类或序列
化模板对应的Bean对象,赋予JavaBean对象type属性指定的数据类型。
Beans.instantiate方法会检查beanName属性指定的名称是类名称还是序列化模板
的名称。假如该JavaBean对象已被序列化,则Beans.instantiate使用类加载器读
取序列化的内容,更多信息可参考JavaBeans.

beanName属性值要么是一个完整类名,要么是一个可以转化为完整类名的表达式。
用来传给Beans.instantiate方法。type属性值可和beanName属性值同,或为其超
类、接口。

beanName和type属性所指定的包名,类名均大小写敏感。

五. JSP动作元素useBean使用剖析:

对于<jsp:useBean>执行步骤的理解,我们可以通过阅读JSP转化成的Servlet源码
完成。以下给出二段示意代码, 可参阅之前步骤进行深化理解:

1) 通过beanName指定要实例化的JavaBean类名:

JSP源码 :
------------------------------------
-------
<jsp:useBean id="u" type="bean.User" beanName="bean.User"/>

JSP转译成Servlet的源码 :
------------------------------------
-------
      bean.User u = null;
      synchronized (_jspx_page_context) {
        u = (bean.User) _jspx_page_context.getAttribute("u",
PageContext.PAGE_SCOPE);
        if (u == null){
          try {
            u = (bean.User)
java.beans.Beans.instantiate(this.getClass().getClassLoader(),
"bean.User");
          } catch (ClassNotFoundException exc) {
            throw new InstantiationException(exc.getMessage());
          } catch (Exception exc) {
            throw new ServletException("Cannot create bean of class " +
"bean.User", exc);
          }
          _jspx_page_context.setAttribute("u", u,
PageContext.PAGE_SCOPE);
        }
      }

2) 通过class指定要实例化的JavaBean类名:

JSP源码 :
------------------------------------
-------
<jsp:useBean id="u" type="bean.User" class="bean.User"/>

JSP转译成Servlet的源码 :
------------------------------------
-------
      bean.User u = null;
      synchronized (_jspx_page_context) {
        u = (bean.User) _jspx_page_context.getAttribute("u",
PageContext.PAGE_SCOPE);
        if (u == null){
          u = new bean.User();
          _jspx_page_context.setAttribute("u", u,
PageContext.PAGE_SCOPE);
        }
      }

六. 注意几点:

1) class或beanName不能同时存在;它们用来指定实例化的类名称或序列化模板;
如果确信JavaBean对象已存在,class和beanName属性均可无须指定, 可只须指定
type属性。
2) class可以省去type独自存在,beanName必须和type一起使用;
3) class指定的是类名,beanName指定的是类名或序列化模板的名称;
4) class指定的类名必须包含public、无参的构造方法;在对象已实例化时,
beanName指定的名称可以为其接口、父类;
5) 如果JavaBean对象已存在,<jsp:useBean>只是用来定位JavaBean,则只需使用
type属性即可,class和beanName这时舍去不影响使用。
6) class或beanName指定的类名必须包括包名称,type可以省去包名,通过<%
@page import=""%>指定所属包亦可。
7) class通过new创建JavaBean对象;beanName通过
java.beans.Beans.instantiate初始化JavaBean对象。

 



page指令的属性:
language:jsp页面采用的语言,只有Java,默认为java
extends:jsp页面产生的Servlet继承的父类
import:导入包,多个包用逗号隔开
session:是否使用Session,默认值为true
buffer:指定输出流缓存大小,默认8kb
autoFlush:自动刷新缓冲区,默认为true
isThreadSafe:是否线程安全(是否能处理多个线程的同步请求)
info:指定jsp页面的相关信息
errorPage:指定出错时跳转的错误页面
contentType:指定MIME类型
isErrorPage:指定当前页面是否为错误处理页面,不能与errorPage同时为true
pageEncoding:页面编码,如”UTF-8″,”GBK”,默认为”"ISO-8859-1″.

page指令不能用于被jsp:include包含的文件,可以在同一页面中多次使用page指令,但是同一属性只能出现一次,除import外。



JSP内置对象page的使用
作者:Eamonn 发布时间:2011-11-05 13:02 访问:189 分类: JSP

  范围:在JSP中设置一个页的属性范围,必须通过pageContext完成。

  例:

  <body>

    //在同一个页面中,我们设置他得值

    <%

      pageContext.setAttribute("name", "姓名");

      pageContext.setAttribute("QQ", "1234567");

    %>

    //则在同一个页面中,我们取得到他的值:

    <%

      String name = (String) pageContext.getAttribute("name");

      String QQ = (String) pageContext.getAttribute("QQ");

    %>

    <h1>

      <%=name%>

    </h1>

    <h1>

      <%=QQ%>

    </h1>

  </body>

  

  好了,在这里强调一个重要概念:

  默认情况下,表示一个页面的保存范围,我们是用pageContext的。

  但实际上,四种属性范围,都是通过pageContext对象完成的。

  

  pageContext对象的补充:

  JSP中如果要想设置一个page范围的属性则一定使用pageContext对象,实际上对于整个JSP代码,所有的四种属性范围都是可以通过pageContext对象进行设置的,因为在此对象中的设置属性方法有两个:

  public void setAttribute(String name,Object attribute)   设置的属性默认为page范围

  public void setAttribute(String name,Object o,int scope) 可以指定属性的范围

   |- 在PageContext类中提供了以下几个常量:

   |- 表示page范围:public static final int PAGE_SCOPE

   |- 表示request范围:public static final int REQUEST_SCOPE

   |- 表示session范围:public static final int SESSION_SCOPE

   |- 表示application范围:public static final int APPLICATION_SCOPE

  下面通过pageContext对象设置一个request范围的属性

  

  RequestScopeDemo04.jsp:

  <%@page contentType="text/html;charset=GBK"%>

  <%@page import="java.util.*"%>

  <%

   // 设置两个属性

   pageContext.setAttribute("uname","HELLO",PageContext.REQUEST_SCOPE) ;

   pageContext.setAttribute("udate",new Date(),PageContext.REQUEST_SCOPE) ;

  %>

  <jsp:forward page="RequestScopeDemo02.jsp"/>

  这样在访问RequestScopeDemo04.jsp,跳转到RequestScopeDemo02.jsp之后,同样会得到同样的输出。



Jsp:useBean使用详解

分类: j2ee   1271人阅读  评论(0)  收藏  举报

<jsp:useBean>标签用来在jsp页面中创建一个Bean实例,定义语法如下:

一:<jsp:useBean>语法

<jsp:useBean id="id" scope="page|request|session|application" typeSpec/>

二:<jsp:setProperty>语法

 <jsp:setProperty name="beanName" propertyDetail />其中,propertyDetail可以是以下中的一个:

1,property="*"

2,property="propertyName" param="parameterName"

3,property="propertyName"

4,property="propertyName" value="property value"

三:<jsp:getProperty>语法

<jsp:getProperty name="beanName" property="propertyName"/>

程序例子:

一共有三个文件:TestBean.java,register.jsp,register.html

TestBean.java

package  com.jsp.ch3;

public   class  TestBean  {
    
private String userName;
    
private String password;
    
private int age;
    
public String getUserName() {
        
return userName;
    }

    
public void setUserName(String userName) {
        
this.userName = userName;
    }

    
public String getPassword() {
        
return password;
    }

    
public void setPassword(String password) {
        
this.password = password;
    }

    
public int getAge() {
        
return age;
    }

    
public void setAge(int age) {
        
this.age = age;
    }

}

register.html

< html >
  
< body >
    
< form  action ="register.jsp"  method ="post" >
        
< table >
            
< tr >
                
< td >
                    姓名:
< input  type ="text"  name ="userName" >
                
</ td >
            
</ tr >
            
< tr >
                
< td >
                    密码:
< input  type ="text"  name ="password" >
                
</ td >
            
</ tr >
            
< tr >
                
< td >
                    年龄:
< input  type ="text"  name ="age" >
                
</ td >
            
</ tr >
            
< tr >
                
< td >
                    
< input  type ="submit" >
                
</ td >
            
</ tr >
        
</ table >
    
</ form >
  
</ body >
</ html >

register.jsp

 

<% @ page language="java"  pageEncoding="gb2312" %>
< jsp:useBean  id ="user"  scope ="page"  class ="com.jsp.ch3.TestBean" />
< jsp:setProperty  name ="user"  property ="*" />
或者用以下,param可以不填写,其中param对应的是提交页面的表单name
< jsp:setProperty  property ="userName"  name ="user"  param ="userName" />
< jsp:setProperty  property ="password"  name ="user"  param ="password" />
< jsp:setProperty  property ="age"  name ="user"  param ="age" />
< html >
  
< body >  
      注册成功:
< br >
      
< hr >
      使用Bean的属性方法
< br >
      用户名: 
<% = user.getUserName() %> < br >
      密码: 
<% = user.getPassword() %> < br >
      年龄: 
<% = user.getAge() %> < br >
      
< hr >
      使用getProperty
< br >
      用户名:
< jsp:getProperty  name ="user"  property ="userName" />< br >
      密码:  
< jsp:getProperty  name ="user"  property ="password" />< br >
      年龄:  
< jsp:getProperty  name ="user"  property ="age" />
      客户端名称:
<% = request.getRemoteAddr()  %>
  
</ body >
</ html >


http://blog.csdn.net/ybyb14/article/details/1882693



2009-05-04 9:29

一个tag就是一个普通的java类,它惟一特别之处是它必须继承TagSupport或者BodyTagSupport类。这两个类提供了一些方法,负责jsp页面和你编写的类之间的交互,例如输入,输出。而这两个类是由jsp容器提供的,无须开发人员自己实现。换句话说,你只需把实现了业务逻辑的类继承TagSupport或者BodyTagSupport,再做一些特别的工作,你的类就是一个Tag。并且它自己负责和jsp 页面的交互,不用你多操心。

“特别的工作”通常有以下几个步骤:

[1]提供属性的set方法,此后这个属性就可以在jsp页面设置。以jstl标签为例 c:out value=""/,这个value就是jsp数据到tag之间的入口。所以tag里面必须有一个setValue方法,具体的属性可以不叫value。例如setValue(String data){this.data = data;}
这个“value”的名称是在tld里以attribute元素存在的。
取什么名字都可以,只需tag里提供相应的set方法即可。

[2]处理 doStartTag 或 doEndTag 。这两个方法是 TagSupport提供的。 还是以c:out value=""/为例,当jsp解析这个标签的时候,在“<”处触发 doStartTag 事件,在“>”时触发 doEndTag 事件。通常在 doStartTag 里进行初始化,流程选择操作,在 doEndTag 里后续页面输出控制。
[3]编写tld文件,就是把编写的tag组件的信息以mxl形式告诉容器,它才好以一定步骤解释tag组件
[4]在jsp页面导入tld。这样,你的jsp页面就可以使用自己的tag组件了。

通常你会发现自己绝大多数活动都集中在 doStartTag 或 doEndTag方法里,如果在服务器端处理标签中的正文或则是嵌套标签时的话,还是过问一下doAfterBody。
一个简单的例子:OutputTag

package test;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

public class OutputTag extends TagSupport {
private String name=null;
public void setName(String name) {
this.name = name;
}
public int doEndTag() throws JspException
{
try {
JspWriter out = pageContext.getOut();
out.print("Hello! " + name);
  } catch (Exception e) { throw new JspException(e); }
return EVAL_PAGE;
}
}

简要说明:
1 如何输出到jsp页面:调用JspWriter JspWriter out = pageContext.getOut();out.print......记住这个方法就可以了。
2 输出后如何作处理,函数会返回几个值之一。EVAL_PAGE 表示tag已处理完毕,返回jsp页面。还有几个值,例如 EVAL_BODY_AGAIN 和EVAL_BODY_INCLUDE等 跟流程控制有关.

编写tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>test</short-name>
<!--OutputTag-->
<tag>
<name>out</name>
<tag-class>test.OutputTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>

在WEB-INF下新建tlds文件夹,把这个文件取名为test.tld,放到tlds文件夹下。引用时的路径应该这样:WEB-INF\tlds\test.tld

关于tld的简单说明:
short-name:taglib的名称,也称为前缀。比如“c:out value=""/” 里的“c”
name:tag的名字。例如“c:out value=""/” 里的"out”,我们的类也取名为out,由于有前缀作区分,不会同其他库的同名tag组件混淆
tag-class:完整的tag组件路径,记着带包名
body-content:指tag之间的内容。例如c:out value="" ...... /c 起始和关闭标签之间就是body-content。由于没有处理body-content ,所以上面设为empty,如果是嵌套标签,或则是要在服务器端处理标签体的话,就是jsp了
“attribute”里的name:属性名字。例如c:out value=""/里的value。名字可任意取,只要类里提供相应的set方法即可。
required:是否必填属性。
rtexprvalue:是否支持运行时表达式取值就是是否可以<%=%>或则是${}方式传值。
这是tag的强大功能。
编写jsp页面

<%@ page language="java"%>
<%@ taglib uri="/WEB-INF/tlds/test.tld" prefix="test"%>
<html>
<body>
Test Tag: <test:out name="TEST"/>
</body>
</html>

启动服务器,如果一切按照上面步骤的话,就能看到 Test Tag: Hello! TEST 字样。最简单的tag就这么出来了。并不难,是不是?
------------------------------------------------------------------
Tag系列的Interface里定义的静态int,通过他们也能一窥tag组键的执行流程,这几个静态值分别是:
SKIP_BODY : 跳过了开始和结束标签之间的代码,一般是在doStartTag中使用
EVAL_BODY_INCLUDE :处理嵌套的标签,一般是在doStartTag中使用,由负责处理标签正文的tag接口提供
EVAL_BODY_BUFFERED :对包含的内容进行解析一般是在doStartTag中使用,由负责处理标签正文的bodyTag接口提供,目的是通知jsp容器作好读取正文的工作(创建一个body-content包装正文和获取存放操作结果的out对象,便于以后的操作和输出).
EVAL_BODY_AGAIN:处理标签正文,嵌套标签的iteratorTag接口的使用
SKIP_PAGE : 忽略剩下的页面,一般是在doEndTag中使用
EVAL_PAGE : 继续执行下面的页, 一般是在doEndTag中使用




2009-07-07 13:31

文章出处:http://book.csdn.net/bookfiles/230/10023010778.shtml

定制标签是为JSP定义新功能而创建的JSP标签。例如,假定有一个名为<temp:F>的定制标签,它将摄氏温度值转换为华氏温度值。可以在JSP中这样使用它:

这段代码显示为:

虽然这个简单例子展示了什么是定制标签,但在实际情况下,可以列出定制标签有用的很多理由。

l    因为它们大大削减了JSP中的代码重复,所以促进了代码复用。

l    因为可以避免使用scriptlet,所以它们使得JSP变得更具有可维护性。

l    因为它们消除了对更难读写的scriptlet的需要,所以它们的使用也简化了Web设计人员的工作。

l    它们是用来贯彻“关注点分离”原则(见第1章)的一个主要工具。大部分Web应用框架,包括Struts和JavaServer Faces,都基于这一理由来使用定制标签。

因为Struts广泛地使用了定制标签,所以理解如何创建和使用定制标签对于用好Struts会有莫大帮助。

4.1 定制标签基础

标签具有一个在JSP页面中定义的前缀(在前述的例子中,前缀是temp)和一个标签名(在前一例子中,是F),它们都是固定在标签的TLD(标签库描述文件)文件中的。

标签能够被用在JSP中之前,它必须在页面的开始处进行声明。例如,对于<temp:F>标签,其声明可能是:

我们将会在下一节分析这个声明。现在,只需注意到前缀是在JSP中被定义的即可。

注意   标签的前缀用来避免标签名字冲突。比如,如果必须通过相同的名字使用两个不同的标签(来自于不同的标签库),就可以给它们赋以不同的前缀,以示区别。因此,前缀具有很强的灵活性,甚至可以在每一个单独的JSP中分别定义它们。另一方面,标签名是不能随意改变的,它是在标签库描述文件中定义的。

标签也可能具有属性,例如:

最后,多个标签可以归集到一起,放入一个TLD文件之内,这也是该文件为何叫标签库描述文件的原因。我们接下来看一看典型的标签生命周期。

4.2 如何处理定制标签

假如有一个带有一个定制标签的JSP文件。它是如何转换为我们在屏幕上面看到的文本的?其实,当servlet容器第一次解析JSP的时候,它遇到定制标签,例如:

servlet容器就会期待并且寻找JSP页面中对应的taglib声明。例如:

在JSP中可能有多个这样类似的taglib声明。servlet通过匹配标签的前缀和taglib声明中的prefix属性来决定使用哪一个声明,如代码清单4-1所示。

代码清单4-1 具有taglib声明和定制标签的示例JSP

taglib声明只是简单地将一个前缀和一个URI(统一资源标识符)相联系,这里的URI是标签的TLD文件的逻辑路径。uri属性是逻辑性的,而不是实际路径,因为它指向的是标准的servlet配置文件web.xml中特定的配置项,而不是硬盘驱动器上的某个位置。

web.xml文件必须包含被uri属性指定的标签库的真实位置。在这里,web.xml中的相关信息被配置在一个<taglib>标签之中(见代码清单4-2)。

代码清单4-2 web.xml中的taglib配置

代码清单4-2中需要注意的是:

l    taglib-uri必须匹配在给定JSP文件中的taglib中声明的uri属性。

l    taglib-location必须包含TLD文件实际的相对路径。在前一个例子中,TLD文件是struts-bean.tld。

TLD文件的物理位置总是相对于Web应用程序的WAR文件的根目录(或者相对于servlet容器中webapps目录下的Web应用程序子目录)。因此,在代码清单4-2中,我们会看到TLD文件位于WEB-INF文件夹中,名为struts-bean.tld。

最后,TLD文件只是一份包含了描述库中标签之元数据的XML文档。这些元数据是:

l    标签的名称(在代码清单4-1中标签名称是write)。

l    标签的可选的和必需的属性,以及来自代码清单4-1中的属性。

l    处理标签的属性和主体部分以产生输出的Java处理器类。这些Java类通常被打包到Web应用程序的WEB-INF\lib文件夹的一个JAR文件中。

我们将会在实验课程中详细讨论TLD文件的核心细节。图4-1总结了定制标签的处理流程。

在最后一个步骤中,servlet容器调用Java标签处理器类中的特定函数,而该处理器类负责处理定制标签的输出。

可见,甚至最简单的定制标签的处理流程也稍微有些棘手。建议你重复阅读这一节,直到能够确信已掌握了所有细节之后再继续往下阅读。

图4-1 定制标签的处理流程

4.3 Java标签处理器类

把定制标签的主体和属性转变成HTML代码的实际工作,是由必须要实现的Java标签处理器类来完成的。

处理器类可以子类化一个或者两个基类,这取决于标签的需求。

如果定制标签没有主体部分,那么可以子类化javax.servlet.jsp.tagext.TagSupport。这个基础处理器类表达了没有主体的定制标签,但是它可能会有属性。

如果定制标签具有主体,那么必须子类化javax.servlet.jsp.tagext.BodyTagSupport。当然,使用BodyTagSupport并不意味着当它们在JSP中使用的时候,必须要有一个主体。实际上,必须实现一个额外的处理功能来处理标签的主体部分。

为简单起见,在接下来的内容中我们会主要关注BodyTagSupport。

注意   我在这里稍微歪曲了一下事实。事实上,不管定制标签是否有一个主体部分,都能子类化BodyTagSupport或TagSupport。只不过,BodyTagSupport有额外的方法能够让用户可以方便地读取标签的主体。TagSupport就没有这种能力。但是这种方便是有代价的,因为servlet容器必须做些额外工作而且要使用更多内存。这就解释了为什么定制标签没有主体部分的时候应该子类化TagSupport,且只是在必要的时候才使用BodyTagSupport。

还有一个额外的函数是doAfterBody(),它是在servlet容器读进标签的主体部分之后被调用的。这一函数也在读取标签主体部分时进行所有必要的处理,并且显示输出。标签必须返回一个名为EVAL_PAGE的标记,该标记是在BodyTagSupport中定义的。这个标记告诉servlet容器继续处理页面的其他部分。

标签处理器类必须满足的另一个需求是,它们必须具有与标签所支持的属性(attribute)相对应的getXXX和setXXX函数。

注意   换句话说,除了作为BodyTagSupport或者TagSupport的子类之外,处理器类还须是一个JavaBean,具有与标签所支持的属性(attribute)相对应的属性(property)。

例如,在代码清单4-1中,通过查看<bean:write>标签,就能推断出对应的Java处理器类具有函数getProperty()和setProperty()。代码清单4-3展示了这个原则。

代码清单4-3 <bean:write>标签的Java处理器类的部分代码

当包含了标签的JSP被载入后,servlet容器便调用所有必需的setXXX()函数,以便标签中的属性能够被标签的Java代码访问。再次以<bean:write>标签为例,在运行时,可以调用getProperty()函数,或者查看_property来读取<bean:write>标签的property属性值。

4.4 辅助类

为了使Java处理器类能做些有用的事情,比如读取一个标签主体部分的内容,或者写标签的输出,必须要了解两个辅助类。

第一个是javax.servlet.jsp.tagext.BodyContent,可以用它来读取标签的主体以及其他东西。函数getString()将标签的主体返回为一个字符串(假定它有一个主体)。如果已经子类化了BodyTagSupport,就可以通过调用在BodyTagSupport基类中已经实现的函数来得到一个BodyContent实例。

BodyContent也会给出一个Writer实例,通过它,可以写出标签经过转换后的主体部分的输出。调用BodyContent实例上的getEnclosingWriter()函数将会给出一个Writer的子类——明确地说,它是javax.servlet.jsp.JSPWriter的一个子类。

为了看清所有这些是如何工作的,请考虑一个简单的<message:write>标签,可以这样使用它:

我们需要将消息“Hello World!”显示为特定的字体颜色——在这里是红色。一个Java处理器类就实现了这个功能,如代码清单4-4所示。

代码清单4-4 <message:write>处理器类的实现

4.5 TLD文件

定制标签拼图中的最后一块是TLD(标签库描述符)文件。创建的每个标签都必须在一个TLD文件中声明,而且这一文件还必须连同标签的Java处理器类一起被部署。正如在前一节中所看到的,servlet容器知道在何处放置了TLD文件,因为已经在web.xml标准servlet配置文件中声明了路径。

注意   这一节主要是作为参考。如果你已经心痒痒地想要编写自己的定制标签,可以跳过这一节而继续实验4。

请看一下声明了先前开发的<message:write>标签的TLD文件,如代码清单4-5所示。

代码清单4-5 声明 <message:write>的TLD文件

可以看到,TLD文件只不过是一个XML文件。根标签是<taglib>,它包含一个或者多个<tag>标签,该元素用来声明定制标签。表4-1、表4-2和表4-3解释了TLD中的每个标签。注意每个<taglib>都必须包含一个或者多个<tag>声明。

表 4-1 TLD文件中的标签

标  签
含  义

taglib
TLD文件的根标签

tlibversion
此标签库的版本

jspversion
此标签库依赖的JSP版本。这里使用1.1

shortname
当在JSP中使用标签时,此标签库首选或者建议的前缀。当然可以完全忽略这个建议

tag
包含针对此标签库中的一个标签的元数据


表4-2 <tag>的子标签

标  签
含  义

name
标签名称

tagclass
Java标签处理器类的名称。注意这是处理器类的全限定名称,比如net.thinksquared.tags. MessageWriteTagHandler

bodycontent
此标签的主体部分的内容。使用JSP

attribute
包含了此标签的一个属性的元数据


表4-3 <attribute>的子标签

标  签
含  义

name
属性的名称。很明显它在该标签中必须是唯一的

required
指示该标签是必需的(true)或者可选的(false)


4.6 实验4:温度转换标签

在这个实验中,将会创建、部署和测试一个进行温度转换的定制标签。下面是一些主要需求规格:

l    标签库将只包含一个名为convert的标签,该标签有一个可选的属性。

l    可选属性to指示需要转换到的温度单位。

l    默认情况下,to属性的值是华氏温度。

l    转换是从摄氏温度到华氏温度或者开氏温度。

注意   在生产实现中,最好包括一些错误报告机制。

例如,下面的代码将100摄氏度转换为212华氏度:

而下面这些代码则将100摄氏度转换为373开氏度:

为了创建这个标签,必须做到以下几点:

(1) 准备开发目录和脚本;

(2) 编写Java标签处理器类;

(3) 编写TLD文件来描述标签;

(4) 编写JSP来测试定制标签;

(5) 修改web.xml来注册TLD文件;

(6) 将应用程序安装到Tomcat中。

4.6.1 步骤1:准备开发环境和脚本

(1) 在硬盘合适的地方创建一个Struts目录。

(2) 复制www.apress.com上的lab4.zip文件到这个Struts目录。

(3) 解压,请确保保留了原来的目录结构。

(4) 应该能够看到.\Struts\lab4\子目录。

(5) 在文本编辑器中打开.\Struts\lab4\compile.bat文件,并且修改PATH环境变量以便它指向JDK安装位置。

注意    在Windows XP、Windows ME或者Windows 2000中,系统内置了解压能力,但是系统解压的文件可能会加上一个额外的lab4目录到被解压的路径中。所以,compile.bat文件的路径可能变成是.\Struts\lab4\lab4\compile.bat。可以将文件夹向上移动,或者就放在那儿。编译脚本也能够正确运行。

单击compile.bat测试修改结果。应该不会得到任何错误,并且能够在.\Struts\lab4\目录中看到一个lab4.war文件。

接下来,我们提及的所有路径都是相对于.\Struts\lab4\的。

4.6.2 步骤2:编写Java标签处理器

(1) 在文本编辑器中打开文件.\src\Converter.java。

(2) 添加一个私有的字符串变量_to。这将对应于定制标签的to属性。

(3) 创建一个getTo()和setTo()方法来获得和设置_to的值。servlet容器将使用这些方法来通过属性(attribute)to的值获得/设置属性(property)_to的值。

(4) 完成doAfterBody()方法,使用上面所属的需求规格。需要使用辅助类来做这些工作(详见代码清单4-4)。

(5) 注意doAfterBody()必须返回整数值的标记EVAL_PAGE来指示JSP页面的剩余部分是否需要继续处理。

(6) 单击compile.bat进行编译工作。

4.6.3 步骤3:编写标签库描述文件

(1) 在文本编辑器中打开.\web\WEB-INF\lab4-converter.tld文件。

(2) 这是一个空的TLD文件,只包含强制的样板文件。在样板之后创建一个根<taglib>... </taglib>元素。

(3) 在<taglib>元素之内,插入一个适当的标签定义,把代码清单4-5作为一个参考。

4.6.4 步骤4:修改web.xml

web.xml是一个标准的servlet配置文件。每个Web应用程序,甚至空的Web应用程序都必须要有自己的web.xml文件。

注意   如果将TLD文件放到WEB-INF目录中,实际上完全不必在web.xml中声明它们。但是,为了完整起见,我们会这样做。

(1) 在文本编辑器中打开.\web\WEB-INF\web.xml文件。注意web目录仅存在于开发时。compile.bat脚本会将整个WEB-INF目录上移,并且删除web文件夹。

(2) web.xml文件包含了样板文本,后面跟了一个<webapp>标签。将代码清单4-6所示的标签插入<webapp>元素封装标签之内。

代码清单4-6 插入到web.xml的代码

注意   请注意在代码清单4-6中,路径分隔符是UNIX风格的斜线(/),而不是Windows风格的反斜线(\)。

4.6.5 步骤5:编写JSP

(1) 在文本编辑器中打开文件.\web\test.jsp。

(2) 在JSP中加入定制标签库的taglib声明。记住使用在web.xml中定义的URI。

(3) 放入相应的标签代码来测试convert标签。至少应该测试一下在本实验开头所给出的全部例子。

4.6.6 步骤6:部署和测试

(1) 如果Tomcat在运行,请停止它。

(2) 单击compile.bat。这将编译源代码,并且产生一个WAR文件lab4.war。

(3) 将WAR文件拖到Tomcat的webapps目录中。记住,如果想要重新部署lab4应用,必须删除在webapps目录下的原有子目录。

(4) 启动Tomcat。使用http://localhost:8080/lab4/进行测试工作。

如果在某处被卡住了,你可能想要参考本实验的答案。可以在www.apress.com上的lab4-answers.zip文件中找到答案。






一简介,

Pager-taglib,支持多种风格的分页显示。实际上她是一个Jsp标签库,为在JSP上显示分页信息而设计的一套标签,通过这些标签的不同的组合,会形成多种不一样的分页页面,风格各异,她自带的DEMO就有七种左右的分页风格,包括Google的分页风格。而需要订制自已的风格的分页页面也非常简单。
分页方式有两种:
一种是从Action中得到一个List,在页面上通过<pg:item>进行自动分页。
第二种是通过把 pageSize,pageNo两参数传给后台进行数据库分页。

我做两个Demo加以说明对比:

二、准备
把pager-taglib.jar放到lib目录下(仅此足亦,完全没必要改web.xml什么的,还有官方war包中的东西都可以不要)
Java代码 复制代码  收藏代码
  1. <%@ taglib uri="http://jsptags.com/tags/navigation/pager" prefix="pg" %>  
<%@ taglib uri="http://jsptags.com/tags/navigation/pager" prefix="pg" %>


三,jsp (第一种分页方案由<pg:item>自行分页 )

Java代码 复制代码  收藏代码
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>   
  2. <%@ taglib uri="/WEB-INF/tld/c.tld" prefix="c"%>   
  3. <%@ taglib uri="http://jsptags.com/tags/navigation/pager" prefix="pg" %>   
  4. <html>   
  5. <head></head>   
  6. <body>   
  7. <pg:pager    
  8. url="/PageAction.do"    
  9. index="half-full"  
  10. maxPageItems = "3"    
  11.     maxIndexPages="5"    
  12. isOffset = "<%=false%>"    
  13.     export = "pageOffset,currentPageNumber=pageNumber"    
  14.     scope = "request">   
  15.        
  16.  <table>     
  17.     <c:forEach items="${userlist}" var="user">   
  18.     <pg:item>   
  19.      <tr>   
  20.       <td height="39">${user.userId}</td>   
  21.       <td height="39">${user.username}</td>   
  22.       <td height="39">${user.password}</td>   
  23.      </tr>        
  24.     </pg:item>   
  25. </c:forEach>   
  26. </table>     
  27.   <pg:index>   
  28.     <center>   
  29.     <table border=0 cellpadding=0 width=10% cellspacing=0>   
  30.     <tr align=center valign=top>   
  31.     <td valign=bottom><font face=arial,sans-serif   
  32.       size=-1>Result Page: </font></td>   
  33.     <pg:prev ifnull="true">   
  34.       <% if (pageUrl != null) { %>   
  35.         <td align=right><A HREF="<%= pageUrl %>"><IMG   
  36.           SRC=http://www.google.com/nav_previous.gif alt="" border=0><br>   
  37.         <b>Previous</b></A></td>   
  38.       <% } else { %>   
  39.         <td><IMG SRC=http://www.google.com/nav_first.gif alt="" border=0></td>   
  40.       <% } %>   
  41.     </pg:prev>   
  42.     <pg:pages>   
  43.       <% if (pageNumber == currentPageNumber) { %>   
  44.         <td><IMG SRC=http://www.google.com/nav_current.gif alt=""><br>   
  45.         <font color=#A90A08><%=pageNumber%></font></td>   
  46.       <% } else { %>   
  47.         <td><A HREF="<%=pageUrl%>"><IMG   
  48.           SRC=http://www.google.com/nav_page.gif alt="" border=0><br>   
  49.         <%= pageNumber %></A></td>   
  50.       <% } %>   
  51.     </pg:pages>   
  52.     <pg:next ifnull="true">   
  53.       <% if (pageUrl != null) { %>   
  54.         <td><A HREF="<%=pageUrl%>"><IMG   
  55.           SRC=http://www.google.com/nav_next.gif alt="" border=0><br>   
  56.         <b>Next</b></A></td>   
  57.       <% } else { %>   
  58.         <td><IMG SRC=http://www.google.com/nav_last.gif alt="" border=0></td>   
  59.       <% } %>   
  60.     </pg:next>   
  61.     </tr>   
  62.     </table>   
  63.     </center>   
  64.   </pg:index>   
  65.   </pg:pager>   
  66. </body></html>  
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/tld/c.tld" prefix="c"%>
<%@ taglib uri="http://jsptags.com/tags/navigation/pager" prefix="pg" %>
<html>
<head></head>
<body>
<pg:pager 
url="/PageAction.do" 
index="half-full"
maxPageItems = "3" 
 	maxIndexPages="5" 
isOffset = "<%=false%>" 
    export = "pageOffset,currentPageNumber=pageNumber" 
    scope = "request">
    
 <table>  
 	<c:forEach items="${userlist}" var="user">
    <pg:item>
     <tr>
      <td height="39">${user.userId}</td>
      <td height="39">${user.username}</td>
      <td height="39">${user.password}</td>
     </tr>     
   	</pg:item>
</c:forEach>
</table>  
  <pg:index>
    <center>
    <table border=0 cellpadding=0 width=10% cellspacing=0>
    <tr align=center valign=top>
    <td valign=bottom><font face=arial,sans-serif
      size=-1>Result Page: </font></td>
    <pg:prev ifnull="true">
      <% if (pageUrl != null) { %>
        <td align=right><A HREF="<%= pageUrl %>"><IMG
          SRC=http://www.google.com/nav_previous.gif alt="" border=0><br>
        <b>Previous</b></A></td>
      <% } else { %>
        <td><IMG SRC=http://www.google.com/nav_first.gif alt="" border=0></td>
      <% } %>
    </pg:prev>
    <pg:pages>
      <% if (pageNumber == currentPageNumber) { %>
        <td><IMG SRC=http://www.google.com/nav_current.gif alt=""><br>
        <font color=#A90A08><%=pageNumber%></font></td>
      <% } else { %>
        <td><A HREF="<%=pageUrl%>"><IMG
          SRC=http://www.google.com/nav_page.gif alt="" border=0><br>
        <%= pageNumber %></A></td>
      <% } %>
    </pg:pages>
    <pg:next ifnull="true">
      <% if (pageUrl != null) { %>
        <td><A HREF="<%=pageUrl%>"><IMG
          SRC=http://www.google.com/nav_next.gif alt="" border=0><br>
        <b>Next</b></A></td>
      <% } else { %>
        <td><IMG SRC=http://www.google.com/nav_last.gif alt="" border=0></td>
      <% } %>
    </pg:next>
    </tr>
    </table>
    </center>
  </pg:index>
  </pg:pager>
</body></html>


四.标签讲解:从页面里可以看到,这里使用了几个标签

1、<pg:pager>,在这个标签库里就充当着一个领袖的作用,一切子标签都在它里面工作。就以上出现的参数进行解释一下:
items:数据的纪录数
maxPageItems:显示最多的纪录数/页
maxIndexPages:显示最多的分页数/次,如设为5的话,则会出现这样的情况 1 2 3 4 5 .或 3 4 5 6 7 这样的形式,其实她自带的DEMO都喜欢把页数展现出来排成一排。
isOffset:与pg:item配套使用
export:这个属性比较重要,文档也对此作好相对长篇幅的说明。这个属性是让标签给你暴露什么变量,当然这些变量是有选择的,如在Pager标签里,可以暴露出来的变量有pageOffset及pageNumber,即页码偏移量及页码。通过这两个变量名,可以在Jsp或Java里面从Request里获得。Export属性接受的值还有表达式,如currentPage=pageNumber表示,把pageNumber的值暴露出来,并赋给一个叫CurrentPage的变量,这个变量将被保存到Request中,在Jsp或Java中可以得到。
scope:咳。还需要讲么?

2、<pg:param>这个标签很有用,用来设置将要加入到URL的参数。使用Name属性指定即可。在这个Demo中我们还没有用的参数传递,下一个Demo你会看到它的用法。

3、<pg:index>这个标签说明分页条显示的内容,在这里你可以设置各种风格的分页显示方式,本例是google风格的分页条。
4,  <pg:prev> , <pg:pages>,<pg:next>这些标签都是导航标签顾名思义,你一看例子就明白了,我就不用讲了吧。

五,第二种分页方案
与页面自行分页不同的是还需要给后台传两个参数,
一个是pageNo(当前页数)
可以在每一个PageUrl后面都加了&pageNo=<%= pageNumber %>。让我们的URL带上页码的参数,这样程序可以拿到页码去查找所需要的数据,你可以去比较一下两Demo的代码。OK,另一个参数是pagesize,这个原本可以在url=”/PageAction.do?pagesize=5来做可是,<pg>标签不支持这样做它给我们提供了另一个传递变量的方法,对了就是我前面标签讲解中所提到过的标<pg:param>

Java代码 复制代码  收藏代码
  1. <pg:pager items="${totalRows} " url="/PageAction.do?pagesize=5"  
<pg:pager items="${totalRows} " url="/PageAction.do?pagesize=5"

这样传递参数不对,应该写成:
Java代码 复制代码  收藏代码
  1. <pg:pager items="${totalRows}" url="/PageAction.do"maxIndexPages="5">   
  2.  <pg:param name=" pagesize " value="5" />  
 <pg:pager items="${totalRows}" url="/PageAction.do"maxIndexPages="5">
  <pg:param name=" pagesize " value="5" />
另外由于不需要在页面分页所在<pg:param>要去调
再就是<pg:pager>要有items属性


六.以下是Demo代码

Java代码 复制代码  收藏代码
  1. <pg:pager    
  2.  items="${ totalRows }"  
  3.  url="/PageAction.do"  
  4. index="half-full"  
  5.  maxPageItems = "5"    
  6.  maxIndexPages="10" isOffset = "<%=false%>"    
  7.     export = "pageOffset,currentPageNumber=pageNumber"    
  8.     scope = "request">   
  9.  <pg:param name="pagesize"  value="5" />   
  10.        
  11.  <table align="center">     
  12. <c:forEach items="${userlist}" var="user">   
  13.   <!--pg:item-->   
  14.   <tr>   
  15.       <td height="39">${user.userId}</td>   
  16.       <td height="39">${user.username}</td>   
  17.       <td height="39">${user.password}</td>   
  18.      </tr>     
  19.    <!--/pg:item-->   
  20. </c:forEach>   
  21. </table>    
  22.  <pg:index>   
  23.     <center>   
  24.     <table border=0 cellpadding=0 width=10% cellspacing=0>   
  25.     <tr align=center valign=top>   
  26.     <td valign=bottom><font face=arial,sans-serif   
  27.       size=-1>Result Page: </font></td>   
  28.     <pg:prev ifnull="true">   
  29.       <% if (pageUrl != null) { %>   
  30.         <td align=right><A HREF="<%=pageUrl%>&pageNo=<%=pageNumber%>"><IMG   
  31.           SRC=http://www.google.com/nav_previous.gif alt="" border=0><br>   
  32.         <b>Previous</b></A></td>   
  33.       <% } else { %>   
  34.         <td><IMG SRC=http://www.google.com/nav_first.gif alt="" border=0></td>   
  35.       <% } %>   
  36.     </pg:prev>   
  37.     <pg:pages>   
  38.       <% if (pageNumber == currentPageNumber) { %>   
  39.         <td><IMG SRC=http://www.google.com/nav_current.gif alt=""><br>   
  40.         <font color=#A90A08><%= pageNumber %></font></td>   
  41.       <% } else { %>   
  42.         <td><A HREF="<%=pageUrl%>&pageNo=<%=pageNumber%>"><IMG   
  43.           SRC=http://www.google.com/nav_page.gif alt="" border=0><br>   
  44.         <%=pageNumber%></A></td>   
  45.       <% } %>   
  46.     </pg:pages>   
  47.     <pg:next ifnull="true">   
  48.       <% if (pageUrl != null) { %>   
  49.         <td><A HREF="<%=pageUrl%>&pageNo=<%=pageNumber%>"><IMG   
  50.           SRC=http://www.google.com/nav_next.gif alt="" border=0><br>   
  51.         <b>Next</b></A></td>   
  52.       <% } else { %>   
  53.         <td><IMG SRC=http://www.google.com/nav_last.gif alt="" border=0></td>   
  54.       <% } %>   
  55.     </pg:next>   
  56.     </tr>   
  57.     </table>   
  58.     </center>   
  59.   </pg:index>   
  60.   </pg:pager>  
<pg:pager 
 items="${ totalRows }"
 url="/PageAction.do"
index="half-full"
 maxPageItems = "5" 
 maxIndexPages="10" isOffset = "<%=false%>" 
    export = "pageOffset,currentPageNumber=pageNumber" 
    scope = "request">
 <pg:param name="pagesize"  value="5" />
    
 <table align="center">  
<c:forEach items="${userlist}" var="user">
  <!--pg:item-->
  <tr>
      <td height="39">${user.userId}</td>
      <td height="39">${user.username}</td>
      <td height="39">${user.password}</td>
     </tr>  
   <!--/pg:item-->
</c:forEach>
</table> 
 <pg:index>
    <center>
    <table border=0 cellpadding=0 width=10% cellspacing=0>
    <tr align=center valign=top>
    <td valign=bottom><font face=arial,sans-serif
      size=-1>Result Page: </font></td>
    <pg:prev ifnull="true">
      <% if (pageUrl != null) { %>
        <td align=right><A HREF="<%=pageUrl%>&pageNo=<%=pageNumber%>"><IMG
          SRC=http://www.google.com/nav_previous.gif alt="" border=0><br>
        <b>Previous</b></A></td>
      <% } else { %>
        <td><IMG SRC=http://www.google.com/nav_first.gif alt="" border=0></td>
      <% } %>
    </pg:prev>
    <pg:pages>
      <% if (pageNumber == currentPageNumber) { %>
        <td><IMG SRC=http://www.google.com/nav_current.gif alt=""><br>
        <font color=#A90A08><%= pageNumber %></font></td>
      <% } else { %>
        <td><A HREF="<%=pageUrl%>&pageNo=<%=pageNumber%>"><IMG
          SRC=http://www.google.com/nav_page.gif alt="" border=0><br>
        <%=pageNumber%></A></td>
      <% } %>
    </pg:pages>
    <pg:next ifnull="true">
      <% if (pageUrl != null) { %>
        <td><A HREF="<%=pageUrl%>&pageNo=<%=pageNumber%>"><IMG
          SRC=http://www.google.com/nav_next.gif alt="" border=0><br>
        <b>Next</b></A></td>
      <% } else { %>
        <td><IMG SRC=http://www.google.com/nav_last.gif alt="" border=0></td>
      <% } %>
    </pg:next>
    </tr>
    </table>
    </center>
  </pg:index>
  </pg:pager>










ServletRequest.getRequestDispatcher
2011-07-10 16:14
转载自 sunshine666666
最终编辑 sunshine666666

getRequestDispatcher

publicRequestDispatcher getRequestDispatcher(java.lang.String path)

这是javax.servlet.ServletRequest下的一个public成员函数。

(Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path. A RequestDispatcher object can be used to forward a request to the resource or to include the resource in a response. The resource can be dynamic or static. )

episode:
它返回一个RequestDispatcher对象,在JDK的文档里是这样定义RequestDispatcher对象的:[Defines an object that receives requests from the client and sends them to any resource (such as a servlet, HTML file, or JSP file) on the server.]
RequestDispatcher对象从客户端获取请求request,并把它们传递给服务器上的servlet,html或jsp。
它的方法很easy,只有两个:

1.voidforward(ServletRequestrequest,ServletResponseresponse)

一看就明白,这是用来传递request的,可以一个Servlet接收request请求,另一个Servlet用这个request请求来产生response。request传递的请求,response是客户端返回的信息。forward要在response到达客户端之前调用,也就是 before response body output has been flushed。如果不是的话,它会报出异常。

例:
request.getRequestDispatcher("smserror.jsp").forward(request,response);

2.voidinclude(ServletRequestrequest,ServletResponseresponse)
Includes the content of a resource (servlet, JSP page, HTML file) in the response.
The included servlet cannot change the response status code or set headers; any attempt to make a change is ignored.这个是用来记录保留request和response,以后不能再修改response里表示状态的信息了,如http head呀,其实保留这个有什么用呢,........thinking...........

ok,继续我们的正题。getRequestDispatcher(String)可以得到一个RequestDispatcher对象,那我们就可以用它来动态的调用我们想要的调用的Servlet,jsp等;而参数String,就是那个你要调用的Servlet或JSP的名称,它可以是相对路径(如前例),也可以是绝对路径,如果你在前面加上“/”。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

福海鑫森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值