在稀里糊涂的过了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相关的
属性id:指明脚本变量名和属性名
class:指明javaBean所在的类
type:声明脚本变量的类型,type和class是父子类关系或是接口和实现类的关系
scope:设置作用域
beanName:
property:
param:
value:
组合形式:
1 name property=* :给同名的参数设置同名的属性的值
2 name property param :用参数名字找出参数的值然后再设置给属性
3 name property value :给属性赋值
设置属性时调用的是属性的setter方法,所以setter方法是必不可少的,可以没有属性,
但是不能没有setter方法!!
jsp:getProperty 取出作用域中对象的属性并打印出来
------------------------------------------------------
注意下述两种写法的区别!!
第一种情况的伪代码
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配置信息。
而前者可以过滤符合格式的目录,比如/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("
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(标签库的名字)是必须的
之后,如果想在jsp页面中使用这个自定义标签还需要<%@ taglib uri="/WEB-INF/first.tld" prefix="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
这样<%@ 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("
只有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("
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: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 ">
<%@ 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+"/";
%>
------------------------------------------
下面作一个比较的复杂的例子
动态的生成一个下拉菜单
下拉菜单的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 ;
}
}
<%@ 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文件:
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd ">
jsp页面:
<%@ page language="java" import="java.util.*, java.sql.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/first.tld" prefix="html" %>
--------------------------------------------------
--------------------------------------------------
今天的作业是自己重复上面的代码,并且加入后台的管理功能!
胡搞了半天终于搞出来了,现在来不及了,明天把代码贴上来吧……