二、前台
1、不带条件的查询
[
1
]
实现Dao方法:getPageList
()
、getTotalItemNum
()
◆在BookDao中写接口方法
/**
* 获取在指定条件下的分页数据
* @param pageNo 不能使用pageCondition返回的pageNoStr,要使用经过Page对象纠正的
* @param pageSize
* @param pageCondition
* @return
*/
List
<
Book
>
getPageList
(
int
pageNo
,
int
pageSize
,
PageCondition pageCondition
);
/**
* 带条件的查询
* @param pageCondition
* @return 返回在指定的条件下一共有多少条记录
*/
int
getTotalItemNum
(
PageCondition pageCondition
);
◇此时需要更改Dao
:
/**
* 获取单一值的接口方法
* @param connection
* @param sql
* @param params
* @return
*/
<
V
>
V getSingleValue
(
Connection connection
,
String sql
,
Object
...
params
);
◇DaoImpi中实现该接口方法:
@Override
public
<
V
>
V getSingleValue
(
Connection connection
,
String sql
,
Object
...
params
)
{
V v
=
null
;
try
{
v
=
(
V
)
runner
.
query
(
connection
,
sql
,
new
ScalarHandler
(),
params
);
}
catch
(
SQLException e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
return
v
;
}
[
2
]
实现Page类
package
com
.
atguigu
.
bookstore
.
fun
;
import
java
.
util
.
List
;
/**
* 封装分页信息的类
* @author Phenix
*
* @param <T>对应具体的实体类
*/
public
class
Page
<
T
>
{
//代表当前页码
private
int
pageNo
;
//页面上的数据
private
List
<
T
>
list
;
//每页显示的数据数量
public
static
final
int
PAGE_SIZE
=
3
;
//总记录数
private
int
totalItemNum
;
//总页数
private
int
totalPageNum
;
public
Page
(
String pageNoStr
,
int
totalItemNum
)
{
//先获取总记录数,以计算总页数
this
.
totalItemNum
=
totalItemNum
;
//计算总页数
this
.
totalPageNum
=
(
totalItemNum
%
PAGE_SIZE
==
0
)
?
totalItemNum
/
PAGE_SIZE
:
totalItemNum
/
PAGE_SIZE
+
1
;
//对pageNoStr进行类型转换
pageNo
=
1
;
try
{
pageNo
=
Integer
.
parseInt
(
pageNoStr
);
}
catch
(
NumberFormatException e
)
{
/*如果转换失败则保持默认值*/
}
//限定pageNo的有效范围
if
(
pageNo
<
1
)
{
pageNo
=
1
;
}
if
(
pageNo
>
totalPageNum
)
{
pageNo
=
totalPageNum
;
}
}
public
List
<
T
>
getList
()
{
return
list
;
}
public
void
setList
(
List
<
T
>
list
)
{
this
.
list
=
list
;
}
public
int
getPageNo
()
{
return
pageNo
;
}
public
int
getTotalItemNum
()
{
return
totalItemNum
;
}
public
int
getTotalPageNum
()
{
return
totalPageNum
;
}
public
boolean
isHasPrev
()
{
return
pageNo
>
1
;
}
public
boolean
isHasNext
()
{
return
pageNo
<
totalPageNum
;
}
public
int
getPrevNo
()
{
return
pageNo
-
1
;
}
public
int
getNextNo
()
{
return
pageNo
+
1
;
}
}
[
3
]
实现与分页相关的Service层代码
◇BookService中添加如下接口方法:获取book类的分页信息
Page
<
Book
>
getBookPage
(
String pageNoStr
);
◇在BookServiceImpi中实现该方法
@Override
public
Page
<
Book
>
getBookPage
(
PageCondition pageCondition
)
{
int
totalItemNum
=
bookDao
.
getTotalItemNum
(
pageCondition
);
Page
<
Book
>
page
=
new
Page
<>(
pageCondition
.
getPageNoStr
(),
totalItemNum
);
//这里,pageNo必须使用Page类纠正过的,不能使用pageCondition中的pageNoStr
List
<
Book
>
list
=
bookDao
.
getPageList
(
page
.
getPageNo
(),
Page
.
PAGE_SIZE
,
pageCondition
);
page
.
setList
(
list
);
return
page
;
//返回book类的分页信息
}
◆在client
.
jsp请求
<
iframe src
=
"client/BookClientServlet?method=getPage"
name
=
"targetFrame"
></
iframe
>
◆BookClientServlet中进行转发
protected
void
getPage
(
HttpServletRequest request
,
HttpServletResponse response
)
throws
ServletException
,
IOException
{
String pageNoStr
=
request
.
getParameter
(
"pageNo"
);
Page
<
Book
>
page
=
bookService
.
getBookPage
(
pageNoStr
);
WebUtils
.
myForward
(
request
,
response
,
"/client/book/bookList.jsp"
,
"page"
,
page
);
}
◆在bookList
.
jsp中接收数据
$
{
page
.
list
}
[
4
]
页面
(
文本框输入数字跳转页面
)
① 给文本框加一个Id 属性:
<
input id
=
"pageCode"
class
=
"inpType"
type
=
"text"
name
=
"pageNo"
/>
②导入jquery:
<
script type
=
"text/javascript"
src
=
"script/jquery-1.7.2.js"
></
script
>
【已经加过base标签】
③书写JS代码:
版本一:可以容错,因为Page类内置了容错校验
<
script type
=
"text/javascript"
>
$
(
function
(){
$
(
"#pageCode"
).
change
(
function
(){
//去掉前后空格
var pageCode
=
$
.
trim
(
this
.
value
);
//判断用户输入的页码是否为数字
if
(
isNaN
(
pageCode
)){
//如果不是将文本框置空,并停止函数的执行
this
.
value
=
""
;
return
false
;
}
//如果是数字,则跳转到指定的页码
var url
=
"${pageContext.request.contextPath }/"
+
"client/BookClientServlet?method=getPage&pageNo="
+
pageCode
;
window
.
location
.
href
=
url
;
});
});
</
script
>
2、在首页显示真实的分类数据
①创建ClientServlet
,
用于跳转到前台页面
,
跟实体类无关,和前台页面相关
②修改index
.
jsp中的代码
<
jsp
:
forward page
=
"client/ClientServlet?method=toClientUI"
></
jsp
:
forward
>
③在toClientUI
()
方法中获取数据库分类列表数据,跳转到client
.
jsp显示
public
class
ClientServlet
extends
BaseServlet
{
private
static
final
long
serialVersionUID
=
1L
;
private
CateService cateService
=
new
CateServiceImpl
();
protected
void
toClientUI
(
HttpServletRequest request
,
HttpServletResponse response
)
throws
ServletException
,
IOException
{
List
<
Category
>
cateList
=
cateService
.
getCateList
();
WebUtils
.
myForward
(
request
,
response
,
"/client/client.jsp"
,
"cateList"
,
cateList
);
}
}
注意:修改web
.
xml将ClientServlet注册一下。
<
servlet
>
<
display
-
name
>
ClientServlet
</
display
-
name
>
<
servlet
-
name
>
ClientServlet
</
servlet
-
name
>
<
servlet
-
class
>
com
.
atguigu
.
bookstore
.
servlet
.
client
.
ClientServlet
</
servlet
-
class
>
</
servlet
>
<
servlet
-
mapping
>
<
servlet
-
name
>
ClientServlet
</
servlet
-
name
>
<
url
-
pattern
>/
client
/
ClientServlet
</
url
-
pattern
>
</
servlet
-
mapping
>
④修改client
.
jsp 中的分类列表
<
li
>
全部分类
</
li
>
<
c
:
forEach items
=
"${cateList }"
var
=
"category"
>
<
li
><
a href
=
"#"
>
$
{
category
.
cateName
}</
a
></
li
>
</
c
:
forEach
>
⑤后台中跳转到前台页面的超链接也要跟着修改
<
a href
=
"client/ClientServlet?method=toClientUI"
>
进入前台
</
a
>
3、★带条件的查询★重点★
难点:查询条件时有时无,要做到适配不同的情况
①查询条件包括
pageNo页码
minPrice 价格区间最小值
maxPrice 价格区间最大值
cateId 分类Id
②将查询条件封装为PageCondition类
(
1
)
为每个查询条件设置默认值
pageNo 页码,默认值:1,最终还是交给Page类纠正
minPrice 默认值:0
maxPrice 默认值:Integer
.
MAX_VALUE
cateId 默认值:null为了避免有可能产生的歧义,所以应声明为Integer类型
(
2
)
在构造器中,获取String类型的参数,进行类型转换,若任何一个条件数据转换失败则保持默认值
(
3
)
提供getXxx
()
方法
代码如下:
public
class
PageCondition
{
// (1)pageNo 页码 声明为String类型是为了直接交给Page类的构造器
private
String pageNoStr
=
"1"
;
// (2)minPrice 价格区间的最小值 默认值的作用是在页面没有传入该参数时仍然可以查询
private
int
minPrice
=
0
;
// (3)maxPrice 价格区间的最大值
private
int
maxPrice
=
Integer
.
MAX_VALUE
;
// (4)cateId 分类ID
private
Integer cateId
=
null
;
public
PageCondition
(
String pageNoStr
,
String minPriceStr
,
String maxPriceStr
,
String cateIdStr
)
{
this
.
pageNoStr
=
pageNoStr
;
//转换失败,使用默认值
try
{
this
.
minPrice
=
Integer
.
parseInt
(
minPriceStr
);
}
catch
(
NumberFormatException e
)
{
/*保持默认值*/
}
try
{
this
.
maxPrice
=
Integer
.
parseInt
(
maxPriceStr
);
}
catch
(
NumberFormatException e
)
{
/*保持默认值*/
}
try
{
this
.
cateId
=
Integer
.
parseInt
(
cateIdStr
);
}
catch
(
NumberFormatException e
)
{
/*保持默认值*/
}
}
public
String getPageNoStr
()
{
return
pageNoStr
;
}
public
int
getMinPrice
()
{
return
minPrice
;
}
public
int
getMaxPrice
()
{
return
maxPrice
;
}
public
Integer getCateId
()
{
return
cateId
;
}
@Override
public
String toString
()
{
return
"PageCondition [pageNoStr="
+
pageNoStr
+
", minPrice="
+
minPrice
+
", maxPrice="
+
maxPrice
+
", cateId="
+
cateId
+
"]"
;
}
}
③在Dao中升级原有的分页方法
(
1
)
int
getTotalItemNum
(
PageCondition pageCondition
)
,根据相关条件进行相关查询
·原本不带条件的SQL语句:SELECT COUNT
(*)
FROM book
·带全部条件的SQL语句
SELECT
COUNT
(*)
FROM
book
WHERE price
<=
10000
AND price
>=
0
AND cate_id
=
1
·适配具体情况的SQL语句
pageCondition
.
getCateId
()
的返回值是否为null,决定是否附加“AND cate_id
=
1
”
○第一部分
SELECT
`book_id` bookId
,
`book_name` bookName
,
`author` author
,
`price` price
,
`store_num` storeNum
,
`salse_amount` salseAmount
,
`imp_path` imgPath
,
`cate_id` cateId
FROM
book
WHERE price
>=
0
AND price
<=
10000
○第二部分
AND cate_id
=
1
根据pageCondition
.
getCateId
()
的返回值是否为null,决定是否附加
○第三部分
LIMIT
?,
?
◆具体更改如下:
★1、在BookDao .java中重载两个方法
/**
* 获取在指定条件下的分页数据
* @param pageNo 表示当前页,不能使用pageCondition返回的pageNoStr,要使用经过Page对象纠正的
* @param pageSize 页面显示的条目数
* @param pageCondition
* @return
*/
List
<
Book
>
getPageList
(
int
pageNo
,
int
pageSize
,
PageCondition pageCondition
);
/**
* 带条件的查询
* @param pageCondition
* @return 返回在指定的条件下一共有多少条记录
*/
int
getTotalItemNum
(
PageCondition pageCondition
);
★2、在BookDaoImpl .java中实现上述两个方法
@Override
public
List
<
Book
>
getPageList
(
int
pageNo
,
int
pageSize
,
PageCondition pageCondition
)
{
Connection connection
=
JDBCUtils
.
getConnection
();
String sql
=
"SELECT `book_id` bookId,"
+
"`book_name` bookName,"
+
"`author` author,"
+
"`price` price,"
+
"`store_num` storeNum,"
+
"`salse_amount` salseAmount,"
+
"`imp_path` imgPath,`cate_id` cateId "
+
"FROM book WHERE price>=? and price<=?"
;
Integer cateId
=
pageCondition
.
getCateId
();
//根据实际情况决定是否加入这个条件
if
(
cateId
!=
null
)
sql
=
sql
+
" and `cate_id`="
+
cateId
;
sql
=
sql
+
" LIMIT ?,?"
;
List
<
Book
>
list
=
this
.
getBeanList
(
connection
,
sql
,
pageCondition
.
getMinPrice
(),
pageCondition
.
getMaxPrice
(),
(
pageNo
-
1
)*
pageSize
,
pageSize
);
JDBCUtils
.
releaseConnection
(
connection
);
return
list
;
}
//获取总记录数
@Override
public
int
getTotalItemNum
(
PageCondition pageCondition
)
{
Connection connection
=
JDBCUtils
.
getConnection
();
String sql
=
"SELECT COUNT(*) FROM book WHERE price >= ? AND price <= ?"
;
Integer cateId
=
pageCondition
.
getCateId
();
if
(
cateId
!=
null
)
sql
=
sql
+
" AND cate_id = "
+
cateId
;
long
itemNum
=
this
.
getSingleValue
(
connection
,
sql
,
pageCondition
.
getMinPrice
(),
pageCondition
.
getMaxPrice
());
JDBCUtils
.
releaseConnection
(
connection
);
return
(
int
)
itemNum
;
}
☆对以上更改进行单元测试
private
BookDao bookDao
=
new
BookDaoImpl
();
@Test
public
void
testGetPageListInCon
()
{
PageCondition pageCondition
=
new
PageCondition
(
"1"
,
null
,
null
,
null
);
List
<
Book
>
list
=
bookDao
.
getPageList
(
1
,
3
,
pageCondition
);
for
(
Iterator iterator
=
list
.
iterator
();
iterator
.
hasNext
();)
{
Book book
=
(
Book
)
iterator
.
next
();
System
.
out
.
println
(
book
);
}
}
@Test
public
void
testGetItemNumInCon
()
{
PageCondition pageCondition
=
new
PageCondition
(
"1"
,
"30"
,
"50"
,
"2"
);
int
totalItemNum
=
bookDao
.
getTotalItemNum
(
pageCondition
);
System
.
out
.
println
(
totalItemNum
);
}
★3、在BookService中对该方法重载
Page
<
Book
>
getBookPage
(
PageCondition pageCondition
);
★4、在BookServiceImpl实现该接口
@Override
public
Page
<
Book
>
getBookPage
(
PageCondition pageCondition
)
{
//总记录数从Dao中获取,先获取总记录数,以计算总页数
int
totalItemNum
=
bookDao
.
getTotalItemNum
(
pageCondition
);
//创建分页类对象,并在构造器中对传入的当前页和总记录数进行校验
Page
<
Book
>
page
=
new
Page
<
Book
>(
pageCondition
.
getPageNoStr
(),
totalItemNum
);
//这里pageNo必须使用Page类纠正过的,不能使用PageCondition中的pageNoStr,它不具备纠正能力
//getPageList()获取在指定条件下的分页数据
List
<
Book
>
list
=
bookDao
.
getPageList
(
page
.
getPageNo
(),
Page
.
PAGE_SIZE
,
pageCondition
);
//将page对象设置到list集合当中
page
.
setList
(
list
);
return
page
;
}
☆对该接口实行单元测试:
@Test
public
void
testGetPageInCon
()
{
//查询第一页,价格在30-77之间,书的分类Id是5的有记录
PageCondition pageCondition
=
new
PageCondition
(
"1"
,
"30"
,
"77"
,
"5"
);
Page
<
Book
>
page
=
bookService
.
getBookPage
(
pageCondition
);
int
totalItemNum
=
page
.
getTotalItemNum
();
int
totalPageNum
=
page
.
getTotalPageNum
();
int
pageNo
=
page
.
getPageNo
();
Iterator
<
Book
>
iterator
=
page
.
getList
().
iterator
();
while
(
iterator
.
hasNext
())
{
Book book
=
(
Book
)
iterator
.
next
();
System
.
out
.
println
(
book
.
getBookId
());
//5 7 18
}
System
.
out
.
println
(
"总记录数:"
+
totalItemNum
);
//总记录数:3
System
.
out
.
println
(
"总页数:"
+
totalPageNum
);
//总页数:1
System
.
out
.
println
(
"当前页:"
+
pageNo
);
// 当前页:1
}
★5、在BookClientServlet中增加getPageInCondition ()方法
protected
void
getPageInCondition
(
HttpServletRequest request
,
HttpServletResponse response
)
throws
ServletException
,
IOException
{
//获取请求参数
String pageNoStr
=
request
.
getParameter
(
"pageNo"
);
String minPriceStr
=
request
.
getParameter
(
"minPrice"
);
String maxPriceStr
=
request
.
getParameter
(
"maxPrice"
);
String cateIdStr
=
request
.
getParameter
(
"cateId"
);
//封装条件对象
PageCondition pageCondition
=
new
PageCondition
(
pageNoStr
,
minPriceStr
,
maxPriceStr
,
cateIdStr
);
Page
<
Book
>
page
=
bookService
.
getBookPage
(
pageCondition
);
WebUtils
.
myForward
(
request
,
response
,
"/client/book/bookList.jsp"
,
"page"
,
page
);
}
★6、在bookList .jsp中更改价格查询的提交地址
<
form action
=
"client/BookClientServlet?method=getPageInCondition"
method
=
"post"
>
价格
<
input type
=
"text"
class
=
"inpType"
name
=
"minPrice"
/>-
<
input type
=
"text"
class
=
"inpType"
name
=
"maxPrice"
/>
<
input type
=
"submit"
value
=
"查询"
/>
</
form
>
★7、在client .jsp中做同样更改
<
li
>
全部分类
</
li
>
<
c
:
forEach items
=
"${cateList }"
var
=
"category"
>
<
li
><
a href
=
"client/BookClientServlet?method=getPageInCondition&cateId=${category.cateId }"
>
$
{
category
.
cateName
}</
a
></
li
>
</
c
:
forEach
>
★8、给分类信息加入target属性使其在mainContent中显示
<
li
>
全部分类
</
li
>
<
c
:
forEach items
=
"${cateList }"
var
=
"category"
>
<
li
><
a target
=
"targetFrame"
href
=
"client/BookClientServlet?method=getPageInCondition&cateId=${category.cateId }"
>
$
{
category
.
cateName
}</
a
></
li
>
</
c
:
forEach
>
4、在页面上保持查询条件
[1 ]会导致“丢失”查询条件的行为
(
1
)
翻页的超链接
·能够保持的条件:pageNo
○分类、价格会丢失
→可将以下条件附着在超链接之后
&
cateId
=
$
{
param
.
cateId
}&
minPrice
=
$
{
param
.
minPrice
}&
maxPrice
=
$
{
param
.
maxPrice
}
例如:
<
a href
=
"client/BookClientServlet?method=getPageInCondition&pageNo=${page.prevNo }
&
cateId
=
$
{
param
.
cateId
}&
minPrice
=
$
{
param
.
minPrice
}&
maxPrice
=
$
{
param
.
maxPrice
}
">上一页</a>
·改进:对超链接进行批量操作
<
script type
=
"text/javascript"
>
$
(
function
(){
var conditonStr
=
"&cateId=${param.cateId }&minPrice=${param.minPrice }&maxPrice=${param.maxPrice }"
;
$
(
"a"
).
each
(
function
(){
this
.
href
=
this
.
href
+
conditonStr
;
});
$
(
"#pageCode"
).
change
(
function
(){
//去掉前后空格
var pageCode
=
$
.
trim
(
this
.
value
);
//判断用户输入的页码是否为数字
if
(
isNaN
(
pageCode
)){
//如果不是将文本框置空,并停止函数的执行
this
.
value
=
""
;
return
false
;
}
//如果是数字,则跳转到指定的页码
var url
=
"${pageContext.request.contextPath }/"
+
"client/BookClientServlet?method=getPageInCondition&pageNo="
+
pageCode
+
conditonStr
;
window
.
location
.
href
=
url
;
});
});
</
script
>
(
2
)
跳转页面的文本框
·能够保持的条件:pageNo
○分类、价格会丢失
◇在bookList
.
jsp中修改JS代码中的URL地址
<
script type
=
"text/javascript"
>
$
(
function
(){
$
(
"#pageCode"
).
change
(
function
(){
//去掉前后空格
var pageCode
=
$
.
trim
(
this
.
value
);
//判断用户输入的页码是否为数字
if
(
isNaN
(
pageCode
)){
//如果不是将文本框置空,并停止函数的执行
this
.
value
=
""
;
return
false
;
}
//如果是数字,则跳转到指定的页码
var url
=
"${pageContext.request.contextPath }/"
+
"client/BookClientServlet?method=getPageInCondition&pageNo="
+
pageCode
+
"&cateId=${param.cateId }&minPrice=${param.minPrice }&maxPrice=${param.maxPrice }"
;
window
.
location
.
href
=
url
;
});
});
</
script
>
注意:方法名要更改为:getPageInCondition
疑问?EL表达式能写在JS里面吗?
解答:可以的,因为Jsp页面的翻译和运行先于JS
,
浏览器取得该超链接地址是被翻译过的。
(
3
)
查询价格的表单提交
·能够保持价格信息
○会丢失pageNo和分类
因此要附着:
&
pageNo
=
$
{
param
.
pageNo
}&
cateId
=
$
{
param
.
cateId
}
◇将其附着在表单提交的地址后面
<
form action
=
"client/BookClientServlet?method=getPageInCondition&pageNo=${param.pageNo }&cateId=${param.cateId }"
method
=
"post"
>
价格
<
input type
=
"text"
class
=
"inpType"
name
=
"minPrice"
value
=
"${param.minPrice }"
/>-
<
input type
=
"text"
class
=
"inpType"
name
=
"maxPrice"
value
=
"${param.maxPrice }"
/>
<
input type
=
"submit"
value
=
"查询"
/>
</
form
>
(
4
)
点击分类超链接【会话控制可以解决】
分类信息client
.
jsp和bookList
.
jsp非同一个页面在bookList
.
jsp中即使用param对象,在client
.
jsp中也获取不到它的值
因此暂时先不动分类Client
.
jsp,之后可以将pageCondition放到session里面,那么这两个页面就可以协同工作了。
·能够保持分类
○丢失分类、价格、页码
[2 ]保持查询条件
(
1
)
在跳转页面时将已存在的查询条件携带提交
(
2
)
$
{
param
.
xxx
}
翻页的超链接:自己发出的不存在保持查询条件的问题,可以将查询条件附着在超链接上面,
<
a href
=
"...let?method=getPageInCondition&pageNo=${num }&minPrice=${param.minPrice }"
>
$
{
num
}</
a
>
<
a href
=
"...let?method=getPageInCondition&pageNo=${num }&minPrice=30"
>
$
{
num
}</
a
>
(
3
)
注意:Servlet方法的名字要改成getPageInCondition
[
3
]
在bookList
.
jsp中显示当前的分类名称
◇在client
.
jsp中将每一个分类都附着cateName信息
<
li
>
全部分类
</
li
>
<
c
:
forEach items
=
"${cateList }"
var
=
"category"
>
<
li
><
a target
=
"targetFrame"
href
=
"client/BookClientServlet?method=getPageInCondition&cateId=${category.cateId }&cateName=${category.cateName }"
>
$
{
category
.
cateName
}</
a
></
li
>
</
c
:
forEach
>
◇在bookList
.
jsp中获取cateName
//<td colspan="2">当前分类:${param.cateName }</td>
<
td colspan
=
"2"
>
当前分类:$
{
param
.
cateName
==
null
?
'全部分类'
:
param
.
cateName
}</
td
>
◆当点击全部分类的时候显示空白,现在要给全部分类也加上超链接以便于用户能回到全部分类
<
li
><
a target
=
"targetFrame"
href
=
"client/BookClientServlet?method=getPageInCondition&cateName=全部分类"
>
全部分类
</
a
></
li
>
目前的局限性:
只能在当前分类下保持查询(先点击“科学”再点击价格可以保持,但是再次点击别的分类就保持不了)
5、点击图书名称显示单本书的信息
①给书名加超链接
<
li
>
书名:
<
a href
=
"client/BookClientServlet?method=getBook&bookId=${book.bookId }"
>
$
{
book
.
bookName
}</
a
></
li
>
②在BookClientServlet中写getBook
()
方法
protected
void
getBook
(
HttpServletRequest request
,
HttpServletResponse response
)
throws
ServletException
,
IOException
{
String bookId
=
request
.
getParameter
(
"bookId"
);
Book book
=
bookService
.
getBookById
(
bookId
);
WebUtils
.
myForward
(
request
,
response
,
"/client/book/book.jsp"
,
"book"
,
book
);
}
③创建book
.
jsp页面用于显示图书信息
注意:编码为UTF
-
8
◇导入:
<
base href
=
"http://${pageContext.request.serverName }:${pageContext.request.serverPort }${pageContext.request.contextPath }/"
/>
◇
<
link rel
=
"stylesheet"
type
=
"text/css"
href
=
"style/css.css"
/>
◇
<
script type
=
"text/javascript"
src
=
"script/jquery-1.7.2.js"
></
script
>
<
script type
=
"text/javascript"
>
$
(
function
(){
$
(
"button"
).
click
(
function
(){
//借助window.history.go(-1)实现后退功能
window
.
history
.
go
(-
1
);
});
});
</
script
>
◇在body中书写
<
body
>
<
img
class
=
"bookImg"
src
=
"${book.imgPath }"
>
<
p
>
书名:$
{
book
.
bookName
}</
p
>
<
p
>
作者:$
{
book
.
author
}</
p
>
<
p
>
价格:$
{
book
.
price
}</
p
>
<
p
>
库存:$
{
book
.
storeNum
}</
p
>
<
p
>
销量:$
{
book
.
salseAmount
}</
p
>
<
p
><
button
>
回到上一页
</
button
></
p
>
</
body
>