1月3日——培训第35天

在稀里糊涂的过了4天之后,已经是2007年了,希望自己在07年能够比06年的时候明白一些,不要总是成天晕晕糊糊的……
对了,还有一点忘了说了,不知为何,我挺怕写分页的……

----------------------------------------------------
2006年JavaWeb总结

一、Servlet
1、两个接口Servlet和ServletConfig
Servlet接口代表在容器上运行的实例,ServletConfig接口代表Servlet在web.xml中的配置信息。
ServletConfig是通过init方法传入Servlet里面的

2、两个类GenericServlet和HttpServlet
前者与协议无关,实现了Servlet和ServletConfig接口,HttpServlet继承了GenericServlet。GenericServlet有两个
init方法,一个是有参的,一个是无参的,我们重写的时候如果覆盖的话,只需要覆盖无参的init方法,如果非要覆盖有参的init
方法,那么需要在里面的第一行写上super.init(config)才可以,因为有参的init方法是给容器调用的,所以父类中的逻辑必不可少。
HttpServlet有两个service方法和七个do方法,get、post、head、trace、options、put、delete,重写的时候只需要重写
do方法即可。

二、JSP
1、模板和元素(Template和Element)
模板会被原封不动的翻译成out.println("")被写到输出流中去
2、元素分为三类
(1)脚本元素
a、脚本片断  <% %>
b、脚本声明  <%!%>
c、脚本表达式<%= %>
脚本片断会被直接翻译到service方法里面,所以必须符合java语法形式;
脚本声明(可以是属性、内部类、内部接口、静态或是非静态代码块、方法)会被翻译到service方法以外但是在类的内部,
脚本表达式会被直接翻译到out.print()里面去
(2)指令元素:下指令给容器的翻译器,所以不会翻译到Servlet代码中去
<%@ %>
a、page     <%@page %>
import
pageEncoding:设置容器翻译这个jsp页面时候的编码方式
contentType:设置响应的报头,用于让浏览器根据响应的报头选择对应的编码
isErrorPage:设置当前的页面是否是错误处理页面,如果是的话,JSP的9大隐式对象之一的exception就可以用了
errorPage:实质上是利用forward方法,将异常存在请求作用域中,然后传到错误处理页面之后给exception
isELIgnored:默认值是false,是可以使用EL表达式的。
session:默认值就是true,默认可以使用session

b、include <%@include file=" "%>
包含进来的文件可以是任何扩展名,在包含的时候统一会以文本的形式来打开。JSP规范中使用扩展名“.jspf”(jsp fragment)
包含进来的时候可能会出现乱码,需要指明包含文件的编码方式,需要在包含的文件中加上<%@ page pageEncoding="GBK"%>
就可以了。被包含进来后再统一的被加入到翻译中

作用就是加上统一的页面头和尾

c、taglib
作用:引入一个自定义标签

(3)动作元素
a、与JavaBean相关的
本来就被翻译到service方法的里面,所以不可能到service方法外边去;另一个作用是在指定的作用域中存储一个属性。
属性id:指明脚本变量名和属性名
class:指明javaBean所在的类
type:声明脚本变量的类型,type和class是父子类关系或是接口和实现类的关系
scope:设置作用域
beanName:

name:
property:
param:
value:
组合形式:
1 name property=*     :给同名的参数设置同名的属性的值
2 name property param :用参数名字找出参数的值然后再设置给属性
3 name property value :给属性赋值
设置属性时调用的是属性的setter方法,所以setter方法是必不可少的,可以没有属性,
但是不能没有setter方法!!

jsp:getProperty   取出作用域中对象的属性并打印出来
------------------------------------------------------
注意下述两种写法的区别!!


   //仅在第一次创建的时候才会调用setProperty方法
 

第一种情况的伪代码
User a = (User)session.getAttribute("a");
if(a==null)
{
 a = new User();
 session.setAttribute("a",a);
}

