请求转发
定义
指服务器收到请求之后,从一个资源跳转到另一个资源的的操作。
这是一种在服务器内部
的资源跳转方式.(换言之,请求转发是不能跳到服务器之外
的资源)
语法格式
requset.getRequestDispatcher(url);
特点
- 浏览器地址栏路径不发生变化
- 请求转发只是
一次请求一次响应
- 他们可以
共享
Request域中的数据 -
请求转发
只能转发到当前服务器内部的资源
- 可以转发到
WEB-INF
目录下
图示:
请求转发就好比,我们去办理业务,我们带材料(数据)去窗口1(Servlet1),窗口1(Servlet1)拿到我们的材料后,开始办理,但是发现材料缺少,因此窗口1(Servlet1)把材料交给窗口2(Servlet2),当窗口2(Servlet2)把缺少的材料补全后,直接把我们的业务给直接办理好,并给我们一个最后的结果。
请求域(request域)
- 在两个servlet请求转发时,会存在A类的数据需要传递给B类这样的需求
- 此时就需要使用请求对象的请求域(resquest)功能
-
request.setAttribute(String key, Object value)
,这样就可以将数据存储在请求对象 - 再另外一个servlet中使用请求对象取出值
request.getAttribute("key")
,要保持两个servlet中的键一致。
案例
index.jsp
<!doctype html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style type="text/css">
table{
text-align: center;
border-collapse: collapse;
}
</style>
</head>
<body>
<div>
<form action="Servlet1" method="post">
<table border="1px" style="text-align: center;">
<tr>
<td>用户名:</td>
<td>
<input type="text" name="username" placeholder="用户名">
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" name="password" placeholder="密码">
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="登录">
<input type="reset">
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
Servlet1类:
package com.lyc.lesson.servlet;
import com.lyc.lesson.utils.DBUtil;
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.sql.*;
@WebServlet("/Servlet1")
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
//将页面获取的数据存入request域中
req.setAttribute("username", username);
//请求转发的路径参数必须加斜杠('/')
//getRequestDispatcher(url);url可以是:servlet(必须是该类的映射路径,不是类名),html或jsp
req.getRequestDispatcher("/login/Servlet2").forward(req,resp);
}
Servlet2类
package com.lyc.lesson.servlet;
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.io.PrintWriter;
@WebServlet("/login/Servlet2")
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//获取request域中的数据
Object username = req.getAttribute("username");
PrintWriter out = resp.getWriter();
out.println("欢迎您:"+username);
}
}
注意:
在请求转发中,
getRequestDispatcher(url); url可以是:servlet(必须是该类的映射路径,不是类名),html或jsp
。
重定向
定义
重定向,指的是Web服务器接收到客户端的请求后,可能由于某些条件限制,不能访问当前请求URL所指向的Web资源,而是指定了一个新的资源路径,让客户端重新发送请求。重定向也可以使用Servlet直接的跳转,以及跳转页面.
语法格式
response.sendRedirect("路径");
特点
- 浏览器地址栏会发生变化
- 重定向是两次请求、两次转发
- 不能共享Request域中的数据
- 不能访问WEB-INF下的资源
- 可以访问工程外的资源
图示:
重定向就好比,我们还是去办理业务,我们带着材料去窗口1(servlet1),窗口1(servlet)开始办理业务发现我们缺少东西,因此把材料给我们,并告诉我们去窗口(servlet2),能继续办理,因此我们带着材料,来到窗口2(servlet2)并把材料交给他,窗口2(servlet2)接收到材料开始办理业务,成功完成业务后,把结果返回给我们。
案例:
Servlet1:
package com.lyc.lesson.servlet;
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;
@WebServlet("/Servlet1")
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//请求重定向的路径参数,不能加斜杠('/')
//如果加了斜杠,项目名会丢失
resp.sendRedirect("Servlet2");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Servlet2:
package com.lyc.lesson.servlet;
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.io.PrintWriter;
@WebServlet("/Servlet2")
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("请求重定向");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
关于请求转发和重定向的路径问题
请求转发
是服务器行为,服务器根路径是项目名,
所以发请求,从/开始,不会丢失项目名
重定向
是浏览器行为,浏览器根路径是端口
所以发请求,从/开始,就会丢项目名
解决丢项目名的方法:
// req.getContextPath(); // 获得项目名
resp.sendRedirect(req.getContextPath()+"/redirect2"); // 拼接项目名
这样即使在重定向内路径也可以加/。
Cookie和Session
什么是cookie以及cookie的作用
cookie是浏览器支持的一种本地存储机制。一般由服务端设置生成
,在响应请求时被自动存储在浏览器中
。
cookie是为了辨别用户身份的。我们知道HTTP本身是无状态的协议
,服务端不会记得是谁向它发来的请求。但在某些情况下我们需要记住用户在未登录的状态下浏览了什么,比如淘宝。这时候就需要借助我们的Cookie了。 客户端请求服务器后,如果服务器需要记录用户状态,服务器会在响应信息中包含一个Set-Cookie
的响应头,客户端会根据这个响应头存储Cookie信息。再次请求服务器时,客户端会在请求信息中包含一个Cookie请求头,而服务器会根据这个请求头进行用户身份、状态等较验。
创建cookie、响应到浏览器
package com.lyc.lesson.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建cookie对象
Cookie cookie = new Cookie(key,value);
//通过响应将cookie对象添加到浏览器
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
获取cookie的值
package com.lyc.lesson.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建cookie对象,解决中文乱码问题
Cookie cookie = new Cookie("username","admin");
//通过响应将cookie对象添加到浏览器
resp.addCookie(cookie);
//通过请求获得站点上的所有cookie对象
Cookie[] cookies = req.getCookies();
//遍历所有cookie对象,得到数据
for (int i = 0; cookies != null && i < cookies.length; i++) {
Cookie ck = cookies[i];
String name = ck.getName( );
String value = ck.getValue( );
System.out.println(name+"="+value );
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
删除cookie
cookie是没有删除方法的,只能靠最大生命(setMaxAge
)值来确定cookie的存活时间。cookie默认的生命周期是会话结束时(浏览器关闭),就销毁。同时也可以设置cookie的生命周期。
setMaxAge(int expiry);
- 大于0,存在指定的
秒
- 等于0,直接删除
- 小于0,一般是-1 ,保存至浏览器关闭
// 创建cookie
Cookie cookie = new Cookie("username","admin");
// 创建的cookie,默认存储到浏览器关闭.
// 可以设置时间,单位是秒!!
// cookie.setMaxAge(30);
// cookie.setMaxAge(0); // 直接删除该cookie
cookie.setMaxAge(-1); // 保存至浏览器关闭
cookie的中文乱码问题
cookie的中文乱码指的是,cookie中的键如果取中文就会乱码。
解决中文乱码的方法:先将中文编码,在解码
package com.lyc.lesson.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建cookie对象,解决中文乱码问题
//编码:URLEncoder.encode
Cookie cookie = new Cookie(
URLEncoder.encode("姓名", "utf-8"),
URLEncoder.encode("张三", "utf-8"));
cookie.setMaxAge(60);
//通过响应将cookie对象添加到浏览器
resp.addCookie(cookie);
//通过请求获得站点上的所有cookie对象
Cookie[] cookies = req.getCookies();
//遍历所有cookie对象,得到数据
for (Cookie cookie1 : cookies) {
String name = cookie1.getName();
String value = cookie1.getValue();
//解码:URLDecoder.decode
System.out.println(URLDecoder.decode(name, "utf-8")+"="+ URLDecoder.decode(value, "utf-8"));
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
什么是Session
- session就一个接口( Httpsession ) 。
- Session就是会话。它是用来维护一个客户端和服务器之间关联的一种技术
- 每个客户端都有自己的一个session会话。
- Session会话中,我们经常用来保存用户登录之后的信息。
创建session
request.getSession();
第一次调用是:创建 Session 会话,之后调用都是:获取前面创建好的 Session 会话对象。
存数据
登录页面
<!doctype html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style type="text/css">
table{
text-align: center;
border-collapse: collapse;
}
</style>
</head>
<body>
<div>
<form action="SessionServlet" method="post">
<table border="1px" style="text-align: center;">
<tr>
<td>用户名:</td>
<td>
<input type="text" name="username" placeholder="用户名">
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" name="password" placeholder="密码">
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="登录">
<input type="reset">
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
SessionServlet:
package com.lyc.lesson.servlet;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/SessionServlet")
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//获取前端页面传来的数据
String username = req.getParameter("username");
//创建session对象
HttpSession session = req.getSession();
//将数据存入session域中
session.setAttribute("username", username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
获取session[重点]
对于session来讲,只要会话不结束,无论是请求转发还是重定向都可以获取session域中的数据。
删除session
public void setMaxInactiveInterval(int interval)
设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁。 值为正数
的时候,设定 Session 的超时时长
。负数表示永不超时
(极少使用)
//获取 Session 的超时时间
public int getMaxInactiveInterval()
//让当前 Session 会话马上超时无效。
public void invalidate()
Session和Cookie的联系和区别
区别:
- cookie数据存放在客户的
浏览器
上,session数据放在服务器
上。 - cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能, 考虑到减轻服务器性能方面,应当使用COOKIE。
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
联系: