目录
引出
1.jsp的本质是啥,核心语法有哪些,常见报错;
2.为啥要分页展示,怎么实现分页展示;
3.首页,尾页,上下页,跳转如何实现;
4.模糊查询怎么实现;
5.只能看自己的怎么搞;
0.jsp的使用和语法 & 报错和解决
JSP的本质
1.Jsp本质是一个长得像html文件的servlet,因此,正常就可以当一个普通的html文件使用;
2.Jsp本质是servlet,因此可以从java的HttpServlet进行值共享,而后转发到 Jsp 进行展示;核心代码如下:
// 共享值
req.setAttribute("bookTypes", bookTypeList);
// 转发给jsp
req.getRequestDispatcher("/book/add.jsp").forward(req,resp);
JSP常用语法及注意事项
(1)后端共享,前端获取 ${pageInfo}
后端共享:
// 共享值;
PageInfo pageInfo = new PageInfo(pageNum, pageSize, total, pages);
req.setAttribute("pageInfo",pageInfo);
// 转发到jsp
req.getRequestDispatcher("/book/messListLikePage.jsp").forward(req,resp);
前端获取:
${pageInfo}
(2)如果想获取pageInfo这个对象的某个属性值,用 点 + 属性 ${pageInfo.pages}
${pageInfo.pages}
(3)如果想回传,即jsp发给后端的值,再在jsp中获得 ${param.bookName}
<div style="text-align: left">
<form action="/day06/opus/messLikeList/page" method="get">
<%-- 如何想要再拿到之前的输入模糊查询的条件
parem的意思是从request中获取参数--%>
书名:<input type="text" placeholder="输入书名进行模糊查询" name="bookName" value="${param.bookName}">
<input type="submit" value="搜索">
</form>
</div>
(4)如果想获取session中的user, ${sessionScope.user.username}
在后端java中把user存在session中,
// 3.用输入的用户名去数据库中查询一条记录
User userDb = userService.queryByUsername(username);
// +登陆成功的用户存到session----用于确定当前的操作是谁做的
req.getSession().setAttribute("user", userDb);
在前端jsp中用sessionScope.user获得user对象:
欢迎您:${sessionScope.user.username}
(5)jsp中的循环语句 c:forEach
<c:forEach items="${opusList}" var="opus">
注意事项:
1)jsp文件中要生成:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2)pom.xml文件中要导包:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
(6)判断语句 c:if + ${type.id==opus.typeId}
类似三元表达式
${type.id==opus.typeId ? 'selected' : ''}
普通的if语句
<c:if test="${pageInfo.pageNum!=1}">
<a href="/day06/news/list?pageNum=1&pageSize=${pageInfo.pageSize}&name=${name}">首页</a>
<a href="/day06/news/list?pageNum=${pageInfo.pageNum-1}&pageSize=${pageInfo.pageSize}&name=${name}">上一页</a>
</c:if>
(7)使用Jsp时常见的报错信息及解决方法
参考下面博客:
Java网络开发(Tomcat)——遇到的 bug 汇总(持续更新)
1.数据分页显示,首页,上一页,下一页,尾页,跳转
(1)之前的方法及存在问题
在下面博客中,
Java网络开发(Tomcat)—— web的 请求request (post和get请求)和 响应response + 【案例】表格显示在网页
实现了用jsp把图书信息显示到前端,但存在的问题是这里把数据全部展示出来,但全部显示存在以下的问题:
1)前端要显示的数据太多,不方便看;
2)后端要查询出数据库中所有的数据,后端查询压力大;
(2)数据分页的解决方案
参考:PageHelper:分页工具
1.pageSize:一页显示多少条:进行设置,默认10条
2.pageNum:当前是第几页,默认第一页
要素 | 含义 | 默认 |
---|---|---|
pageNum | 当前是第几页 | 默认是第一页 |
pageSize | 每一页显示条数 | 百度默认10条 |
total | 数据的总条数 | 需要后端统计 |
pages | 总页数 | 需要计算 |
list | 传给前端的list | 需要后端查 |
后端:
1.total:数据的总条数:是变化的
// 如果没有输入查询关键词,数据条数为总数;
Integer total = companyService.countLines(name);
2.pages:总页数怎么算?
// 3.根据查询数据条数,以及前端获取的每页显示数据条数,计算总页数;
// 思路:如果能整除,则为页数;如果不能整除,则/后再加1;
Integer pages = total % pageSize==0 ? total/pageSize:total/pageSize+1;
3.如何进行判断,首页,下一页,上一页?
1).当前页是否是首页:pageNum == 1;
2).是否是最后一页: pageNum == pages;
3).是否有上一页:pageNum > 1;
4).是否有下一页:pageNum < pages;
(3)后端代码
首先是PageInfo实体类:PageInfo.java文件如下:
package com.tianju.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 和分页相关的实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageInfo<T> {
private Integer pageNum; // 当前是第几页,如果没有输入,默认是第一页
private Integer pageSize; // 每页显示的数据条数,百度默认一页10条
private Integer total; // 总条数;
private Integer pages; // 总页数;
private List<T> list; // 传给前端的list
}
然后是在ListServlet.java中进行PageInfo实体类的实例化,共享,然后传给前端jsp
package com.tianju.servlet.news;
import com.tianju.entity.Article;
import com.tianju.entity.PageInfo;
import com.tianju.service.IArticleService;
import com.tianju.service.impl.ArticleServiceImpl;
import com.tianju.util.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* 文章列表显示的servlet
*/
@WebServlet("/news/list")
public class ListServlet extends HttpServlet {
private IArticleService articleService = new ArticleServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取前端的输入:第几页,每页数据量,查询关键词是啥
String pageNumStr = req.getParameter("pageNum"); // 第几页
String pageSizeStr = req.getParameter("pageSize"); // 每页显示数据条数
String keyword = req.getParameter("name");
// 2.进行赋值,默认首页,默认每页3条
Integer pageNum = StringUtils.isBlank(pageNumStr) ? 1:Integer.parseInt(pageNumStr);
Integer pageSize = StringUtils.isBlank(pageSizeStr) ? 3:Integer.parseInt(pageSizeStr);
// 3.计算数据总条数
Integer total = articleService.countLikeLines(keyword);
// 4.计算总页数
Integer pages = total % pageSize==0 ? total/pageSize:total/pageSize+1;
// 5.new pageInfo对象
List<Article> list = articleService.queryByKeyWordDescLimit(keyword, pageNum, pageSize);
PageInfo<Article> pageInfo = new PageInfo<>(pageNum,pageSize,total, pages, list);
System.out.println(list);
// 6.共享值
req.setAttribute("pageInfo", pageInfo);
req.setAttribute("name", keyword);
System.out.println(pageInfo);
// 6.转发给前端显示
req.getRequestDispatcher("/news/list.jsp").forward(req, resp);
}
}
(4)前端代码
前端的jsp文件,list.jsp文件代码如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>新闻浏览页面</title>
</head>
<body>
<h1>新闻浏览页面</h1>
${pageInfo}<br>
<%--${param}<br>--%>
<%--${sessionScope}--%>
<%-- 输入查询的条件--%>
<div style="align-content: center">
<form action="/day06/news/list">
<%-- 隐藏框--%>
<input type="hidden" name="pageSize" value="${pageInfo.pageSize}">
<input type="hidden" name="pageNum" value="${pageInfo.pageNum}">
查询:<input type="text" placeholder="输入要查询关键字" name="name" value="${param.name}">
<input type="submit" value="搜索"><br>
</form>
</div>
<div style="color: blueviolet" >
<form action="/day06/news/list">
<input type="hidden" name="name" value="${name}">
<input type="hidden" name="pageNum" value="${pageInfo.pageNum}">
每页显示条数:<input type="text" name="pageSize" value="${pageInfo.pageSize}">
<input type="submit" value="提交"><br>
</form>
</div>
<a href="/day06/news/addPage">发布文章</a><br>
<table width="100%" border="1px">
<tr>
<th>编号</th>
<th>栏目</th>
<th>标题</th>
<th>内容</th>
<th>操作</th>
</tr>
<c:forEach items="${pageInfo.list}" var="ar">
<tr>
<td>${ar.articleId}</td>
<td>${ar.channelName}</td>
<td>${ar.articleTitle}</td>
<td>${ar.articleContent}</td>
<td>
<a href="/day06/news/delete?id=${ar.articleId}">删除</a>
<a href="/day06/update/page?id=${ar.articleId}">修改</a>
</td>
</tr>
</c:forEach>
</table><br><hr>
<c:if test="${pageInfo.pageNum!=1}">
<a href="/day06/news/list?pageNum=1&pageSize=${pageInfo.pageSize}&name=${name}">首页</a>
<a href="/day06/news/list?pageNum=${pageInfo.pageNum-1}&pageSize=${pageInfo.pageSize}&name=${name}">上一页</a>
</c:if>
<%-- 如果当前页是尾页,需要控制下一页和尾页不显示 --%>
<c:if test="${pageInfo.pageNum!=pageInfo.pages}">
<a href="/day06/news/list?pageNum=${pageInfo.pageNum+1}&pageSize=${pageInfo.pageSize}&name=${name}">下一页</a>
<a href="/day06/news/list?pageNum=${pageInfo.pages}&pageSize=${pageInfo.pageSize}&name=${name}">尾页</a>
</c:if>
总计${pageInfo.pages}页/当前${pageInfo.pageNum}
<form action="/day06/news/list" method="get">
<input type="hidden" name="name" value="${name}">
<input type="hidden" name="pageSize" value="${pageInfo.pageSize}">
跳转到:<input type="text" name="pageNum" value="${pageInfo.pageNum}">
<input type="submit" value="提交">
</form>
</body>
</html>
2.模糊查询 + 分页显示 + 记录输入的查询条件
(1)模糊查询核心代码:放在form表单中,div块中,隐藏框
<%-- 输入查询的条件--%>
<div style="align-content: center">
<form action="/day06/news/list">
<%-- 隐藏框--%>
<input type="hidden" name="pageSize" value="${pageInfo.pageSize}">
<input type="hidden" name="pageNum" value="${pageInfo.pageNum}">
查询:<input type="text" placeholder="输入要查询关键字" name="name" value="${param.name}">
<input type="submit" value="搜索"><br>
</form>
</div>
每页显示条数的核心代码,div中,form表单,隐藏框
<div style="color: blueviolet" >
<form action="/day06/news/list">
<input type="hidden" name="name" value="${name}">
<input type="hidden" name="pageNum" value="${pageInfo.pageNum}">
每页显示条数:<input type="text" name="pageSize" value="${pageInfo.pageSize}">
<input type="submit" value="提交"><br>
</form>
</div>
(2)首页尾页,上下页的核心代码,记得把pageSize和搜索条件再传回后端
<c:if test="${pageInfo.pageNum!=1}">
<a href="/day06/news/list?pageNum=1&pageSize=${pageInfo.pageSize}&name=${name}">首页</a>
<a href="/day06/news/list?pageNum=${pageInfo.pageNum-1}&pageSize=${pageInfo.pageSize}&name=${name}">上一页</a>
</c:if>
<%-- 如果当前页是尾页,需要控制下一页和尾页不显示 --%>
<c:if test="${pageInfo.pageNum!=pageInfo.pages}">
<a href="/day06/news/list?pageNum=${pageInfo.pageNum+1}&pageSize=${pageInfo.pageSize}&name=${name}">下一页</a>
<a href="/day06/news/list?pageNum=${pageInfo.pages}&pageSize=${pageInfo.pageSize}&name=${name}">尾页</a>
</c:if>
总计${pageInfo.pages}页/当前${pageInfo.pageNum}
跳转到某页,记得回传信息
<form action="/day06/news/list" method="get">
<input type="hidden" name="name" value="${name}">
<input type="hidden" name="pageSize" value="${pageInfo.pageSize}">
跳转到:<input type="text" name="pageNum" value="${pageInfo.pageNum}">
<input type="submit" value="提交">
</form>
3.只能查看自己的数据–本质是session + sql语句
(1)后端核心代码–获取session
// TODO:+++++++++++只能查看自己的数据
HttpSession session = req.getSession();
User user = (User) session.getAttribute("user");
// TODO:只能查询自己的,根据条件查询到的数据的总条数
Integer total = opusService.CountAuthorIdAndLikeNameLines(queryLikeName,user.getId());
// TODO:+++++++++++只能查看自己的数据
// 进行查询;
List<Opus> list = opusService.queryByAuthorIdAndLikeNameLimit(pageNum, pageSize, queryLikeName, user.getId());
(2)核心sql语句–authorId作为条件
1)数据总条数
@Override
public Integer CountAuthorIdAndLikeNameLines(String name, Integer authorId) {
// 如果没有输入条件,统计全部
if (StringUtils.isBlank(name)){
return db.queryForObject("SELECT COUNT(id) FROM t_opus WHERE authorId = ?", Integer.class,authorId);
}
// 如果输入条件
return db.queryForObject("SELECT COUNT(id) FROM t_opus WHERE authorId = ? AND name LIKE ?",
Integer.class,authorId,"%"+name.trim()+"%");
}
2)只能查看自己的数据
@Override
public List<Opus> queryByAuthorIdAndLikeNameLimit(Integer pageNum, Integer pageSize, String name, Integer authorId) {
String sql = "SELECT t_opus.*,tt.name AS typename,tu.username\n" +
"FROM t_opus \n" +
"LEFT JOIN t_types tt ON t_opus.typeId = tt.id\n" +
"LEFT JOIN user_tab tu ON t_opus.authorId = tu.id WHERE authorId = ?";
String limit = " LIMIT " + (pageNum-1)*pageSize + "," + pageSize + " ";
String order = " ORDER BY t_opus.id DESC ";
// 如果没有输入条件,默认查全部
if (StringUtils.isBlank(name)){
return db.query(sql + order + limit, rowMapper,authorId);
}
// 模糊查询后limit,去掉空格
String whereCondition = " AND t_opus.name LIKE ? ";
System.out.println(sql + whereCondition + order +limit);
return db.query(sql + whereCondition + order +limit, rowMapper,authorId, "%"+name.trim()+"%");
}
总结
1.jsp本质是servlet,param.回传,获取session用sessionScope;
2.jsp的循环和分支语句,三元表达式,常见报错及解决;
3.数据分页显示的解决方案,用PageInfo实体类实现;
4.模糊查询,每页条数,页面跳转 要全部回传到后端;
4.用session结合sql语句实现只能看自己的数据;