setProperty(a) ;//设置a中的对应属性

第二种情况中的伪代码
User a = (User)session.getAttribute("a");
if(a==null)
{
 a = new User();
 session.setAttribute("a",a);
 setProperty(a) ;
}
也就是说第二种情况只是在对象初始化的时候才被调用setProperty方法,也就是setProperty方法
仅仅调用一次!

第一种情况的setProperty会调用多次
----------------------------------------------------------
b、与流程相关的动作元素


RequestDispatcher.forward
     .include


c、参数相关

3 内置对象和作用域
pageContext:PageContext
request:HttpServletRequest
session:HttpSession
application:ServletContext
page : Object

out:JspWriter
response:HttpServletResponse
exception:Throwable
config:ServletConfig

作用域都有getAttribute、setAttribute、removeAttribute和getAttributeNames


4、表达式语言EL

三、监听器和过滤器
(1)监听器
监听三个作用域,除了session外,每个作用域都有两个事件(生命周期和属性的增删改),session有三个事件(多了钝化和激活事件),
所以共有7个监听器

(2)过滤器
必须要实现Filter接口,这个接口中定义的可以声明生命周期的方法有三个:init、doFilter和destroy
这里面有一个FilterChain,里面只有一个方法叫做doFilter(ServletRequest req,ServletResponse rep)
该方法用于将资源转到下一个过滤链或是目标资源。还有一个FilterConfig是在init中传给Filter的,和Servlet
一样,里面记录了Filter的xml配置信息。

 
 


 
 或者(注意一般使用前者,后者只能过滤一个特定的servlet,
 而前者可以过滤符合格式的目录,比如/con/*)               */

--------------------------------------------------------------
四 自定义标签(今天要讲的内容)

标签的组成:

 body(标记体)


无标签体,直接闭合


jsp就是namespace,useBean就是tagname,id和class就是attribute

标签最终肯定要翻译成为Servlet的,也就是最终肯定会是一段java的代码,所以sun在定义的时候让自定义的标签
和一个类关联起来,所以在标签翻译的过程中是去调用一个类中的对应方法

当标签开始、结束、标签体开始和结束的时候容器都会调用对应的方法。

所有有关自定义标签的接口都在javax.servlet.jsp.tagext中,tagext就是tagextension

我们如果写一个标签的话,该标签一定要和一个类关联起来,这个类叫做标签处理类tag Handler Class,首先要把这个类做出来。

JspTag也是个空接口,属于类型安全的一个接口,它的子接口中有Tag,里面有doEndTag、doStartTag、release、getParent、setParent等

现在实现一个简单的标签,标签作用仅仅是打印出一句话而已:

新建一个Web工程叫做tag,在src中建一个类cn.itcast.tag.FirstTag

public class FirstTag implements Tag
{
 private PageContext pageContext ;
 private Tag parent ;
 public void setPageContext(PageContext arg0)
 {
  this.pageContext = arg0;       //是容器调用的方法,传入页面上下文
 }

 public void setParent(Tag arg0)
 {
  this.parent = arg0;   //容器调用,传入父标签
 }

 public Tag getParent()
 {
  return this.parent ;
 }

 public int doEndTag() throws JspException
 {
  return EVAL_PAGE ;
 }

 public int doStartTag() throws JspException
 {
  JspWriter out = pageContext.getOut();
  try
  {
   out.println("

This is my first tag!!

");
  }
  catch(IOException e)
  {
   throw new JspException(e);
  }
  //如果想处理标签体的话,返回EVAL_BODY_INCLUDE给容器
  return EVAL_BODY_INCLUDE; //或者 return Tag.EVAL_BODY_INCLUDE;
 }
}


EVAL_BODY_INCLUDE:处理体到当前的输出流中,会原封不动的将标签体的内容输出到页面上来而不作任何的处理
EVAL_PAGE:继续处理这个页面
SKIP_BODY:跳过标签体
SKIP_PAGE:跳过剩下的页面

现在要将标签和标签处理类关联起来!这时候需要使用标签描述文件TLD来关联两者
TLD是Tag Library Descriptor 的简写。
TLD的作用就是将一个标签和一个标签处理类关联起来,TLD文件应该存储在WEB-INF目录中或者其任意子目录中才行。
因为它属于配置文件,如果不放在WEB-INF中,会被客户端访问到!

新建一个XML文件first.tld,从schema创建,选择jsptaglibrary-2.0
在taglib中,tlib-version(版本,一般填写2.0)和short-name(标签库的名字)是必须的

2.0
my

 first
 cn.itcast.tag.FirstTag
 JSP

 

之后,如果想在jsp页面中使用这个自定义标签还需要<%@ taglib uri="/WEB-INF/first.tld" prefix="my"%>

然后就可以执行下面的代码了
  //first是tld文件中的标签的名字,my是指令中定义的前缀名
 HELLO!!! //由于返回了EVAL_BODY_INCLUDE,所以HELLO!!!会原封不动的输出!如果doStartTag方法中返回的是
   //SKIP_BODY,那么这个HELLO!!!不会出现

 WORLD! //如果doEndTag方法中返回的不是EVAL_PAGE,而是SKIP_PAGE的话,那么这个WORLD!也不会出现。

------------------------------------------------------------------------------------------------
taglib代表的是一个库,在一个库中可以放多个tag元素,包含多个标签,short-name其实是库的名字,
tag中的name是要在jsp页面中使用的,配合taglib指令中的prefix

jsp页面解析的时候,是先根据prefix去找tld文件,然后找到对应的tag里面的name,然后去找标签处理类

可以通过在short-name元素下加上下面这行语句来配置一个虚拟的uri
http://www.itcast.cn/tag
这样<%@ taglib uri="http://www.itcast.cn/tag" prefix="dd"%>
就可以做到使用虚拟的地址了,如果没有在标签处理文件tld中加上uri元素的话,上面的uri中就必须得写上真实的物理地址

 

但是如果要在标签中加上属性,该如何去作呢?
1、在标签处理类中加入与标签属性同名的属性
2、为该属性添加getter和setter方法
3、在tld文件中注册属性

先调用setParent,然后是setPageContext,最后是属性的setter方法!
public class FirstTag implements Tag
{
 private PageContext pageContext;
 private Tag parent ;
 private String clor = "black";

 public String getColor()
 {
  return color ;
 }

 public void setColor(String color)
 {
  if(color!=null&&color.length()!=0)
   this.color = color ;
 }

 public int doStartTag() throws JspException
 {
  JspWriter out = pageContext.getOut();
  try
  {
   out.println("

This is my tag!!

");
  }
  catch(IOException e)
  {
   throw new JspException(e);
  }
  //如果想处理标签体的话,返回EVAL_BODY_INCLUDE给容器
  return EVAL_BODY_INCLUDE; //或者 return Tag.EVAL_BODY_INCLUDE;
 }
}



 
 
 
 
  color
  false  //该属性是否必须
  true //动态赋值Run Time Expression Value  
 

 只有rtexprvalue赋值为true的时候,">才可以使用!

-------------------------------------------------------------
演示代码如下:

package cn.itcast;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

public class FirstTag implements Tag {

 private PageContext pageContext ;
 private Tag parent ;
 private String size ;
 private String color ;
 
 public String getColor() {
  return color;
 }

 public void setColor(String color) {
  this.color = color;
 }

 public String getSize() {
  return size;
 }

 public void setSize(String size) {
  this.size = size;
 }

 public int doEndTag() throws JspException {
  // TODO Auto-generated method stub
  JspWriter out = pageContext.getOut();
  try {
   out.println("

");        //在标签结束的时候闭合p和font标签!来起到把标签体的内容改变字体和颜色的作用
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return FirstTag.EVAL_PAGE;
 }

 public int doStartTag() throws JspException {
  // TODO Auto-generated method stub
  JspWriter out = pageContext.getOut();
  try {
   out.println("

"); //让p和font在doEndTag中去闭合,这样就能把体的内容设置字体和颜色了!
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return FirstTag.EVAL_BODY_INCLUDE;
  
 }

 public Tag getParent() {
  // TODO Auto-generated method stub
  return this.parent;
 }

 public void release() {
  // TODO Auto-generated method stub
  System.out.println("Bad Luck! Chummy!!!");
 }

 public void setPageContext(PageContext arg0) {
  // TODO Auto-generated method stub
  this.pageContext = arg0 ;
 }

 public void setParent(Tag arg0) {
  // TODO Auto-generated method stub
  this.parent = arg0 ;
 }
 
}



xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd ">
  2.0
  my
 
   first
   cn.itcast.FirstTag
   JSP
   
    color
    false
    true
   

   
    size
    false
    true
   

 

 


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/lib/FirstTld.tld" prefix="my"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>



 
   
   
    My JSP 'index.jsp' starting page
   
   
   
   
   
   
   
   
 
 
 
    hahahaha!!!
    hehehehe!!!
 

------------------------------------------
下面作一个比较的复杂的例子
动态的生成一个下拉菜单

下拉菜单的HTML语法形式:

数据库里面要存储value和标签体中的映射,保证能够动态的从数据库中读取内容来生成一个下拉菜单

新建一个degree表(里面有id和name两个字段,注意name要设置成gbk编码)
里面有学历,但是随着时代的变迁,学历也会相应的变化,所以我们自然需要通过数据库的改变而动态的改变前台,
也就是只要改变数据库,网站前台的显示全部会相应的变化,所以只需要一个控制台让管理员可以更改这张表就可以
让前台的学历全部改变

完全可以通过select * 先把全部记录读到结果集里面去,然后循环结果集,通过jsp页面中的脚本就可以实现了
源代码如下:

 

之后就可以通过只更改数据库来改变这个下拉菜单了

其实应该有一个管理的后台来通过页面的方式改变数据库中的表,由此来达到改变下拉列表菜单的目的。

---------------
但是这个代码由于过多的使用了脚本代码,所以导致重用的不方便,如果能够做成一个标签来实现上述功能的话,
重用效果就非常非常的好了,直接拿过来就可以使用了。

下面就来将其封装到标签里面
目标:

//valueCol指的是id,textCol指的是name,dondition是让我们可以根据条件来显示对应的内容
public void SelectTag implements Tag
{
 private PageContext pageContext ;
 private Tag parent ;
 
 private String name ;
 private String table ;
 private String valueCol = "id" ;
 private String textCol = "name" ;
 private String condition = null ;

 以上5个属性还要加上getter和setter方法!这里暂时省略!
 public String getColor() {
  return color;
 }

 public void setColor(String color) {
  this.color = color;
 }

 public String getSize() {
  return size;
 }

 public void setSize(String size) {
  this.size = size;
 }

 public int doEndTag() throws JspException {
  // TODO Auto-generated method stub
  
  return FirstTag.EVAL_PAGE;
 }

 public int doStartTag() throws JspException {
  // TODO Auto-generated method stub
  Connection conn = null ;
  PreparedStatement pstmt = null ;
  ResultSet rs = null ;
  JspWriter out = pageContext.getOut();
  try
  {
   Class.forName("com.mysql.jdbc.Driver");
   conn = DriverManager.getConnection("jdbc:mysql:///j2ee?useUnicode=true&characterEncoding=gbk","root","root");
   String sql = "select " + valueCol+"," + textCol + " from " + table ;
   sql = (condition==null) ? sql : sql+" where " + condition ; //注意字符串的+不应该这么作,应该用StringBuffer的append,这样效率
   System.out.println(sql);         //会明显的提高!
   pstmt = conn.prepareStatement(sql);
   rs = pstmt.executeQuery();

   out.println("");
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
  finally
  {
   if(conn!=null)
   {
    conn.close();
    conn=null ;
   }
  }
  return FirstTag.EVAL_BODY_INCLUDE;
  
 }

 public Tag getParent() {
  // TODO Auto-generated method stub
  return this.parent;
 }

 public void release() {
  // TODO Auto-generated method stub
 
 }

 public void setPageContext(PageContext arg0) {
  // TODO Auto-generated method stub
  this.pageContext = arg0 ;
 }

 public void setParent(Tag arg0) {
  // TODO Auto-generated method stub
  this.parent = arg0 ;
 }

}



 select
 
 
  name
  yes
  true
 

 


<%@ taglib uri="/WEB-INF/first.tld" prefix="html" %>


------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
老师的源代码:

标签处理类:
package cn.itcast.tag;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

public class SelectTag implements Tag {

 private PageContext pageContext;

 private Tag parent;

 private String name;

 private String table;

 private String valueCol = "id";

 private String textCol = "name";

 private String condition = null;

 public String getCondition() {
  return condition;
 }

 public void setCondition(String condition) {
  this.condition = condition;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getTable() {
  return table;
 }

 public void setTable(String table) {
  this.table = table;
 }

 public String getTextCol() {
  return textCol;
 }

 public void setTextCol(String textCol) {
  this.textCol = textCol;
 }

 public String getValueCol() {
  return valueCol;
 }

 public void setValueCol(String valueCol) {
  this.valueCol = valueCol;
 }

 public int doEndTag() throws JspException {
  // TODO Auto-generated method stub
  return 0;
 }

 public int doStartTag() throws JspException {
  // TODO Auto-generated method stub
  Connection conn = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  JspWriter out = pageContext.getOut();
  
  try {
   Class.forName("com.mysql.jdbc.Driver");
   conn = DriverManager.getConnection(
     "jdbc:mysql:///j2ee?useUnicode=true&characterEncoding=gbk",
     "root", "root");
   String sql = "select "+valueCol+","+textCol+" from "+table;
   sql= (condition==null) ? sql : sql+" where " +condition;
   System.out.println(sql);
   pstmt = conn.prepareStatement(sql);
   rs = pstmt.executeQuery();
   
   out.println("");
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    if (conn != null) {
     conn.close();
     conn = null;
    }
   } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  return 0;
 }

 public Tag getParent() {
  // TODO Auto-generated method stub
  return parent;
 }

 public void release() {
  // TODO Auto-generated method stub

 }

 public void setPageContext(PageContext arg0) {
  // TODO Auto-generated method stub
  pageContext = arg0;
 }

 public void setParent(Tag arg0) {
  // TODO Auto-generated method stub
  parent = arg0;
 }

}


tld文件:


        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd ">
  2.0
  my
  http://www.itcast.cn/tag
 
     first
     cn.itcast.tag.FirstTag
     JSP
    
       color
       false
       true
    

    
 

 
 
     select
     cn.itcast.tag.SelectTag
     JSP
    
       name
       yes
       true
    

    
       table
       yes
       true
    

    
       valueCol
       no
       true
    

    
       textCol
       no
       true
    

    
       condition
       no
       true
    

    
 

 

jsp页面:


<%@ page language="java" import="java.util.*, java.sql.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/first.tld" prefix="html" %>


 
   
    My JSP 'index.jsp' starting page
   
   
   
   
   
   
   
   
 
 
 
  
 

--------------------------------------------------
--------------------------------------------------
今天的作业是自己重复上面的代码,并且加入后台的管理功能!

胡搞了半天终于搞出来了,现在来不及了,明天把代码贴上来吧……

 

 

 

 


 

你可能感兴趣的:(四个月的编程培训经历)