目录
一、前面内容的补充
二、当下servlet存在的几个问题
三、分离两个Servlet后存在的问题
四、转发
4.1 作用
4.2 页面跳转
4.3 操作与代码
4.4 数据传递
4.5 转发特点
五、重定向
5.1 作用
5.2 页面跳转
5.3 代码实现
5.4 数据传递
5.5 代码
5.6 重定向特点
5.7 转发、重定向总结
一、前面内容的补充
编写Java代码如下,并且使用get请求查看显示的效果
package com.ha.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class RegisterServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取用户请求发送的数据
String username = req.getParameter("username");
String password = req.getParameter("password");
// 【设置响应头】
// setStatus: 设置状态行中的状态码
// resp.setStatus(200);
// setContentType: 设置响应头中的 Content-Type,设置响应客户端的数据格式
resp.setContentType("text/html"); // 等价于:resp.setHeader("Content-Type", "text/html");
// setContentLength: 设置响应客户端的数据长度,一般不需要设置,客户端会读完数据(这个一般用于验证)
// resp.setContentLength(1024); // 等价于:resp.setHeader("Content-Length", "1024");
// setHeader: 设置其他的一些信息
resp.setHeader("Connection", "keep-alive");
// 【设置响应正文】
// setCharacterEncoding:设置响应客户端的数据编码格式
resp.setCharacterEncoding("utf-8");
// 通过resp对象获取输出流
// 字节流(如果要响应文件数据给客户端,则需要使用字节流)
// ServletOutputStream outputStream = resp.getOutputStream();
// 字符流(如果要响应文件数据-HTML文档,则使用字符流)
PrintWriter printWriter = resp.getWriter();
// 通过流写出的数据,就会以响应正文的形式传输给客户端浏览器,如果浏览器可以识别数据,则直接显示
printWriter.println("");
printWriter.println("");
printWriter.println("");
printWriter.println("");
printWriter.println("登录使用的用户名和密码 ");
printWriter.println("");
printWriter.println("");
printWriter.println("
这是响应头:
二、当下servlet存在的几个问题
1、在上述的Java程序中可能做了判断等业务逻辑工作,也用于打印显示的效果。
2、后面有更好的页面要显示出来的时候,会重新修改这个Java代码。
这个就是调用业务逻辑和显示结果页面都在同一个Servlet里,会产生设计问题:(1)不符合单一职能原则、各司其职的思想;(2)不利于后续的维护
应该将业务逻辑和显示结果分离开
三、分离两个Servlet后存在的问题
问题:业务逻辑和显示结果分离后,如何跳转到显示结果的Servlet?
业务逻辑得到的数据结果如何传递给显示结果的Servlet?
四、转发
4.1 作用
转发的作用在服务器端,将请求发送给服务器上的其他资源,以共同完成一次请求的处理。
4.2 页面跳转
在调用业务逻辑的Servlet中,编写以下代码:
request.getRequestDispatcher("/目标URL-pattern").forward(request, response);
4.3 操作与代码
新建一个Java文件
package com.ha.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/rs").forward(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
增加配置文件内容
rs com.ha.servlet.RegisterServlet rs /rs a com.ha.servlet.AServlet a /a
访问 /a
完成了页面从AServlet.java跳转到RegisterServlet.java
在客户端眼中始终访问的是a。使用forward跳转时,是在服务器内部跳转,地址栏不发生变化,属于同一次请求。
4.4 数据传递
1、forward表示一次请求,是在服务器内部跳转,可以共享同一-次request作用域中的数据
(1)request作用域:拥有存储数据的空间,作用范围是一 次请求有效(一 次请求可以经过多次转发)
可以将数据存入request后,在一次请求过程中的任何位置进行获取
可传递任何数据(基本数据类型、对象、数组、集合等)
(2)存数据:request.setAttribute(key, value);
以键值对形式存储在request作用域中。key为String类型, value为0bject类型
(3)取数据:request.gettribute(key);
通过String类型的key访问0bject类型的value
2、完整流程
package com.ha.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("username", "胡安");
req.setAttribute("password", "123456");
req.getRequestDispatcher("/rs").forward(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.ha.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class RegisterServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = (String)req.getAttribute("username");
String password = (String)req.getAttribute("password");
resp.setContentType("text/html");
resp.setHeader("Connection", "keep-alive");
resp.setCharacterEncoding("utf-8");
PrintWriter printWriter = resp.getWriter();
printWriter.println("");
printWriter.println("");
printWriter.println("");
printWriter.println("");
printWriter.println("登录使用的用户名和密码 ");
printWriter.println("");
printWriter.println("");
printWriter.println("用户名:" + username + "");
printWriter.println("密码:" + password + "");
printWriter.println("");
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
rs com.ha.servlet.RegisterServlet rs /rs a com.ha.servlet.AServlet a /a
运行结果:
4.5 转发特点
转发是服务器行为
转发是浏览器只做了一次访问请求
转发浏览器地址不变
转发两次跳转之间传输的信息不会丢失,所以可以通过request进行数据的传递、
转发只能将请求转发给同一个Web应用中的组件
五、重定向
5.1 作用
重定向作用在客户端,客户端将请求发送给服务器后,服务器响应给客户端一个 新的请求地址,客户端重新发送新请求。
5.2 页面跳转
在调用业务逻辑的Servlet中,编写以下代码
response.sendRedirect("目标URL");
URL:统一资源标识符(Uniform Resource Identifier),用来表示服务器中定位一 个资源,资源在web项目中的路径(/project/source)
5.3 代码实现
访问/a调换到/rs
5.4 数据传递
sendRedirect跳转时,地址栏改变,代表客户端重新发送的请求。属于两次请求
response没有作用域, 两次request请求中的数据无法共享
传递数据:通过UR的拼接进行数据传递("/WebProject/b?usemame=tom");
获取数据:request.getParameter("usemame");
5.5 代码
5.6 重定向特点
重定向是客户端行为。
重定向是浏览器做了至少两次的访问请求。
重定向浏览器地址改变。
重定向两次跳转之间传输的信息会丢失(request范围)。
重定向可以指向任何的资源,包括当前应用程序中的其他资源、同一个站点上的其他应用程序中的资源、其他站点的资源。
5.7 转发、重定向总结
当两个Servlet需要传递数据时,选择forward转发。 不建议使用sendRedirect进行传递



