1月6日——培训第38天


总结的一、二、三在培训日记的第35天…………

四、自定义标签的总结:
1、每个自定义标签都对应一个标签处理类,任何一个标签处理类都必须实现的一个接口是JspTag
2、总的来说,自定义标签可以分为三种,Tag、SimpleTag、Tag File (标签文件),Tag File实际中用的人很少
3、Tag分为三种,
(1)Tag:不处理标签体,只是直接将体的内容直接输出到界面。不能循环处理,它的生命周期doStartTag-》doEndTag
(2)IterationTag:不处理标签体,只是直接将体的内容直接输出到界面。但可以循环处理,它的生命周期:
    doStartTag-->doAfterBody-->doEndTag
    Jsp中提供了一个实现这个接口的实现类叫做TagSupport
(3)BodyTag: 处理标签体,并且可以循环处理。它的生命周期:doStartTag-->doInitBody-->doAfterBody-->doEndTag
   JSP中提供了一个实现这个接口的实现类叫做BodyTagSupport
4、返回值的类型:
SKIP_BODY----------------------doStartTag/doAfterBody
EVAL_BODY_INCLUDE--------------doStartTag
EVAL_BODY_BUFFERED-------------doStartTag (/doAfterBody)
EVAL_BODY_AGAIN----------------doAfterBody (/doStartTag)
SKIP_PAGE----------------------doEndTag
EVAL_PAGE----------------------doEndTag

注意:EVAL_BODY_BUFFERED和EVAL_BODY_AGAIN其实是一样的静态整型常量值,所以括号里面的虽然可以,但是不推荐。

5、SimpleTag标签,它的生命周期
   setJspContext-->setParent-->AttrSetter(所有属性的setter方法)--setJspBody>doTag
这里注意JspFragment代表的是不含有脚本元素的JSP代码片断,tld文件的元素必须设置为scriptless或者empty
当值为empty时,不能有标签体!!
 Jsp提供的实现类是SimpleTagSupport

6、Tag File 标签文件(一会儿下面再说)
7、TLD文件(Tag Library Descriptor),一般可以放置在/WEB-INF或者其任意的子目录中,当然放在其他的地方也是没有问题的,
   比如META-INF
8、taglib指令元素,uri和prefix,uri这里可以放置真实地址或者tld文件中的uri的一个虚拟地址


Tag File把标签处理类的代码转换为类似于jsp式的东西,就是对自定义标签的描述;相当于JSP是对Servlet的一种描述

五、表达式语言和JSTL(今天的主要内容)

=======================================================
EL ${}:常量、变量、函数、它们只能是以表达式的形式出现,目的是为了取代脚本表达式
标签做好后可以当作组件使用JUnit来进行测试,但是JSP页面是没有办法进行测试的………………

脚本片断可以用标签或是jsp动作来取代。

表达式语言中,
布尔型、整型、浮点型、字符串型和空值null五种常量类型,有数学操作符、关系操作符、
逻辑操作符、条件操作符、empty操作符、()操作符和[]操作符以及.操作符

保留字有16个,比如gt、or、and之类

出现在EL表达式中的变量,都会被当作存储在某个作用域中的一个属性,从小往大找,即从pageContext、
request、session、application的顺序去找

在JspContext类中有个findAttribute(String name)方法会去顺序找这四个作用域,

${a>b}其实就是先pageContext.findAttribute("a");找a里面存储的属性对象,然后再用相同的方法去找
b里面存储的属性对象。


RequestDispatcher.forward
PageContext.forward

上述三者在jsp页面中都可以使用,都是请求转发


${a=1} 这是不可以的,只能把作用域中的属性值给取出来,不可以给它赋值……
下面介绍EL表达式语言中的.操作符,可以通过点操作符来访问对象的属性,对于自定义的对象,
被访问的属性必须要定义对应的getter方法


   例:
   <%
 Map user = new HashMap();
 user.put("name","Gavin King");
 user.put("age", new Integer(34));
 pageContext.setAttribute("user",user);
   %>

   ${user.name}
   <%=user.get("name")%>
上述两句代码是等价的
--------------------------------------------
EL语言中的11种内置对象,它们和jsp中的9个内置对象没有任何关系,只是名字相近而已

