先放效果图:
好了,正式开始实现的功能过程:
我们注意到顶部的各分类的导航栏部分,实际是一个横向列表,让其中的各部分左浮动起来,然后再建立点击事件~
<%--图书分类导航栏 --%>
<div class="jumbotron">
<div class="container">
<ul class="nav">
<li class="nav-item">
<a class="nav-link active" href='javascript:void(0)' id="fenlei" >所有分类</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei" >AngularJS</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">BootStrap</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">CSS</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">HTML5</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">IOS</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">java</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">Javascript</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">Jquery</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">linux</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">NoSql</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">php</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">python</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">SEO</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">thinkphp</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">web</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">Database</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">Computer</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">science</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">Design pattern</a>
</li>
<li class="nav-item">
<a class="nav-link" href='javascript:void(0)' id="fenlei">C</a>
</li>
</ul>
</div>
<%--用于清除浮动,让父元素高度可以自适应 --%>
<div class="clear"></div>
</div>
相应CSS:
/*头部*/
#header{
height:35px;
background-color:#000000;
}
/*分类导航栏部分*/
.jumbotron{
padding:0;
margin:0 auto;
height:auto;
/*单独设置父元素透明度*/
background: rgba(0,0,0,0.5)。
}
.container{
float:left;
}
/*--用于清除浮动,让父元素高度可以自适应*/
.clear{
clear:both;
}
我们进入点击相应返回书籍内容的页面。我们首先需要设计一个放置图书内容的布局
<%--展示图书内容 --%>
<div class="contain">
<table class="table table-striped">
<thead>
<tr>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<%--存放图书数据 --%>
<tbody id="BookContainShow">
</tbody>
</table>
<%--翻页的部分 --%>
<div id="pagination">
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item">
<a class="page-link" id="PreviousPage" href="javascript:void(0)" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">Previous</span>
</a>
</li>
<p id="PageCenterStr"><span id="whatbook"></span>共有<span id="booksum"></span>本,当前 第
<span id="current">1</span> 页/共 <span id="total"></span> 页 </p>
<li class="page-item">
<a class="page-link" id="NextPage" href="javascript:void(0)" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
相应的CSS样式:
.contain{
position:relative;
width:1000px;
margin:0 auto;
height:auto;
margin-top:5px;
}
/*令书籍显示内容的高度自适应~*/
#BookContainShow{
height:auto;
}
/*设置书籍显示时的高和宽*/
.BookPicSize{
height:136px;
width:108px;
}
/*分页栏*/
#pagination{
position:relative;
display:none;
margin:0 auto;
}
/*分页栏的介绍文字*/
#PageCenterStr{
margin-top:6px;
}
接下来,进入事件相应的方法实现:
$(document).ready(function(){
//要注意的点;多个相同id绑定了点击事件,要加上前缀例如下面这个 $("a#fenlie")
$("a#fenlei").click(function(){
var c = $(this).html()
//获取值和数据库交互
//console.log("我是被监听的"+a+"标签");
$.ajax({
url:"FindBook.action",
method:"post",
datatype:'text',
data:{
chooseBook:c,
},
//返回json的数据,入表格
success:function(backa){
/*如果返回成功,要清除原本表格内容,因为都在同一个表格中显示*/
var a = parseInt(backa);
var aa = parseInt((a+5-1)/5);
if(a>0){
//把页码行列显示出来
$("#pagination").show();
$("#whatbook").html(c);
$("#booksum").html(a);
$("#total").html(aa);
/*获得当前页面的数值,目前一定是第一页~*/
var currentPage = parseInt($("#current").text());
getPageInfo(currentPage,c);
}
},
error:function(backa){
},
});
});
简单来说,每当我们点击一次某个图书分类的时候都会先执行一次js去查询该分类有多少书,多少本,并计算可以分为多少页~
这里要注意的:
1、我们要通过<a>标签去相应操作,但是又不想设置很多个id内容,我们可以一致为一个id,$("a#fenlei").click,然后在里面取到标签对应得值,再变化为ajax带去后台的数据就行了
struts2的配置:
<!-- 寻找图书总页数的action -->
<action name="FindBook" class="ExecuteDo.doFindBook">
<!-- 返回Json数据 -->
<result name="success" type="stream">
<param name="contentType">text/html</param>
<param name="inputName">bookSum</param>
</result>
</action>
doFindBook.java:
//查找图书总数---1
public String execute() throws UnsupportedEncodingException{
String bOOKSUM = FindBookdeal(chooseBook);
int totalRecord =Integer.parseInt(bOOKSUM);
//计算页数
//int a = (totalRecord + 5 - 1) / 5;
bOOKSUM = String.valueOf(totalRecord);
bookSum = new ByteArrayInputStream(bOOKSUM.getBytes("utf-8"));
return SUCCESS;
}
//查找图书总数---2
public String FindBookdeal(String chooseBook){
Session session = HibernateSessionFactory.getSession();
//打开事务
Transaction tx =session.beginTransaction();
//区分一下是所有分类还是具体行业
if(chooseBook.equals("所有分类")){
Query query = session.createQuery("select count(*) from PythonbookCopy");
String str = query.uniqueResult().toString();
return str;
}
else{
Query query = session.createQuery("select count(*) from PythonbookCopy where leibie ='"+chooseBook+"'");
String str = query.uniqueResult().toString();
return str;
}
}
得到了总页数,我们就可以去查询第一页的内容了,通过ajax里的方法
getPageInfo(currentPage,c):
/*查每一页详情的方法*/
function getPageInfo(currentPage,c){
c = $("#whatbook").html();
//用ajax去获取每一页
$.ajax({
url:"FindCurrentPage.action",
method:"post",
dataType:"json",
//传递的数据是那一页,c是书的类别~
data:{
bookLeiBie:c,
howPage:currentPage,
},
success:function(data){
//如果数据非空要用于清除表单原有的数据
if(data!=null){
//清除原有的表格数据,方便更新新的附上去~
$("#BookContainShow").empty();
//返回list对象~
var list = data.pagebooklist;
/*测试输出,以及是否有接收到~
for(var i=0;i<list.length;i++){
var news = list[i];
console.log(news);
}
*/
//定义表格str语句,稍后赋给.html()
var str=""
for(var i=0;i<list.length;i++){
var news = list[i];
//分别给书本的各属性赋值
var booktitle = news.title;
var bookauthor = news.author;
var bookbelongg = news.belongg;
var booksummaryy = news.summaryy;
var bookpicUrl = news.picUrl;
str += "<tr >" +
"<td><img class=\"BookPicSize\" src=\" "+bookpicUrl+" \" alt=\" "+booktitle+" \"/></td>" +
"<td>" +
"书名:"+booktitle+"</br>"+
"作者:"+bookauthor+"</br>"+
"出版信息"+bookbelongg+"</br>"+
"书籍简介"+booksummaryy+"</br>"+
//给一个超链接,并且可以预指定方法
"<a href=\"checklogin.action\">下载本书籍</a>"
/*一开始的时候想用ajax验证一下是否已经登录的,但是,结果不能先用ajax~所以直接用action的形式~那么用拦截器来验证登登录吧~
"<a href=\"javascript:void(0)\"class=\"DLbook\" id=\""+booktitle+"\">下载本书籍" +
"</a>"+
*/
"</td>" +
"</tr>"
}
//连接~
str+=""
$("#BookContainShow").html(str);
}
},
});
}
动态生成表格中的每一项内容,以及下载链接的内容
其中struts2配置:
<!-- 寻找当前某一页的数据的action -->
<action name="FindCurrentPage" class="ExecuteDo.doFindBook" method="FindCurrentPageBook">
<!-- 返回Json数据 -->
<result name="success" type="json">bbbbooklist</result>
</action>
//查找每一页的书籍内容----1
public String FindCurrentPageBook(){
//start计算从第几个开始查;5的话是指查多少个数据~,bookLeiBie是书的类别
int start = (howPage-1)*5;
pagebooklist = getNewsByPage(start,5,bookLeiBie);
/*
*转换为JSONArray数据格式,具体如下[{},{},{},{}....]详情可以百度JSONObject,和,JSONArray~查的
*/
JSONArray ssss = JSONArray.fromObject(pagebooklist);
bbbbooklist = ssss.toString();
return SUCCESS;
}
//查找每一页的书籍内容----2
public List<PageBookList> getNewsByPage(int start, int i,String bookLeiBie){
if(bookLeiBie.equals("所有分类")){
try{
Session session = HibernateSessionFactory.getSession();
//分为两种情况,所欲分类是特殊的情况
Query query = session.createQuery("from PythonbookCopy");
query.setFirstResult(start);
query.setMaxResults(i);
return query.list();
}catch(Exception e){
e.printStackTrace();
return null;
}
}
else{
try{
Session session = HibernateSessionFactory.getSession();
//解决先筛选出书的分类,再进行分页查询的HQL语句是难点,想一想~
Query query = session.createQuery("from PythonbookCopy where leibie='"+bookLeiBie+"'");
query.setFirstResult(start);
query.setMaxResults(i);
return query.list();
}catch(Exception e){
e.printStackTrace();
return null;
}
}
}
要注意的地方:
1、返回书籍时时list的形式;我们需要用JSONArray转为我们需求格式
[{...},{....}]
2、详情可以去了解JSONObject和JSONArray的区别~
如何实现分页呢?
我们对分页的前一页后一页的按钮增加事件方法:
//点击上一页时,计算一下是否超出总页数
$("#PreviousPage").click(function(){
if($("#current").text()=="1"){
alert("不行,没有上一页了")
}
else{
//parseInt将字符形式转为数字!
var currentPage = parseInt($("#current").text())-1;
$("#current").html(currentPage);
getPageInfo(currentPage);
}
});
//点击下一页时计算是否超出
$("#NextPage").click(function(){
//比较相应字符相不相同即可,无所谓转不转
if($("#current").text()==$("#total").text()){
alert("不行,没有下一页了")
}
else{
var currentPage =parseInt($("#current").text())+1;
$("#current").html(currentPage);
getPageInfo(currentPage);
}
});
计算是否页面数不合法,如果不是得话,再把要的页面传递去个体到就可以了
下载书籍:
当我们点击链接<a>之后,
struts配置:
<!-- 下载书籍的action -->
<action name="downloadbook" class="ExecuteDo.dodownloadbook">
<result name="success" type="stream">
<!-- 返回的流名字 -->
<param name="inputName">bookfile</param>
<!-- 通知以附件的形式文件;filename是文件名 -->
<param name="contentDisposition">attachment;filename=${filename}</param>
<!-- 文件类型;前者表示,不限定文件类型;后者表示编码形式 -->
<param name="contentType">
application/octet-stream;charset=ISO8859-1
</param>
<!-- 缓冲区大小 -->
<param name="bufferSize">1024</param>
</result>
</action>
public String execute() throws Exception{
//String projectPath = ServletActionContext.getServletContext().getRealPath(File.separator+"\\BookFile\\offer.pdf");
//System.out.println(projectPath);
//目前全部都下载剑指的pdf,因为没准备那么多文件
bookfile = ServletActionContext.getServletContext().getResourceAsStream("\\BookFile\\offer.pdf");
//System.out.println(bookfile);
filename= new String("剑指Offer.pdf".getBytes(),"ISO8859-1");
//System.out.println(filename);
return SUCCESS;
}
需要注意的是:
1、获取文件路径的问题,很容易出错