Servlet 对象是由tomcat创建并维护的
Servlet类里面有两个方法,doGet(),doPost(),分别处理浏览器发送到服务器端的get请求和post请求(超链接是get请求)
Servlet是服务端小程序,由Java语言编写的,可以生成动态的网页,主要用来处理数据,实现业务逻辑功能
创建一个Servlet要点:
Servlet类要继承HttpServlet, Servlet的定义要继承或实现API接口(还可以通过实现接口或者继承其他的抽象类来定义Servlet)
在web.xml中配置Servlet(告知tomcat有servlet)
Servlet在使用中,我们只定义了类,没有创建过对象。
Servlet对象是由容器(tomcat)创建的。
生命周期:servlet对象从创建到销毁回收的整个过程。
生命周期的各个阶段转换的时候会调用生命周期方法。
创建(加载):web容器创建servlet实例(对象),要调用servlet类的构造方法。容器加载对象默认是在对象第一次被访问的时候,我们可以根据情况修改为:服务器一启动就创建对象。
初始化:完成一些需要在用户访问之前就做的工作,比如:JDBC连接数据库,读取一些资源类文件,初始化阶段会调用生命周期方法init()
服务(处理请求):servlet的正常运行,处理浏览器发送的请求。 销毁:删除servlet对象,并不是主动删除,从容器里面删除这个对象,释放它占用的资源,会调用生命周期方法destroy();通常用来释放JDBC连接,关闭曾经打开的文件。
回收(卸载):把destroy了的对象当垃圾回收掉。 1) 用户在浏览器地址栏输入一个地址,回车。
2) 用户在浏览器里面点击了一个超链接
百度一下
3) 用户在页面上单击form的submit按钮,提交数据
前面两种操作发出的都是GET类型的请求,第三种可以发出get和post两种请求。Get方法会把参数放在http请求头里面,由长度限制,不安全。Post方法会把参数放在http专门的请求数据域里面,长度比放在请求头里面大很多,可以加密。 1.常用的HTTP请求类型:get和post
不常用的类型:delete put HEAD TRACE 1.获取请求中携带的参数(一般是表单)
常用的方法getParameters(“参数名称”)
String u1=request.getParameters(“user”);
String pwd=request.getParameters(“pwd”);
u1,pwd:我们在doget方法中定义的局部变量,获取的表单的数据暂存在里面。默认都是String类型,如果实际参数是其他类型,比如int,要进行数据类型转换。
“user”,”pwd”
注意1:要加双引号 注意2:他们是在表单里文本框的name属性定义的 2.out对象往浏览器输出一个HTML文件
如果参数获取不到,会返回null;
要保证获取的参数是唯一的
其他的获取参数的方法
String[] getParameterValues(“参数名称”)
对于request来说,服务器端跳转 Forward()转发页面的时候,浏览器的地址栏还是servlet的地址,并没有转到success.jsp Include()跳转页面的时候,浏览器的地址栏还是servlet的地址,并没有转到success.jsp 区别: Forward,将请求转发到服务器上的一个资源,当前servlet里面,forward之后的代码不再执行。 Include,把另一个资源的执行结果包含在当前的servlet里面(跳转到零一个资源文件执行,执行完成之后返回来继续执行。),include后面的代码会继续执行。 Forward和include都不要在out.flush之后执行,结果输出不了,(out.flush是向浏览器输出整个文件)forward会报错。
响应 由服务器发送到客户端浏览器的http消息,称为响应 相应HTTP,由HTTP头和HTTP体(响应数据)组成
1)输出流 PrintWriter: 被servlet用来产生动态页面,用于向客户端浏览器发送文本数据。 ServletOutStream,Servlet用来像客户端发送二进制文件。
2)设置输出数据格式 response.setCharacterEncoding(“utf-8”); response.setHeader(“Content-Encoding”,”utf-8”); response.setContentType(“text/html;charset=utf-8l”);
3)相应重定向 用response实现跳转 response.sendRedirect("./success.jsp");
浏览器地址栏的地址不会发生变化
Request.dispatcher.forward();
把当前页面的部分替换成了目标页面,forward语句后面的语句不会再执行
Request.diapatcher.include();
把目标页面包含进当前页面中,include语句后面的语句会继续执行
Response.sendRedirection():重定向,结束了当前的请求,发出响应(服务器给客户端的HTTP请求),浏览器地址栏的地址发生了改变
内置变量:tomcat定义好的变量,我们可以直接通过get***()获取使用,不用自己去new
会话:内置变量的作用范围
Session和Cookie
获取应用程序和Servlet的初始化配置信息
获取Servlet的配置信息(web.xml里面)
9.10和9.11两个例子
1)ServletConfig对象怎么获取
①在init(带参数的形式)里面直接使用Tomcat传递来的实参
②在doGet(doPost)里面直接调用get***()获取
2)怎么通过ServletConfig 获取web.xml里面Servlet的参数列表ServletContext
Servlet上下文
ServletContext 是一个内置对象,属于整个应用程序的
ServletContext是作用域是整个应用程序
1) ServletContext 对象的获取方式
调用:getServletContext()方法
2) 在不同的servlet之间传递信息
public class DServlet extends HttpServlet { private String initParm=null; public DServlet() {} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //System.out.println("初始化参数:"+this.initParm); ServletContext context = getServletContext(); context.setAttribute("username", "jack"); context.setAttribute("password", "123456"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } } public class FServlet extends HttpServlet { public FServlet() {} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String s1 = (String) getServletContext().getAttribute("username"); String s2 = (String) getServletContext().getAttribute("password"); System.out.println(s1+s2); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }京东登录之后,浏览很多页面,选择物品放入购物车,结算,到结算的时候,是不需要登录
1.session怎么获取
public class GServlet extends HttpServlet { private static final long serialVersionUID = 1L; public GServlet() {} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //创建时间 long creationTime = session.getCreationTime(); //设置属性值 session.setAttribute("username", "李兴华"); //最后访问的时间 long lastAccessedTime = session.getLastAccessedTime(); //获取最大不活动时间间隔 session多少时间不活动,就会销毁 int interval = session.getMaxInactiveInterval(); System.out.println("A creat time:"+creationTime); System.out.println("A sessionID:"+session.getId()); System.out.println("A username属性内容:"+session.getAttribute("username")); System.out.println("A last request time:"+lastAccessedTime); System.out.println("A interval:"+interval); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }运行结果:
2.会话管理
一个浏览器打开网页第一次访问的时候,服务器会从reqeust里面获取Session对象,获取不到就创建,之后在浏览器和服务器之间的所有的访问里面,http请求都会携带该session的信息。
浏览器关闭:原session对象失效,因为新打开的浏览器不携带原来的session访问服务器,服务器会为这次会话创建新的session
浏览器没有关闭,但是session设置了失效时间30分钟,浏览器如果30分钟没有发送新的请求,session对象被服务器销毁(销毁时间可以通过xml文件设置)
Cookie(小饼干)
1)Cookie是客户访问Web服务器时,服务器在客户端的硬盘(内存)里面存放的小信息(实际上是一小段文本信息)
服务器发送给客户端之后,客户端再访问服务器,都会携带该信息
客户端在访问某个服务器时候会把所有该服务器写来的cookie都携带上
SESSIONID 也就是会话中每次请求和响应都携带的会话的ID,就是通过cookie携带的
2)使用
public class AServlet extends HttpServlet { private static final long serialVersionUID = 1L; public AServlet() {} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* 用户从登录界面登录信息传递到当前的servlet里面 获取登录信息之后,把登录的用户名放入一个Cookie 把Cookie发送回客户端浏览器 在本次会话内客户端之后每次访问服务器都会携带该Cookie, 我们就可以在其他的页面里面通过获取Cookie来获取登录信息 */ String username = request.getParameter("username"); String password = request.getParameter("pwd"); /* * 1.创建一个Cookie,就是直接使用new创建对象 * 参数:一个键值对 * 第一个String 是要放入的信息的名称 * 第2个String 放入的信息的值 * */ Cookie cookie = new Cookie("username", username); Cookie cookie1 = new Cookie("password", password); /* 设置Cookie在客户端的有效时间 * 设置单位是int,秒数 * */ cookie.setMaxAge(60); /* * 2.发回客户端 * 1)把创建的cookie添加到response * 2)使用客户端跳转,把信息发回客户端 * 注意不要使用服务器端跳转 * */ response.addCookie(cookie); response.addCookie(cookie1); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } } public class BServlet extends HttpServlet { private static final long serialVersionUID = 1L; public BServlet() {} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); for(int i=0;i<cookies.length;i++) { if(cookies[i].getName().equals("username")) { System.out.println("用户名是:"+cookies[i].getValue()); } System.out.println(i+":"+cookies[i].getName()+":"+cookies[i].getValue()); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }运行结果
作用域:一个对象的存在周期
1) 应用程序级别
存储在应用程序里面的对象,它可以被应用程序内的所有的servlet,jsp访问
例如:Aservlet放进去一个参数,其他的Servlet或者jsp都可以随时获取(只要服务器没关闭,应用程序没停止,参数没有被remove)
例如:ServletContext
2) 会话作用域
在一次会话周期之间存在的对象,从会话开始到会话结束的周期内,servlet和jsp可以访问,会话结束,则对象就不存在了
例如:HttpSession
3) 请求作用域
处理同一个请求的组件(servlet,jsp)可以访问该对象
例如:Request
4) 页面作用域
一般用在jsp里面,存储在页面作用域的对象只能在他们所定义的转换单元中被访问
往不同的域对象里面放置属性值都使用setAttribute(), 获取属性的值都使用getAttribute()
setAttribute()可以放入很复杂的参数,
四种作用域的使用
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> This is my JSP page. <br> <a href="servlet/BServlet">BServlet</a><br/> <a href="servlet/CServlet">CServlet</a><br/> <form action="servlet/AServlet"> <input type="text" name="user"/><br/> <input type="text" name="user"/><br/> <input type="submit" value="login"/> </form> </body> </html> <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'MyJsp.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> This is my JSP page. <br> <!-- jsp中显示一个java变量的值,此处显示从请求作用域对象request里面获取的名字为user的数据的值 --> <%=request.getAttribute("requestUser") %><br/> <!-- 显示会话域级别对象session里面名字为sessionUser的数据的值 --> <%=session.getAttribute("sessionUser") %><br/> <!-- 显示应用程序域界别对象context里面名字为contextUser的数据的值,jsp中应用程序域对象为applicaion --> <%=application.getAttribute("contextUser") %><br/> </body> </html> public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1.获取用户在表单的文本框和密码框里面输入的值 * */ String user = request.getParameter("user"); String pwd = request.getParameter("pwd"); /* * 2.把获取的名字为user的文本框的值放入应用程序级别域对象 * */ ServletContext context = getServletContext(); context.setAttribute("contextUser", user); /* * 3.把获取的名字为user的文本框的值放入会话级别域对象 * */ HttpSession session = request.getSession(); session.setAttribute("sessionUser", user); /* * 4.把获取的名字为user的文本框的值放入请求级别域对象 * */ request.setAttribute("user", user); /* * 5.服务器端跳转 * 服务器收到一个HTPP请求,内部完成了一个页面跳转,没有发回响应让客户端重新请求一个新页面 * MyJsp.jsp是服务器内部跳转的,不是客户端发来一个新请求显示的,所以在一次请求范围内 * 用此段代码,MyJsp.jsp页面里面能获取到request级别里面的数据 * */ //request.getRequestDispatcher("/MyJsp.jsp").forward(request, response); /* * 6.客户端跳转 * 服务器收到HTTP请求后,发一个重定向相应给客户端, * 可以理解为客户端收到响应后又发了一个请求,请求的是MyJsp.jsp页面 * 这种方式显示的MyJsp.jsp页面,与之前的index.jsp页面是两个请求,无法获取request里面的数据 * */ response.sendRedirect("./MyJsp.jsp"); } } public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 获取应用程序级别域对象里的数据 * */ ServletContext context = getServletContext(); String user = (String)context.getAttribute("contextUser"); /* * 获取会话级别域对象里的数据 * */ HttpSession session = request.getSession(); String user1 = (String)session.getAttribute("sessionUser"); /* * 获取请求界别域对象里的数据 * */ String user2 = (String)request.getAttribute("user"); System.out.println("context user:"+user); System.out.println("session user:"+user1); System.out.println("request user:"+user1); } }实现的功能:
浏览多个页面,把选中的物品添加到购物车里面,打开购物车页面可以显示购物车里的物品(登录用户,非登录用户)
非登录用户:登录Jd,放入购物车的物品,换个浏览器浏览(或者是间隔一定的时间后再打开网页),购物车的物品清空——非登录用户放入购物车的物品是基于Session实现的,
登录用户,放入购物车的物品会永远都在(只要登录就能查看到),——登录用户放入购物车的物品是和用户名关联的,修改了该用户在数据库里的数据
用户在登录界面登录后,打开的每个页面,都会提示“欢迎”(Cookie)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJxg4qYg-1601896516169)(D:\青职课堂笔记\Javaweb讲义\img\9-27-cart2.png)]
问题:怎么向index.jsp页面返回alert(提示)?
public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1.定义购物车数据结构ArrayList对象引用 * */ ArrayList<String> cartList; /* * 2.获取要被添加到购物车里的商品的信息(编号) * mate20.jsp里面 * servlet/AServlet?id=mate20 * 获取的是?后面的id=mate20,变量thing里面就存储了mate20 * */ String thing = request.getParameter("id"); /* * 3.从session里面获取购物车对象ArrayList * */ HttpSession session=request.getSession(); cartList = (ArrayList<String>) session.getAttribute("cartList"); /* * 如果返回结果为空 * session里面还没有购物车对象 * 这是添加到购物车里面的第一件商品 * */ if(cartList==null) { cartList = new ArrayList<String>(); } /* * 4.在购物车对象里面添加物品 * */ cartList.add(thing); /* * 5.把更新后的购物车放入会话域对象,jsp页面里面就可以直接获取最新的购物车对象了 * */ session.setAttribute("cartList", cartList); /* * 6.跳转到购物车展示页面 * */ response.sendRedirect("../cart.jsp"); } } public class loginServlet extends HttpServlet { /* * 登录验证 * 登录成功把用户名发回客户端 * */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("pwd"); if(username.equals("admin")&&password.equals("123456")) { Cookie cookie = new Cookie("username",username); cookie.setPath(request.getContextPath()); response.addCookie(cookie); //HttpSession session = request.getSession(); //session.setAttribute("username", "123123123"); response.sendRedirect("../index.jsp"); }else { // response.sendRedirect("../fail.jsp"); request.getRequestDispatcher("/index.jsp").include(request, response); } } }首页
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1>这是购物网站首页</h1><br> <% Cookie[] cookie = request.getCookies(); String test="欢迎用户:"; if(cookie!=null) for(Cookie c:cookie){ if(c.getName().equals("username")){ %> <%=test+c.getValue() %> <% } } %> <form action="servlet/loginServlet"> <input type="text" name="username"/> <input type="password" name="pwd"/> <input type="submit" value="login"/> </form> <h2>单击商品浏览细节</h2> <!-- 表格里面展示了四种商品,单击超链接可以进入商品详细页面 --> <table width="40%"> <tr> <td><a href="honor9x.jsp">荣耀9X</a></td> <td><a href="p30.jsp">华为P30</a></td> </tr> <tr> <td><a href="honor_v20.jsp">荣耀V20</a></td> <td><a href="mate20.jsp">Mate20</a></td> </tr></table> </body> </html>商品页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'honor9x.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% Cookie[] cookie = request.getCookies(); String test="欢迎用户:"; if(cookie!=null) for(Cookie c:cookie){ if(c.getName().equals("username")){ %> <%=test+c.getValue() %> <% } } %> <h1>This is 荣耀9X page. </h1> <a href="servlet/AServlet?id=honor9x">加入购物车</a><br/> <img src="image/honor9x.jpg"/> </body> </html>购物车页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'cart.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% Cookie[] cookie = request.getCookies(); String test="欢迎用户:"; if(cookie!=null) for(Cookie c:cookie){ if(c.getName().equals("username")){ %> <%=test+c.getValue() %> <% } } %> <h1>This is my 购物车 page.</h1> <br> <a href="index.jsp">返回首页</a><br/> <!-- 从会话域对象session里面获取购物车对象ArrayList --> <!-- 从ArrayList里面逐一获取商品信息,在页面上展示出来 --> <% ArrayList<String> list = (ArrayList<String>)session.getAttribute("cartList"); for(int k=0;k<list.size();k++){ String s = list.get(k); %> <%=s %> <br/> <% }%> </body> </html>1)过滤器是特殊的Servlet,它的生命周期和Servlet一样
工作方法:doFilter(),过滤器每次工作的时候,都会调用该方法。
2)通常处理一些组件的公共操作
工作机制:把一些Servlet或者jsp,HTML等组件的公共需求提取出来,用过滤器统一实现,多层嵌套(过滤器链)
定义类,实现接口
根据需要重写各个方法 实现:实现接口Filter, 重写相应的方法doFilter
在web.xml里面配置(配置方式类似Servlet),url-pattern:配置的是过滤器过滤的目标路径 /classjsp/*
监听器用于监听某个事件是否发生,如果事件发生了就触发监听器,会执行一段关联的代码
监听器是什么?是一种特殊的Servlet
监听器的实现定义类,实现接口(监听器相关接口-好几个)
Web.xml中配置监听器,只需要配置监听器类的路径
监听器的工作见案例
监听范围Javaweb的监听器,三大类
监听Request, Session Context