作用域的四个内置对象:
pageScope、requestScope、sessionScope、applicationScope

pageContext也是EL内置对象之一。这个pageContext可以得到所有的Jsp中的内置对象!

param和paramValues也是EL内置对象,还有header和headerValues、Cookie和initParam!
-----------------------------------------------
pageContext有无参的getter方法可以取出作用域!!

如果
 <%
 Map user = new HashMap();
 user.put("name","Gavin King");
 user.put("age", new Integer(34));
 pageContext.setAttribute("user",user);
 request.setAttribute("user",new Integer(36));
 %>
//这时候如果直接使用${user.name}找的肯定是pageContext中的user属性
但是由于Integer中没有无参的getter方法,所以只能使用Integer的getClass方法
${requestScope.user.class} ,指明去请求作用域中去找user属性,
       这会打印出class java.lang.Integer,而不是36……
${requestScope.user} 这就返回的是36了!
${pageContext.request.class}  之所以能这么写是因为PageContext里面有getRequest方法!返回的是ServletRequest
       然后再调用getClass方法!getClass返回的是ServletRequest接口现在的实现类!
       pageContext隐式对象的好处就在于可以调用很多的无参的get方法,而且还可以得到所有的内置对象!!
${pageContext.request.characterEncoding} 这也是可以的(在之前记住要设好请求request的编码)。
${pageContext.request.contextPath} 这也没问题,只要是没有参数的getter方法就可以使用.操作符来访问!
${requestScope.contextPath} 注意这句话和上面的区别,是去请求作用域中找这个同名的属性
JSP:pageContext


${param.user} 是去找同名的参数,比如如果访问这个页面后面加上?user=Gavin ,就会得到Gavin
${paramValues.user[1]} (一般用在复选框中)

${header.accept} //返回accept报头的值

在web.xml中添加如下配置:

 index
 /index.jsp
 
  name
  Gavin
 


注意上面的是index页面的config隐式对象的参数取的时候<%=%>



 name
 Gavin

对于上面来说,${initParam.name} 返回Gavin
注意表达式语言的initParam隐式对象是针对的ServletContext中的initParam参数,也就是web.xml中的
定义的初始化参数!

点操作符使用特点:
1、如果点操作符施加在一个javaBean对象上面,则调用JavaBean对象属性的getter方法。
2、如果点操作符施加在一个Map对象上,则调用get方法
3、如果点操作符施加在作用域内置对象上面,则返回存储在这个作用域中的同名属性值
4、如果点操作符施加在pageContext内置对象上,则调用其相应的getter方法
5、如果点操作符施加在参数内置对象param或是paramValues上,则返回同名参数的值!
6、如果点操作符施加在请求报头的内置对象herder或headerValues上,则返回同名报头的值

==================================================

函数:

EL中的函数将映射到一个Java类中的公共而且静态的方法,这种映射是通过TLD文件来完成的

函数语法形式:ns:f(a1,a2……an)

例:新建一个类:
package tag ;

public class ElFunc
{
 public static String showHello(String name)//必须是公共静态的
 {
  return "Hello, " + name + "!" ;
 }
}

TLD文件中的配置

 showNameEl
 tag.ElFunc//指明方法的类
  //指明方法
  java.lang.String showHello(java.lang.String) //这里必须给类的全名
 

在jsp页面中使用taglib引入tld后,prefix是my
${my:showNameEl("Gavin")}  打印“Hello,Gavin!”

点操作符
1、点操作符施加在JavaBean对象上,则调用JavaBean对象属性的getter方法
2、如果点操作符施加在Map对象上,则调用get方法
3、如果点操作符施加在作用域内置对象上,则返回存储在这个作用域中的同名属性
4、如果点操作符施加在pageConext内置对象上,则调用其相应getter方法。
5、如果点操作符施加在参数内置对象上,则返回同名参数值
6、如果点操作符施加在请求报头内置对象上,则返回同名报头的值
------------------------------------------------------------------------

现在来看一下表达式语言的底层实现机制
javax.servlet.jsp.el包是用来解析EL表达式的
里面有两个接口,两个抽象类,容器Tomcat提供了ExpressionEvaluator和VariableResolver

