网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
- 转发由request控制
2.响应重定向----response
特点:值不共享,浏览器的地址变化
重定向的意思是:第一次请求到达服务器后,服务器处理完成,可以在响应信息中告诉浏览器去下一个地址,浏览器会自动请求下一个路径。这个过程中浏览器发送了两次请求。从这里可以看出重定向是由响应response发起的。
代码如下:其中/day01上下文,可以通过代码获得
resp.sendRedirect("/day01/demo2");
最终的代码如下:不要忘了加req.getContextPath()
resp.sendRedirect(req.getContextPath()+"/news/list.jsp");
重定向的特点:redirect
- 地址栏发生变化,因为浏览器要访问重定向的地址
- 重定向可以访问其他站点(服务器)的资源
- 重定向是两次请求。不能使用request对象来共享数据
- 重定向由response控制
转发?重定向?
以一个新闻阅读的登陆的业务为例:
异步请求axios为例—响应必须是response
1.新建一个专门用来处理响应的实体类ResData
package com.tianju.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/\*\*
\* 响应的实体类
\*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResData {
// 返回码,200正常,10001参数错误。。。
private Integer code;
// 正常标识,success,ok
private String msg;
// 具体的信息,可以是对象
private Object data;
}
2.在axios中,所有响应必须是 resp.getWriter().write() 的方式,核心代码如下
resp.getWriter().write(JSON.toJSONString(new ResData(1001, "输入为空", null)));
同步请求情况下—根据需求选response/request
TODO:什么时候跳转到jsp,什么时候重定向,什么时候转发
思考:和需求相关,如果这里直接到一个不需要servlet处理的页面,则用重定向即可
如果需要处理一下,再到页面,则用转发给另一个servlet继续进行业务处理
跳转到新闻信息页面---开始为了测试跳转是否实现,用了重定向;
最终,业务是登陆成功后,查询数据库,进行显示,则转发给ListServlet进行处理,
1.登陆后重定向
在一开始写代码的时候,在login.jsp中进行输入用户名和密码,进行登陆,然后在LoginServlet.java中对前端传进来的用户名和密码进行验证,即处理登陆业务;如果验证成功,则跳转到新闻展示页面。由于一开始代码并不完善,因此:
在这里先让登陆成功后,直接跳转到 list.jsp 前端页面,在页面上只有一个<h1标签。此时,我的目的是,用跳转成功来验证登陆的业务代码是否正确,因此,用了重定向;
resp.sendRedirect(req.getContextPath()+"/news/list.jsp");
login.jsp中的代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户登陆</title>
</head>
<body>
<h1>杂七杂八新闻管理系统登陆页面</h1>
<form action="/day06/user/login" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
<input type="reset" value="重置">
</form>
</body>
</html>
LoginServlet.java代码:
/\*\*
\* 处理登陆的servlet
\*/
@WebServlet("/user/login")
public class LoginServlet extends HttpServlet {
private IUserService userService = new UserServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+password);
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)){
// TODO:给前端
System.out.println("输入空");
return;
}
User userDb = userService.queryByUsername(username);
if (userDb==null || !password.equals(userDb.getPassword())){
System.out.println("用户名|密码错误");
return;
}
// 登陆成功的信息保存到session中
HttpSession session = req.getSession();
session.setAttribute("user", userDb);
// TODO:什么时候跳转到jsp,什么时候重定向,什么时候转发
// 思考:和需求相关,如果这里直接到一个不需要servlet处理的页面,则用重定向即可
// 如果需要处理一下,再到页面,则用转发给另一个servlet继续进行业务处理
// 跳转到新闻信息页面---开始为了测试跳转是否实现,用了重定向
resp.sendRedirect(req.getContextPath()+"/news/list.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>
</body>
</html>
2.登陆后转发
实际上,新闻的页面需要先查询一下数据库,获取数据库中的新闻后,再发送到 list.jsp 页面进行显示,此时,就用请求的转发,从LoginServlet.java的
@WebServlet(“/user/login”) 转发到 ListServlet.java 的@WebServlet(“/news/list”),在这个servlet里面进行新闻的查询,然后把查询到的新闻共享到 list.jsp 页面进行展示。
此时LoginServlet.java用请求转发:
req.getRequestDispatcher("/news/list").forward(req, resp);
进行数据库查询的ListServlet.java代码如下:
/\*\*
\* 文章列表显示的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);
}
}
转发到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>
![img](https://img-blog.csdnimg.cn/img_convert/441498eadcf389ce649207c66c8ffbb1.png)
![img](https://img-blog.csdnimg.cn/img_convert/7de49b6d0aaa9a7c0b2a8e6fb7bfce9c.png)
![img](https://img-blog.csdnimg.cn/img_convert/bd862ca56ef0ef515e60dca02d3d9267.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618631832)**
="submit" value="提交">
</form>
</body>
</html>
[外链图片转存中...(img-dhTrLvdX-1715791037591)]
[外链图片转存中...(img-cG0jznrF-1715791037591)]
[外链图片转存中...(img-5tnhUTi4-1715791037592)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618631832)**