Cookie是浏览器提供的一种技术,通过服务器的程序将一些只需保存在客户端,或者在客户端的进行处理的数据,放在本地计算机上,不需要通过网络传输,因而提高网页处理的效率,并且能够减少服务器的负载,但是由于cookie是服务器端保存在客户端的信息,所以其安全性很差。例如常见的记住密码则可以通过Cookie实现。
1.2 Cookie的创建与发送@WebServlet("/cook01")
public class Cookie01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("name", "admin");
//发送(响应cookie)
resp.addCookie(cookie);
}
}
1.3cookie对象的获取
@WebServlet("/cook02")
public class Cookie02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//cookie的获取 返回的cookie数组
Cookie[] cookies = req.getCookies();
//判断是否为空
if(cookies != null && cookies.length > 0 ){
//遍历cookie数组
for (Cookie cookie : cookies) {
//获取cookie的名称和值
String name = cookie.getName();
String value = cookie.getValue();
System.out.println("名称:" + name + "值:" + value);
}
}
}
}
1.4 Cookie设置到期时间
@WebServlet("/cook03")
public class Cookie03 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//到期时间 负整数(默认值-1 表示只在浏览器内中存活,关闭浏览器失效)
Cookie cookie = new Cookie("name", "zhanhsan");
cookie.setMaxAge(-1);
resp.addCookie(cookie);
//到期时间 正整数(表示存活指定的秒数,会将数据存在磁盘中)
Cookie cookie2 = new Cookie("name2", "lisi");
cookie2.setMaxAge(30);
resp.addCookie(cookie2);
//到期时间:零(表示删除cookie)
Cookie cookie3 = new Cookie("name3", "wangwu");
cookie3.setMaxAge(0);
resp.addCookie(cookie3);
}
}
1.5 Cookie注意点
1.cookie保存在当前的浏览器中。
在一般的站点常常有记住用户名这一个操作,该操作只是将信息保存在本机上,换电脑后这些信息就无效了。而且cookie还不能跨浏览器。
2.Cookie存中文问题
Cookie中不能出现中文 ,如果实在想存中文则通过URLEncoder.encode()来进行编码,获取时使用URLDecoder.decode()来进行解码。
3.同名Cookie问题
如果服务器发送重复的Cookie那么会覆盖原有的Cookie。
4.浏览器存放Cookie数量
不同的浏览器对Cookie也有限定 Cookie的存储是有上限的。Cookie时存储在客户端(浏览器)的,而且一般是由服务器创建设定。后期集合session来实现会话跟踪
Cookie的setPath设置cookie的路径,这个路径直接决定服务器的请求是否会从浏览器中加载某些cookie。
@WebServlet("/cook04")
public class Cookie04 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.设置路径为”/“ 表示在当前服务器下任何项目都可以访问到Cookie对象
Cookie cookie = new Cookie("name", "admin");
cookie.setPath("/");
resp.addCookie(cookie);
//2.设置路径为”/hello“ 当前目录下的资源可以访问到Cookie对象
Cookie cookie2 = new Cookie("name", "admin");
cookie2.setPath("/hello");
resp.addCookie(cookie2);
//3.设置路径为”/hello2“ 表示在hello2项目下才可以访问到Cookie对象
Cookie cookie3 = new Cookie("name", "admin");
cookie3.setPath("/hello2");
resp.addCookie(cookie3);
//4.设置路径为”/hello/cook02“ 表示在hello2项目下的cook02站点才可以访问到Cookie对象
Cookie cookie4 = new Cookie("name", "admin");
cookie4.setPath("/hello2/cook02");
resp.addCookie(cookie4);
}
}
1.6 Session介绍
对于服务器而言,每个连接到它的客户端都是一个session,servlet容器使用此接口创建HTTP客户端和HTTP服务器之间的会话。会话将保留指定的时间段,跨多个连接或来自用户的页面请求。一个会话通常对应于一个用户,该用户可能多次访问一个站点。可以通过此接口查看和操作有关某个会话的信息,比如会话标识符、创建时间和最后一次访问时间。在整个session中,最重要的就是属性的操作。
session无论客户端还是服务器端都可以感知到,若重新打开一个新的浏览器,则无法取得之前设置的session,因为每个session只保存在当前的浏览器中,并在相关的页面取得。
Session的作用就是标识一次会话,或者说确认一个用户;并且在一次会话(一个用户的多次请求)期间共享数据。使用req.getSeesion()方法来获取当前的session对象。
Session既然十为了标识一次会话,那么此此次会话就应该有一个唯一的标志,这个标志就是session id。
每当一次请求到达服务器时,如果开启了会话(访问了session),服务器第一步会查看是否从客户端回传一个名为JESSIONID的cookie,如果没有则认为这是一次新的会话,会创建一个新的session对象,并用唯一的sessionid为此次会话做一个标志。如果有JESSIONID这个cookie回传,服务器会个根据JESSIONID这个值去查看是否有id为JSESSION值得session对象,如果没有则认为这是一个新的会话。重新创建一个新的session对象,并标志此次会话;如果找到了相应得session对象,则认为是之前标志过的一次会话,返回该session对象,数据达到共享。
这里提到的一个叫做JESSIONID的cookie,当用户请求服务器时,如果访问了session 则服务器会创建一个名为JESSIONID,值为session(无论获取到的还是新建的)的sessionid的cookie对象吗,并添加到response对象中,响应给客户端。
session 用来标识一次会话,在一次会话中数据是共享的,这时session作为域对象存在,可以通过setAttribute(name,value)方法向域对象中添加数据,通过getAttribute(name)从域对象中获取数据,通过removeAttribute(name)从域对象中移除数据。
数据存储在session域对象中,当session对象不存在了,或者是两个不同的session对象时,数据也就不能共享了。这就不得不谈到session得生命周期。
@WebServlet("/session02")
public class Session02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
//设置session域对象
session.setAttribute("name","lukecheng");
session.setAttribute("password","123456");
//移除session域对象
session.removeAttribute("password");
//req域对象
req.setAttribute("name","zhangsan");
//请求转发跳转到jsp页面
req.getRequestDispatcher("index.jsp").forward(req,resp);
//重定向到jsp(重定向是服务器向客户端说明跳转地址,因此使用resp)
resp.sendRedirect("index.jsp");
}
}
1.9 ServlertContext对象
每一个web应用都有仅有一个ServletContext对象,又称Application对象,从名称中可知,该对象是与应用程序相关得。在web容器启动得时候,会为每一个web应用程序创建一个对应得ServletContext对象。
该对象有两个作用,第一、作为域对象用来共享数据,此时数据在整个应用程序中共享;第二,该对象保存了当前应用程序得相关信息。例如可以通过getServerInfo()方法获取当前服务器信息。getRealPath(String path)获取资源得真实路径等等。
@WebServlet("/hello")
public class ServletContext01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、通过req获取servletContext对象
ServletContext servletContext = req.getServletContext();
//2、通过session对象获取
ServletContext servletContext1 = req.getSession().getServletContext();
//3、通过servletConfig对象获取,在servlet标准中提供了ServletConfig方法
ServletConfig servletConfig =getServletConfig();
ServletContext servletContext2 = servletConfig.getServletContext();
//4、直接获取
ServletContext servletContext4 = getServletContext();
//常用方法:
//1,获取当前服务器得版本信息
String serverinfo = req.getServletContext().getServerInfo();
System.out.println("当前服务器得版本信息:"+serverinfo);
//2.获取项目得真实路径("/:根路径")
String realPath = req.getServletContext().getRealPath("/");
// 当前项目得根路径:D:softwaretomcatapache-tomcat-10.0.20webappsss04
//ss04:tomcat虚拟数目
System.out.println("当前项目得根路径:" + realPath);
}
}
1.9 ServlertContext域对象
ServlertContext当然也可以作为域对象来使用,通过向ServletContext中存取数据,可以使整个应用程序共享某些数据。当然不建议存放过多得数据,因为ServlertContext中的数据一旦存储进去没有手动移除将会一直保存。
@WebServlet("/hello2")
public class ServletContext02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取ServlertContext对象
ServletContext servletContext = req.getServletContext();
//2.设置域对象
servletContext.setAttribute("name","zhangsan");
//3.获取域对象
String name = (String) servletContext.getAttribute("name");
//4.移除域对对象
servletContext.removeAttribute("name");
}
}
Servlet的三大域对象
1.request对象
在一次请求中有效。请求转发有效(请求转发是在服务器内部完成的,因此是仍是一次请求),重定向失效。
2.session域对象
在一次会话中有效,请求转发和重定向有效,session销毁后失效
3.ServletContext对象
二、JSP和标准库JSTL的使用 2.1、Scriptlet在整个应用程序中有效,服务器关闭后失效
在JSP中最重要的就是Scriptlet(脚本小程序),所有嵌入在HTML代码中的java程序。在JSP中一共有三种Scriptlet代码:都必须使用Scriptlet标记起来。
第一种:<% %>:java 脚本段 可以定义局部变量 编写语句
第二种:<%! %>:声明,可以定义全局(成员)变量,方法,类
第三种:<%= %>: 输出表达式,可以输出变量或者字面量
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--java 脚本段 可以定义局部变量 编写语句--%>
<%
//定义局部变量
String str = "hello jsp";
//输出内容
System.out.println(str);
//响应到浏览器
response.getWriter().print(str);
//测试全局变量
System.out.println("全局变量:" + num);
%>
<%--声明,可以定义全局(成员)变量,方法,类--%>
<%!
//声明全局变量
int num = 10;
%>
<%--输出表达式,可以输出变量或者字面量--%>
<%=str%>
2.1、JSP的指令标签
使用包含操作,可以将一些重复的代码包含进来继续使用,从正常的页面组成来看,有时可能分为几个区域,而其中的一些可能是一直不需要改变的,改变的就其中一个具体内容的区域。这就是JSP的包含操作。有两种:静态包含和动态包含
1.静态包含:
静态包含就是将内容进行了直接的替换,就好比程序中定义的变量一样 是在servlet引擎转译时,就把文件内容包含了进去(两个文件的源代码整合在了一起),所以只生成了一个servlet,所以两个页面不能有同名的变量。运行效率高一点点,但耦合度较高,不够灵活。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--
静态包含: <%@include file=要包含的文件地址(相对路径)"%>
--%>
<%@include file="jsp02header.jsp"%>
主题内容
<%@include file="jsp02footer.jsp"%>
1.动态包含:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--动态包含:
动态包含传递参数
注意:name属性不支持表达式,value属性支持表达式
获取参数:
request.getParameter(name);指定参数名获取参数值
--%>
主体内容
<%--动态包含传递参数--%>
<%
String url = "jsp02footer.jsp";
String str = "hello";
%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
底部内容
<%
//获取动态包含传递的参数
String uname = request.getParameter("uname");
String msg = request.getParameter("msg");
System.out.println("uname:"+uname);
System.out.println("msg:"+msg);
%>
2.3、JSP的四大域对象
2.4、EL表达式的使用
在这里插入代码片<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %><%--
Created by IntelliJ IDEA.
User: 克成
Date: 2022/8/3
Time: 21:54
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
Title
<%
List list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list",list);//保存到域对象
Map map = new HashMap<>();
map.put("aaa",111);
map.put("bbb",222);
map.put("ccc",333);
request.setAttribute("map",map); //保存到域对象
%>
获取list
获取List的size:${list.size()}
获取List的指定的下标值:${list[1]}
获取map
<%--
获取map中指定key的value:
${map.key}--${map["key"]}
--%>
获取map指定的key的value:${map.aaa}--${map["bbb"]}
@WebFilter("/s01") //拦截路径是s01的资源 可以写
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Filter01正在被拦截....");
//放行资源
chain.doFilter(request,response);
System.out.println("访问到了servlet回来继续执行Filter的逻辑代码");
}
@Override
public void destroy() {
System.out.println("Filter01 destroy...");
}
}
@WebServlet("/s01")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet01...");
}
}
@WebServlet("/s02")
public class Servlet02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet02...");
}
}
注意:
- @WebFilter(“/*”) //配置拦截的资源路径
- doFilter()方法中需要设置放行,否则请求无法到达资源
- 如果是过滤器链,则先配置的先执行(首字母在前的先执行) 响应时,顺序返回过来即可。