request.setAttribute("user",new Integer(33));
ExpressionEvaluator ee = pageContext.getExpressionEvaluator();
VariableResolver vr = pageContext.getVariableResolver();
Integer result = (Integer)ee.evaluate("${requestScope.user+10}",Integer.class,vr,null);
//上面那个方法可以去查包里面的具体类,Integer.class是希望返回的具体的类
System.out.println(result); //得到43

其实表达式${requestScope.user+10}就是这么像上面那样解析出来的,这就是EL表达式的底层实现机制的简单介绍。
-------------------------------------------------
下面来作一个标签,达到这样一种效果:
  //test里面放置一个表达式,检测如果这个值为true的话,就执行标签体,如果不为true,就不执行标签体。
 //要求标签体中放置表达式语言也没有问题

package tag ;
public class ConditionTag extends SimpleTagSupport//它的生命周期只有一个doTag
{
 private boolean test ;
 public void setTest(boolean test)
 {
  this.test = test ;
 }
 public void doTag() throws JspException,IOException
 {
  if(test)
  {
   this.getJspBody().invoke(null); //直接将标签体弄进当前输出流里面去!不用别的代码了
  }
 }
}

tld文件:

 if
 tag.ConditionTag
 scriptless
 
  test
  yes
  yes
 



 

kfdjsljfs


//这其实就是JSTL核心标签库中的if标签…………

JSTL:JSP Standard Tag Library (JSP标准标签库)


作用:将var变量赋予值value,并且存储在作用域scope中去

上述标签如何实现呢?标签处理类的代码如下所示:

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.SimpleTagSupport;

public class setTag extends SimpleTagSupport{
 private String var ;
 private Integer value ;
 private String scope ;
 public String getScope() {
  return scope;
 }
 public void setScope(String scope) {
  this.scope = scope;
 }
 public Integer getValue() {
  return value;
 }
 public void setValue(Integer value) {
  this.value = value;
 }
 public String getVar() {
  return var;
 }
 public void setVar(String var) {
  this.var = var;
 }
 public void doTag() throws JspException, IOException {
  // TODO Auto-generated method stub
  //super.doTag();
  //System.out.println(this.getJspBody());
  //this.getJspBody().invoke(null);
  
  //PageContext是JspContext的子类!需要强制类型的转换…………
  /*System.out.println("参数名字符串"+var);
  System.out.println("参数值字符串"+value);
  System.out.println("作用域字符串"+scope);*/

  //想办法得到PageContext类,因为它可以和Jsp九大隐式对象通信!
  //而PageContext又正好是JspContext的子类,所以……
  PageContext p = (PageContext)this.getJspContext();
  JspWriter out = this.getJspContext().getOut(); 
  if("session".equals(scope))
  {
   p.getSession().setAttribute(var,value);
  }
  else if("request".equals(scope))
  {
   p.getRequest().setAttribute(var,value);
  }
  else if("application".equals(scope))
  {
   p.getServletContext().setAttribute(var,value);
  }
  else if("page".equals(scope))
  {
   p.setAttribute(var,value);
  }
  //out.println("<%"+scope+".setAttribute(/""+var+"/","+value+")%>");
  //注意:绝对不可以写成上面的样子!!如果写成上面的样子就相当于在查看源文件里面
  //直接嵌入到html里面了,也就是<%%>连同里面的代码会变成html源文件的一部分,完全
  //起不到jsp脚本代码的意义了。
 }

}


tld文件配置:


   set
   cn.itcast.setTag
   scriptless
   
    var
    yes
    true
   

   
    value
    yes
    true
   

   
    scope
    yes
    true
   

 


  jsp页面:
    <%
     Integer user = new Integer(34);
    %>
   

这样一来就可以在另一个页面通过${sessionScope.userhaha}得到34了。
注意上面的标签里面绝对不可以写成value="${user}"!!因为user一不是作用域中存的属性,
二不是javaBean,三不是Map,所以不行……
=====================================================


