基于前面两篇文章,我们已经具备一定的servlet基础,接下来我们要对servlet做更深入的剖析,这篇文章主要针对请求转发、重定向、Cookie、Session、ServletContext、servletConfig的作用以及使用方式做一个总结,并针对这些知识点做了一个小的web应用,读者如果需要可以在github上进行下载,下载链接:https://github.com/hlc0216/Login。
req.getRequestDispatcher("要转发的地址").forward(req, resp); //地址:相对路径,直接书写servlet的别名即可
问题:使用请求转发后,不同的sevlet之间怎么进行数据的共享呢?或者说数据怎么从一个servlet流转给另外一个servlet呢?
解决方法:使用request对象的作用域
request.setAttribute(Object name,Object value);
request.getAttribute(Object name);
问题1:如果当前的请求,servlet无法进行处理怎么办?如果使用请求转发,造成表单数据重复提交怎么办?
解决:使用重定向
Response.sendRedirect(“路径”); //本地路径为:uri ;网络路径为:定向资源的url
问题2:请求转发和重定向的区别?
解答:
创建cookie对象:
Cookie ck =new Cookie("mouse", "lenovo");
设置cookie:
ck.setMaxAge(3*60*60); //设置cookie的有效期(以秒为单位)
ck.setPath("test"); //设置cookie的有效路径
响应cookie信息给客户端:
resp.addCookie(ck);
cookie的获取
Cookie[] cks = req.getCookies()
遍历数组获取cookie信息
if (cks != null) {
for (Cookie c : cks) {
String name = c.getName();
String value = c.getValue();
System.out.println(name + ":" + value);
}
}
- 注意:
- 一个Cookie对象存储一条数据;创建多条数据可以创建多个cookie对象;
- 存储的数据声明在服务器端:
临时存储:存储在浏览器的运行内存中,浏览器关闭即失效。
定时存储:设置了cookie的有效期,存储在客户端的硬盘中,在有效期内符合路径要求的>请求都会附带该信息。- 默认cookie信息存储好之后,每次请求都会附带,除非设置有效路径。
问题:一个用户的不同请求处理的数据共享怎么办??
解决:使用Session技术
用户第一次访问服务器,服务器会创建一个session对象给用户,并将该session对象的
JSESSIONID使用Cookie技术存储到浏览器中,保证用户的其他请求能够获取到同一个session对象,也保证了不同请求能够获取到共享数据。
特点:
作用:解决了一个用户不同请求处理的数据共享问题
使用方式:
HttpSession hs = req.getSession();
- 如果请求中拥有session的标识符即JSESSIONID,则返回其对应的session对象。
- 如果请求中没有session的标识符即JSESSIONID,则创建新的session对象,并将其JSESSIONID作为cookie数据存储到浏览器中。
- 如果session对象失效了,也会重新创建一个session对象,并将其JSESSIONID存储在浏览器内存中。
注意:JSESSIONID存储在Cookie的临时存储空间中,浏览器关闭即失效。
hs.setMaxInactiveInterval(30*60);//单位是秒
注意:在指定时间内的session对象没有被使用则销毁,如果使用了则重新计时。
hs.setAttribute(String name, Object value);//存储
hs.getAttribute(String name);//获取,返回的数据类型为Object
注意:存储的动作和取出的动作发生在不同的请求中,但是存储要先于获取执行。
使用时机:一般用户在登陆web项目时会将用户的个人信息存储到Sesion中,供该用户的其他请求使用。
总结:
- Session解决了一个用户的不同请求的数据共享问题,只要在JSESSIONID不失效和swssion对象不失效的情况下。
- 用户的任意请求在处理时都能获取到同一个session对象。
- 作用域:一次会话(在JSESSION和session对象不失效的情况下为整个项目内)
- Session 失效处理:将用户请求中的JSESSIONID和后台获取的session对象的JSESSIONID进行比对,如果一致则session没有失效,如果不一致则证明session失效了(当然还有其他方法比如判断是否是
null
),重定向到登陆页面,让用户重新来过。
Cookie和Session的区别
问题:Request解决了一次请求内的数据共享问题,Session解决了同一用户不同请求的数据共享问题,那么不同用户间的数据共享该怎么办呢??
解决:使用servletContext对象解决不同用户的数据共享问题。
//第一种方式
ServletContext sc =this.getServletContext();
//第二种方式
ServletContext sc2 = this.getServletConfig().getServletContext();
//第三种方式
ServletContext sc3 = req.getSession().getServletContext();
//数据存储
Sc.setAttribute(String name,Object value);
//数据获取
Sc.getAttribute(String name);
注意 :
- 不同的用户可以给ServletContext对象进行数据的存取
- 存取的数据不存在返回null
sc.getInitParameter(String name);//根据键的名字返回String类型的值
Sc.getInitParameterNanmes();//返回键名的枚举
配置方式:一组
标签只能存储一组键值对数据,多组可以声明多个
进行存储
<context-param> <param-name>namepara-name> <param-value>valuepara-value> context-param>
作用:将静态数据和代码进行解耦。
获取项目webroot下的资源
//获取项目根目录下的资源的绝对路径
String path=sc.getRealPath(String path);
String path=sc.getRealPath("/doc/1.txt");
获取的路径为项目根目录,path参数为根目录中的路径
//获取webroot下的资源的流对象
InputStream is = sc.getResourceAsStream(String path);
注意:此种方式只能获取项目根目录下的资源流对象,class文件的流对象需要使用类加载器获取。
问题:如何获取web.xml中每个servlet单独配置的数据呢?
解决:使用servletConfig对象
使用如下:
<init-param>
<param-name>configparam-name>
<param-value>utf-8param-value>
init-param>
//获取ServletConfig对象
ServletConfig sc = this.getServletConfig();
String str = sc.getInitParameter("config");
作用: 存储项目相关的配置信息,保护servlet,解耦一些数据对程序的依赖。
使用位置:(1)每个web项目中 (2) tomcat服务器中
区别:web项目下的web.xml文件为局部配置,针对本项目的位置,Tomcat下的web.xml文件为全局配置,配置公共信息。
内容(核心组件)
- 全局上下文配置(全局配置参数)
- servlet配置
- 过滤器配置
- 监听器配置
加载顺序:web容器会按照servletContext->context-param->listener->filter->servlet这个顺序加载组建,这些元素可以配置在web.xml文件中的任意位置。
加载时机:服务器启动
- 浏览器发送请求到服务器(请求)
- 服务器接收浏览器的请求,进行解析,创建request对象存储请求数据
- 服务器调用对应的servlet进行请求处理,并将request对象作为实参传递给servlet的方法
- servlet的方法执行进行请求处理(这是我们程序员做的,上面是服务器自动帮我们做的)
//设置请求编码格式 //设置响应编码格式 //获取请求信息 //处理请求信息 //创建业务层对象 //调用业务层对象的方法 //响应处理结果
- 数据流转流程
浏览器–》服务器–》数据库
数据库–》服务器–》浏览器