登录时用户名或密码输入错误,给用户提示信息,重新展示登录页面。
作用:实现多个servlet联动操作处理请求,避免代码冗余,让每个servlet职责明确。
使用:
req.getRequestDispatcher("要转发的地址").forward(req, resp);
地址:相对路径,写servlet的别名即可。
特点:
一次请求(一个request),地址栏信息不改变,是访问的第一个servlet有的请求信息。
问题:请求转发过程中数据流转问题
浏览器向服务器发请求,服务器建立request对象,在进行请求转发时将request对象作为实参进行传递。
在传递过程中可以向request对象中添加数据,但后一个servlet只能删除前边添加的数据,不能删原始数据。
作用域:浏览器一次请求中所有servlet共享
使用: 解决了一次请求内的servlet的数据共享问题
req.setAttribute("object name", "object value");//添加数据
req.getAttribute("object name");//获取添加的数据,获取服务器信息
req.getParameter("username");//获取浏览器带有的信息,没有set方法
问题:使用请求转发表单数据重复提交怎么办?当前请求servlet无法处理,怎么办?
使用: resp.sendRedirect("String uri");
特点:两次请求(两个request),浏览器地址栏信息改变,避免表单重复提交
第一次用pageservlet呈现登录页面,点击提交给proveservlet处理,如果登录失败,添加提示信息请求转发给pageservlet处理(拥有所有原请求信息),登录成功重定向到mainservlet(第二次新的请求,直接请求mainservlet,原请求信息没有了)
转发和重定向的区别:
RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件。相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比绰号叫“浏览器”的人写信找张三借钱,张三没有钱,于是张三找李四借了一些钱,甚至还可以加上自己的一些钱,然后再将这些钱汇给了“浏览器”。可见,“浏览器”只发 出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程。 对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute方法传递预处理结果,那就应该使用RequestDispatcher.forward方法。
HttpServletResponse.sendRedirect 方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。相对URL以“/”开头,它是相对于整个WEB站点的根目录。对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的 访问请求,这个过程好比有个绰号叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。于是,“浏览器”又按张三提供通信地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。可见,“浏览器”一共发出了两封信和收到了两次回复, “浏览器”也知道他借到的钱出自李四之手。HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。
————————————————
版权声明:本文为CSDN博主「liubin5620」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liubin5620/article/details/79922692
相对路径:从当前请求的路径查找资源的路径
问题:如果servlet的别名中包含目录,会造成重定向资源查找失败。
绝对路径:
写法:/ 虚拟项目名 / 资源路径 (第一个 / 表示服务器根目录)
相对路径:
绝对路径:
写法:/ 资源路径 (第一个 / 表示项目根目录)
作用: 后面发起的请求可能会用到之前提交过的信息,利用cookie,解决了发送的不同请求的数据共享问题
使用: cookie的创建和存储:
1.创建cookie对象,一个cookie对象存储一条键值对,存多个创建多个对象
Cookie c=new Cookie("mouse","thinkpad" );//键,值
2.设置cookie
//设置有效期,定时存储
c.setMaxAge(3*24*60*60);//以秒为单位
//设置有效路径
c.setPath("/Cookie/abc");//只在访问abc时cookie中附带该信息
3.添加cookie信息到响应
resp.addCookie(c);
cookie的获取:
1. 获取Cookie数组
2.遍历数组
Cookie[] cks=req.getCookies();//如果没有cookie返回null
if(cks!=null)
{//防止有空指针异常
for(Cookie ck:cks)
{
String name=ck.getName();
String value=ck.getValue();
System.out .println(name+"::"+value);
}
}
特点:数据存在浏览器,是浏览器端的存储技术,存储的数据声明在服务器
临时存储:浏览器内存中,浏览器关闭即失效
定时存储:设置有效期,就会存储在硬盘中,在有效期内符合路径要求的请求信息都会附带该信息
有效路径:默认cookie信息存储好之后,每次请求cookie都会附带,除非设置有效路径。)
package learn.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
//获取cookie信息
Cookie[] cks=req.getCookies();//如果没有cookie返回null
if(cks!=null)
{//防止有空指针异常
for(Cookie ck:cks)
{
String name=ck.getName();
String value=ck.getValue();
System.out .println(name+"::"+value);
}
}
//获取用户信息
//处理信息
//给出响应
//直接响应
resp.getWriter().write("cookie 学习");
//重定向
//请求转发
//使用Cookie进行浏览器端数据缓存
//1.创建cookie对象
Cookie c=new Cookie("mouse","thinkpad" );//键,值
Cookie c2=new Cookie("key","lenovo");
//2.设置cookie
//设置有效期
c2.setMaxAge(3*24*60*60);//以秒为单位
//设置有效路径
c2.setPath("/Cookie/abc");
//3.添加cookie信息到响应
resp.addCookie(c);
resp.addCookie(c2);
}
}
五、三天免登录
第一次登录page展示登录界面没有cookie信息,prove处理后如果用户名-密码匹配,重定向到main页面,第二次登录,有cookie不需要填写用户名密码,直接响应main页面。所以需要校验有没有cookie信息,需要另外创建一个Servlet,作为登录的入口,它决定是page展示登录界面还是直接响应main页面。