中午难得能和田老师一起吃饭,自己都没有想到…………虽然是老师,毕竟也是年轻人,共同话题还是有的,他身上感觉不到
太多的职业人的世故和老成,所以……呵呵,难得赵金良和他住的这么近,竟然没有主动去接触,可惜啊……中国人有的时候
不是很善于和别人沟通交际,这也是……没有办法的事情,换了我恐怕也一样吧,田老师的身体状况并不好,其实不是病什么
的,好像是气血方面有些不足,用中医的话说白了就是“气血不调”,如果一直讲课讲到下午的话可能有的时候声音会变小,而且
有的时候也好像不是很精神,田老师也意识到了这一点,并且在一直吃药,但是……始终不太见好转,我表姐也是差不多的
症状,但是要严重的多,她连多走一走都会有气无力的说不动话,……身体这东西有的时候很难说,对于搞IT的人,可能有的
时候更难说,当老师不容易……


=====================================================
下午介绍JSTL核心标签库……

JSTL就是一套自定义标签,所以需要标签处理类和TLD文件,也就是JAR包和tld文件
标签库共有5个:Core、XML、I18n(处理国际化)、Database、Functions
 前缀名依次为: c     x   fmt                sql      fn
http://java.sun.com/jsp/jstl/core(xml/fmt/sql/functions)

----------------------------------------
core标签:

老师写的set标签处理类:
public class VarSetTag extends SimpleTagSupport
{
 private String var ;
 private Object value ;
 private String scope = "page" ;

 setter、getter方法这里略
 public void doTag() throws JspException,IOException
 {
  //其实JspContext中的setAttribute(String name, Object value, int scope)
  //也可以,注意scope这里是常量,PageContext中定义了一些静态的常量
 
  int scopeValue = PageContext.PAGE_SCOPE //默认是page作用域
  PageContext pageContext = (PageContext)getJspContext();//对于这种方法,这句话是不必要的……
  if("request".equals(scope))
  {
   scopeValue = PageContext.REQUEST_SCOPE;
  }
  else if("session".equals(scope))
  {
   scopeValue = PageContext.SESSION_SCOPE;
  }
  else if("application".equals(scope))
  {
   scopeValue = PageContext.APPLICATION_SCOPE;
  }
  getJspContext().setAttribute(var,value,scopeValue);
 }

}
-------------------------------------

两种用途
1、设置变量值:
//如果不写scope的话,默认是存在页面作用域中!

  mumbojumbo

2、设置对象属性:


    ${param.color}
     //target表明一个cust对象中的address是一个javaBean,javaBean里面又个属性叫做city

例如:
package vo;

//注意下面的两段javaBean的getter和setter方法我都省略了!!
public class Address
{
 private String country ;
 private String city ;
}

public class Customer
{  
 private String name ;
 private Address address = new Address();//这个new Address()如果不写的话就错了!!不写的话就是null!
}

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

//其实target就是设置对象

     
     //由于Map是接口,所以必须得用type


//会在ss类里面存入一个键为name,值为ss的键值对,


${param.name}


可以${cust.address.city} ,所以没有标签

标签:

以前表达式语言在2.0版本以前是不可以在jsp页面直接使用的,这也是为什么
存在的原因,对现在来说,既然可以直接在jsp页面上使用表达式,那么这个也没有
必要使用的。
--------------------------------------------
流程控制标签:

条件标记

      This is your first visit. Welcome to the site!

没有标记体的语法形式:
16}" var=“result“/>
   必须要指定var属性。当test的内容被计算后,结果将存储在var所指的变量中,JSP页面就可以通过这个变量对结果进行访问了。

根据时间 显示不同的问候语,应该如何使用if标记来实现?

//下面的模拟了if、else if、代码
(注意后两者不可以单独的存在,而是只能够作为前者的标签体出现)

  
       whenBody1
  

  
       whenBody2
  

  
       whenBody3
  

  
       otherwiseBody
  

如果要实现if/then/else结果,则就采用如下的形式:

   
        No records matched your selection.
   

   
        ${count} records matched your selection.
   

-------------------------------------
循环结构:

有两种用法:
1、访问集合类型,例如:


 
    

 
${customer}

2、实现一个循环、指定循环的起始、终止及步长,例如:

    ${i}

上述标签模拟了for循环

可以被元素轮询的集合类型包括:
实现了java.util.Collection的类:List、LinkedList、ArrayList、Vector、Stack和Set。
实现了java.util.Map的类:HashMap、Hashtable、Properties、Provider和Attributes。
对象数组和基本数据类型数组。
实现了java.util.Iterator或java.util.Enumeration的类。


