总结的一、二、三在培训日记的第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文件的
当值为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页面的config隐式对象的参数取的时候<%=%>
对于上面来说,${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文件中的配置
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表达式的底层实现机制的简单介绍。
-------------------------------------------------
下面来作一个标签,达到这样一种效果:
//要求标签体中放置表达式语言也没有问题
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文件:
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文件配置:
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、设置变量值:
2、设置对象属性:
${param.color}
例如:
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!
没有标记体的语法形式:
必须要指定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}
//上面那种循环基本上用处不大
//真正有用的是集合的迭代处理
<%
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读出全部的数据然后放到集合里面去,存到request作用域中转发请求给jsp,就可以了。
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"%>
${article.id} | //相当于调用map的get("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" %>
${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+"/";
%>
index页面和老师的一样,就一句代码:
PageDisplayServlet:
读取数据库,取出第x页到第y页的记录并且存入ArrayList中
由于我使用的是DataSource数据源,所以需要配置server.xml:
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+"/";
%>
帖子号 | 帖子标题 | 发贴时间 |
---|---|---|
${message.messageid} | ${message.messagetitle} | ${message.messagetime} |
首页
上一页
下一页
尾页
当前是第${page}页
一共${pageSize}页
首页
上一页
下一页
尾页
当前是第${page}页
一共${pageSize}页
首页
上一页
下一页
尾页
当前是第${page}页
一共${pageSize}页