//循环变量i会以属性的方式存储在页面的作用域中!
 ${i}
 

//上面那种循环基本上用处不大

//真正有用的是集合的迭代处理
<%
 ArrayList a = new ArrayList();
 a.add("djkfsa");
 a.add("dfsjklafs");
 pageContext.setAttribute("b",a);
%>


 ${name}

==========================================================================
使用核心标签库建立留言板:
id                integer         主键、自增
title           varchar(200)
content           text
publish_time    datetime

//注意相应字段要设置中文编码GBK!!
只能够迭代集合类型,而且这个集合类型必须已经存储在作用域中了!所以应该先到Servlet中去,
让Servlet读出全部的数据然后放到集合里面去,存到request作用域中转发请求给jsp,就可以了。



 //因为上下文路径可能会发生变化,所以需要动态获得。

//注意list是个Servlet

Servlet代码:
先在server.xml中加上Context字段,里面的内容去Tomcat中拷贝,就像昨天做法一样。别忘了驱动程序要将驱动拷贝到
common/lib中去,这是全局类路径,Tomcat可见,这段Context中的内容相当于一个连接池,是由Tomcat去维护的

//引入javax.naming包
Connection conn = null ;
PreparedStatement pstmt = null ;
ResultSet rs = null ;
int page = 0 ;
int perPage = 10 ;

try
{
 page = Integer.parseInt(request.getParameter("page"));
 perPage = Integer.parseInt(request.getParameter("perPage"));
}
catch(NumberFormatException e1)
{
 page = 0 ;    //第一次访问页面的时候request中肯定什么属性也没有设置,所以会出现异常
 perPage = 10 ;
}
try
{
 Context ctx = new InitialContext();
 DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/data");
 conn = ds.getConnection();

 pstmt = conn.prepareStatement(select * from article limit ?,?);
 pstmt.setInt(1,page*perPage);
 pstmt.setInt(2,perPage);

 
 
 rs = pstmt.executeQuery();

 ArrayList articles = new ArrayList();
 while(rs.next())
 {
  Map map = new HashMap();
  map.put("id",new Integer(rs.getInt(1)));
  map.put("title",rs.getString(2));
  map.put("content",rs.getString(3));
  map.put("time",rs.getTimestamp(4));//SimpleDateFormat可以转换为想要的时间日期格式
  articles.add(map);
 }
 
 pstmt = conn.prepareStatement("select count(*) from articles");
 rs = pstmt.executeQuery();
 int totalPage = 0 ;
 if(rs.next())
 {
  totalPage = (rs.getInt(1) + perPage - 1)/perPage ;//求总页数
 }
 request.setAttribute("page",new Integer(page));  //放到request作用域中以便EL表达式使用!!
 request.setAttribute("totalPage", new Integer(totalPage));
 request.setAttribute("articles"articles);//放到request作用域中以便EL表达式使用!!
 request.getRequestDispatcher("/articleList.jsp").forward(request,response);//注意这里的绝对路径是绝对于上下文的!
 
}
catch(Exception ex)
{
 e.printStackTrace();
}
finally
{
 if(conn!=null)
 {
  conn.close();
  conn = null ;
 }
}

 

articleList.jsp:

<% taglib uri="/WEB-INF/c.tld" prefix="c"%>



 


  
   

     //相当于调用map的get("id")
    
    
   
  

  

//注意这里没有考虑首页和尾页的情况!!
   
  
 
${article.id}${article.title}${article.time}

   
    下一页
   

   
   上一页   

   
    上一页
   

   



还有一点需要说明,如果用户直接访问jsp页面的话就不好了,第一次会什么都显示不出来,所以可以考虑将jsp页面放入到
WEB-INF目录下,这样客户端就无法访问了,请求转发可以转发到WEB-INF里面的页面,而且include指令也可以包含那些
WEB-INF里面的页面,include动作也是可以包含WEB-INF

上面的代码并不完整…………
===========================================================
附上老师的源代码如下所示:


package servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

public class ListServlet extends HttpServlet {

 
 int perPage = 10;
 /**
  * The doGet method of the servlet.

  *
  * This method is called when a form has its tag value method equals to get.
  *
  * @param request the request send by the client to the server
  * @param response the response send by the server to the client
  * @throws ServletException if an error occurred
  * @throws IOException if an error occurred
  */
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

  doPost(request, response);
 }

 /**
  * The doPost method of the servlet.

  *
  * This method is called when a form has its tag value method equals to post.
  *
  * @param request the request send by the client to the server
  * @param response the response send by the server to the client
  * @throws ServletException if an error occurred
  * @throws IOException if an error occurred
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

  Connection conn = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  int page = 0;
  
  
  try {
   page = Integer.parseInt(request.getParameter("page"));
   perPage = Integer.parseInt(request.getParameter("perPage"));
  } catch (NumberFormatException e1) {
   page = 0;
  }
  
  
  try {
   Context ctx = new InitialContext();
   DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/data");
   conn = ds.getConnection();
   pstmt = conn.prepareStatement("select * from articles limit ?, ?");
   pstmt.setInt(1, page*perPage);
   pstmt.setInt(2, perPage);
   
   
   
   rs = pstmt.executeQuery();
   
   ArrayList articles = new ArrayList();
   while(rs.next()) {
    Map map = new HashMap();
    map.put("id", new Integer(rs.getInt(1)));
    map.put("title", rs.getString(2));
    //map.put("content", rs.getString(3));
    map.put("time", rs.getTimestamp(4));
    articles.add(map);
   }
   
   pstmt = conn.prepareStatement("select count(*) from articles");
   rs = pstmt.executeQuery();
   int totalPage = 0;
   if(rs.next()) {
    totalPage = (rs.getInt(1)+perPage-1)/perPage;
   }
   
   request.setAttribute("page", new Integer(page));
   request.setAttribute("totalPage", new Integer(totalPage));
   request.setAttribute("articles", articles);
   
   request.getRequestDispatcher("/WEB-INF/hiddenJsp/articleList.jsp").forward(request, response);
   
   
   
  } catch (NamingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally {
   try {
    if(conn!=null) {
     conn.close();
     conn = null;
    }
   } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }

}

 

 


articleList.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>



 
  
    My JSP 'articlList.jsp' starting page
   
   
   
   
   
   
   
   
 
 
 
   


     
       

         
         
          <%----%>
       
     
     
      
     
   
${article.id}${article.title}${article.time}

      

       
          上一页
       

       
          上一页
       

       
          下一页
       

       
          下一页
       

        每页显示
       
      

      

 

 


index.jsp:


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>



 
   
   
    My JSP 'index.jsp' starting page
   
   
   
   
   
   
   
   
 
 
 
    查看留言
 

================================================================================
================================================================================
================================================================================
晚上模仿老师的例子又弄了一下那个分页,一到分页这里我就有些磕磕绊绊的,再加上核心标签库,弄的我状态非常的差…………

index页面和老师的一样,就一句代码:

查看所有的留言

 

PageDisplayServlet:
读取数据库,取出第x页到第y页的记录并且存入ArrayList中

由于我使用的是DataSource数据源,所以需要配置server.xml:
   debug="5" reloadable="true" crossContext="true">


                 maxActive="100" maxIdle="30" maxWait="10000"
               username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/bbs?autoReconnect=true&useUnicode=true&characterEncoding=GBK"/>

 


package cn.itcast.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

public class PageDisplayServlet extends HttpServlet {
 
 int perPage = 3 ;    //每页的显示记录数
 int curPage = 1 ;    //当前的页数
 //之所以把这两个参数放到do方法外面是因为这两个方法可能会被留言板页面更改,比如我更改了每页显示的记录数,
 //但是我没有要显示下一页,这时候如果curPage=1是放到了do方法里面的话,则会被自动还原为1。而perPage如果
 //放到了do方法里面的话,每一次执行点击下一页或是上一页的时候,都会被还原为一次显示3条记录!

 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  request.setCharacterEncoding("GBK");
  response.setContentType("text/html;charset=GBK");
  PrintWriter out = response.getWriter();
  
  String per = request.getParameter("per");//由留言板的表单提交而来
  String cur = request.getParameter("curPage");//由留言板的链接提交而来
  //由Jsp请求得到当前页数的参数!!!
  
  int totalCount = 0;  //总记录数
  int pageSize = 0 ;   //总页数
  
  if(cur!=null)
  {
   curPage = Integer.parseInt(cur);
   //如果请求不为空说明是从留言板页面跳转来的。
  }
  if(per != null)
  {
   perPage = Integer.parseInt(per) ;
   //如果请求不为空则说明是从留言板页面跳转而来,需要重新设定每页显示的记录数目!
  }
  
  Connection conn = null ;
  PreparedStatement pstmt = null ;
  ResultSet rs = null ;
  ArrayList list = new ArrayList();
  
  
  
  try
  {
   Context ctx = new InitialContext();//注意这三行的数据源连接法!!!
   DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/TestDB");
   conn = ds.getConnection();
   
   //分页代码,取出第x条到第y条的记录!
   pstmt = conn.prepareStatement("select * from message limit ?,?");
   pstmt.setInt(1,(curPage-1)*perPage);
   pstmt.setInt(2,perPage);
   rs = pstmt.executeQuery();
   while(rs.next())
   {
    Map map = new HashMap(); //和老师一样使用map而不是javaBean来存储每行记录,这样就省得写一个新的类了。
    map.put("messageid",new Integer(rs.getInt(1)));
    map.put("messagetitle",rs.getString(2));
    map.put("messagetime",rs.getString(4));
    list.add(map);
   }
   
   pstmt = conn.prepareStatement("select count(*) from message");
   rs = pstmt.executeQuery() ;
   if(rs.next())
   {
    totalCount = rs.getInt(1);//得到总记录数;
   }
   pageSize = (totalCount + perPage - 1)/perPage;//得到总页数
   
   //下面三句代码把集合、总页数、当前页数分别存入request作用域,是为了
   //能够让表达式语言直接使用!
   request.setAttribute("list",list);
   request.setAttribute("page",new Integer(curPage));
   request.setAttribute("pageSize",new Integer(pageSize));
  }
  catch (NamingException e)
  {   
   e.printStackTrace();
   System.out.println("数据源DataSource获取连接出现异常");
  }
  catch (SQLException e)
  {   
   e.printStackTrace();
   System.out.println("与数据库交互时出现问题");
  }
  finally
  {
   try {
    if(rs!=null)
    {
     rs.close();
     rs = null ;
    }
    if(pstmt!=null)
    {
     pstmt.close();
     pstmt = null ;
    }
    if(conn!=null&&!conn.isClosed())
    {
     conn.close();
     conn = null ;
    }
   } catch (SQLException e) {    
    e.printStackTrace();
    System.out.println("关闭资源出现了问题");
   }
  }
  //动态获得jsp路径
  String contextPath = request.getContextPath();
  //System.out.println(contextPath+"/messageList.jsp");  
  //request.getRequestDispatcher(contextPath+"/messageList.jsp").forward(request,response);
  //请求转发给jsp
  request.getRequestDispatcher("/messageList.jsp").forward(request,response);
  //这里请再次注意请求转发的绝对路径指的是什么!我已经不只一次在这里栽跟头了!!!
  
 }

 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

  doGet(request,response);
 }

}


messageList.jsp:


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



 
   
   
    My JSP 'messageList.jsp' starting page
   
   
   
   
   
   
   
   
 
 
 
    

欢迎查看留言板


    
     
      
      
            
     
     
     
      //上面那个requestScope不加的话也可以,只要能够确认别的作用域里面没有同名属性就行!
      
      
      
     
     
     
      
     
    
帖子号帖子标题发贴时间
${message.messageid}${message.messagetitle}${message.messagetime}

       

        请输入您想显示的每页显示的记录数:
          
        
       

      

    
    
     
      


       首页  
       上一页  
       下一页  
       尾页  
       当前是第${page}页  
       一共${pageSize}页  
      


     

     
      


       首页  
       上一页  
       下一页  
       尾页  
       当前是第${page}页  
       一共${pageSize}页  
      


     

     
      


       首页  
       上一页  
       下一页  
       尾页  
       当前是第${page}页  
       一共${pageSize}页  
      


     

    

   
 

 

 

 

 

 

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