一.MVC分层开发
1.概念
-
M:Model模型(service+dao+pojo)。
-
V:View视图(HTML页面+JSP页面)。
-
C:Controller控制器(Servlet)。
2.作用
将代码根据不同的功能进行分层开发(分层也就是不同的包)。
3.特点
降低代码的冗余,提高代码的重用性。
提高了代码的阅读性。
便于后期的维护升级。
降低代码之间的耦合度。
4.使用
MVC分层开发落地的使用,也就是创建不同的包,然后在不同的包中写功能不同的代码。具体的包结构如下:
com.aa.controller 编写Servlet代码
com.aa.service 编写业务层的接口
com.aa.service.impl 编写业务层的实现类
com.aa.dao 编写持久层的接口
com.aa.dao.impl 编写持久层的接口实现类
com.aa.pojo 编写实体类
5.分层后各个层的作用及代码调用情况:
二. 请求转发和请求重定向
1.请求转发
1.使用请求转发的方式
使用请求转发的方式。(forward)
作用: 在Servlet的service方法中完成其他Servlet的调用。
示例:
req.getRequestDispatcher("/Servlet2").forward(req,resp);
2.请求转发的特点
请求转发是一次请求,地址栏地址不变,还是访问第一个Servlet的地址。
请求转发是一次请求(共享请求和响应对象),所以转发内的各个Servlet共享一个request对象。
请求转发是Tomcat服务器内部的行为,用户是看不到的。
可以使用req.setAttribute(key,value)和getAttribute(key)实现请求转发内的Servlet的数据的流转。
注意:在学习的请求转发后,每个Servlet的访问方式就会有两种:
浏览器直接发起请求访问。其他Servlet通过请求转发访问。- 总结:请求转发可以实现在后端Servlet之间的相互调用,一个请求由一个Servlet处理,转变为了多个Servlet的协同处理。
2.请求重定向
学习了请求转发后,可以实现一次请求由多个Servlet协同处理,使得处理请求的Servlet的职责更加清晰。而在实际开发中,也可以使用其它的解决方案实现多个Servlet配合完成某一项功能。
示例:
resp.sendRedirect(req.getContextPath() + "/MainServlet");
请求重定向的特点
重定向是两次请求,地址栏信息改变,地址会变成第二次请求的地址。
重定向的地址是浏览器收到第一次请求响应回来的地址,自动跳转的,用户不参与。
重定向的两次请求,request对象是不同的。
3.请求转发与重定向的比较
请求转发:
请求转发是一次请求,是Tomcat服务器内部的行为,共享同一个request对象。浏览器只需要发一次请求即可将业务处理完毕。
一般浏览器发起的查询功能会使用请求转发来完成请求的处理及结果的响应。
浏览器发起的是增删改的请求,如果使用请求转发来处理的话,因为转发后的地址栏信息是不变的,容易造成用户刷新页面后表单重复提交。
重定向:
重定向是两次请求,地址栏信息会改变,不共享同一个请求和响应对象。
一般用户的增删改请求会使用重定向的方式来处理请求。目的是保护第一次请求,避免用户因刷新页面造成表单重复提交。
总结:
不论是请求转发还是请求重定向,都会涉及到多个Servlet。其实,什么时候该用请求转发什么时候该用请求重定向也很容易判断。
如果你需要将A Servlet的处理结果通过请求对象带到B Servlet中去使用,那就使用请求转发。
如果A Servlet的处理结果不需要带到B Servlet中去使用,那就使用重定向。
区别 | 转发 | 重定向 |
---|---|---|
浏览器地址栏发生是否改变 | 否 | 是 |
请求与响应的次数 | 1次请求,1次响应 | 2次请求,2次响应 |
是否共享Request和Response对象 | 是 | 否 |
是否可以通过Request对象传递数据 | 是 | 否 |
速度 | 相对较快 | 相对较慢 |
行为类型 | 服务器内部行为 | 非服务器内部行为 |
三、Cookie对象
1.特点:
Cookie是浏览器端的数据存储技术。
Cookie使用字符串存储数据。
Cookie使用Key与Value结构存储数据。
不安全,不适合存储重要的数据到浏览器端。
单个Cookie存储数据大小限制在4097个字节(4kb左右)。
Cookie存储的数据中不支持中文,Servlet4.0中支持。
Cookie分为持久化Cooke与状态Cookie。
Cookie对象保存在客户端浏览器内存或系统磁盘中。
浏览器在保存同一域名所返回Cookie的数量是有限的。不同浏览器支持的数量不同,Chrome浏览器为50个
浏览器每次请求时都会把与当前访问的域名相关的Cookie在请求中提交到服务端。
Cookie是与域名绑定所以不支持跨一级域名访问。
2.Cookie的使用
Cookie的创建及响应
//创建Cookie,Cookie中保存的数据是键值对的方式
Cookie cookie = new Cookie("username", "root");
//将创建好的Cookie添加到响应中,这样浏览器就会将Cookie中的信息保存起来了
resp.addCookie(cookie);
Cookie数据的获取
Cookie[] cookies = req.getCookies();
if(cookies != null){
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
System.out.println(name + ":" + value);
}
}
Cookie的存活设置
使用setMaxAge()方法可以设置存活时间:
-
正数:表示在指定的秒数后过期
-
负数:表示浏览器一关,Cookie就会被删除(默认是-1)
-
零:表示马上删除Cookie
Cookie cookie = new Cookie("life60", "life60");
cookie.setMaxAge(60);
resp.addCookie(cookie);
Cookie的path属性
Cookie的path属性可以有效的过滤哪些Cookie可以发送给服务器,哪些不发。
path属性是通过请求的地址来进行有效的过滤。
如果不设置path属性,那Cookie的有效路径是当前项目。
请求地址如下:
http://ip:port/工程路径/a.html 则CookieA发送,CookieB不发送
http://ip:port/工程路径/abc/a.html 则CookieA发送,CookieB发送
Cookie cookie = new Cookie("path1","path1");
cookie.setPath(req.getContextPath() + "/abc");// 路径是 /工程路径/abc
resp.addCookie(cookie);
四、HttpSession对象
1.概述
服务端存储数据的技术解决Http无状态。
2.特点
Session将数据保存在服务器端。
HttpSession使用Key与Value结构存储数据。
HttpSession的Key是字符串类型,Value则是Object类型。
HttpSession存储数据大小无限制。
HttpSession存储数据安全。
3.介绍
-
一个浏览器在服务器中只会创建一个Session对象。不同用户(浏览器)的Session对象之间是互相独立的。
-
服务器中创建Session对象,创建完成后会将Session对象的Id(JSESSIONID)以Cookie的形式保存在客户端(浏览器)。用户再次发请求时,会携带该Cookie,也就是JSESSIONID到服务器,服务器会根据该Id找到用户的Session对象。
-
用户JSESSIONID的Cookie丢失或者服务器中存储的Session对象被销毁,服务器接收到用户的请求后,如果找不到对应的Session对象,会重新创建,并将新的JSESSIONID以Cookie的形式保存到浏览器中。
-
存储JSESSIONID的Cookie不需要手动创建,Session对象创建完成,Tomcat服务器会自动创建Cookie, 将JESSIONID存储在Cookie中响应回浏览器。
-
Cookie默认的有效期为一次会话(浏览器不能关闭),浏览器关闭,Cookie即失效。
-
Session对象在Tomcat服务器的默认有效期为30分钟。
4.使用
HttpSession对象的创建是通过request.getSession()方法来创建的。客户端浏览器在请求服务端资源时,如果在请求中没有jsessionid,getSession()方法将会为这个客户端浏览器创建一个新的HttpSession对象,并为这个HttpSession对象生成一个jsessionid,在响应中通过状态Cookie写回给客户端浏览器、如果在请求中包含了jsessionid,getSession()方法则根据这个ID返回与这个客户端浏览器对应的HttpSession对象。
getSession()方法还有一个重载方法getSession(true|false)。
1.HttpSession的创建
HttpSession session = req.getSession();
注意:
如果请求的Cookie中携带了JSESSIONID,则根据JSESSIONID找对应的Session对象
找到, 返回该Session。
没有找到, 创建新的Session对象, 会将JSESSIONID存储在Cookie中响应回浏览器。
如果请求中没有携带JSESSIONID,则会创建一个Session对象, 会将JSESSIONID存储在Cookie中响应回浏览器
总结:服务器中能找到对应的Session对象,那就使用该Session对象,如果找不到,就会新创建。
2.HttpSession存储数据
session.setAttribute("user", user);
3.HttpSession获取数据
session.getAttribute("user");
4.HttpSession销毁方式
HttpSession的销毁方式有两种:
1.达到超时时间后会销毁,默认30分钟,时间的计算方式是根据最后一次请求时间作为起始时间开始计算。
-
Tomcat服务器的conf/web.xml文件中配置HttpSession的超时时间,这个文件是所有项目web.xml的父文件,不建议修改。
-
可以修改项目的web.xml中的HttpSession的超时时间。该时间对整个web项目中的所有HttpSession对象有效。
2.调用HttpSession对象中的invalidate()方法销毁。
5.总结
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
String id = session.getId();//获取JSESSIONID
System.out.println(id);
long creationTime = session.getCreationTime();//获取创建时间
Date date = new Date(creationTime);
System.out.println(date.toLocaleString());
long lastAccessedTime = session.getLastAccessedTime();//获取最后一次访问时间
System.out.println(new Date(lastAccessedTime).toLocaleString());
session.setMaxInactiveInterval(10);//设置最大非活动时间
int maxInactiveInterval = session.getMaxInactiveInterval();//获取最大非活动时间
System.out.println(maxInactiveInterval);
//session.invalidate();//销毁session对象
}
Session和Cookie的区别
Cookie数据存储在客户端,而HttpSession中的数据存储在服务器。
Cookie不安全,而HttpSession是安全的。
单个cookie保存的数据不能超过约4KB,很多浏览器都限制一个域名保存cookie的数量。
HttpSession没有容量以及数量的限制, 随着Session中存储的内容增多,会比较占用服务器内存,Session不存放业务数据。
Cookie的数据都以字符串的形式保存。Session中可以保存对象。
Cookie实现,如:记住我 最近浏览商品 网页皮肤 等。
Session实现,如:登录信息 错误信息 购物车 等。
五、基于注解式开发Servlet
在Servlet3.0以及之后的版本中支持注解式开发Servlet。对于Servlet的配置不在依赖于web.xml配置文件,而是使用@WebServlet注解完成Servlet的配置。
1.@WebServlet
属性名 | 类型 | 作用 |
---|---|---|
initParams | WebInitParam[] | Servlet的init参数 |
name | String | Servlet的名称 |
urlPatterns | String[] | Servlet的访问URL,支持多个 |
value | String[] | Servlet的访问URL,支持多个 |
loadOnStartup | int | 自启动Servlet |
description | String | Servlet的描述 |
@WebServlet(name = "first", value = "/first",
loadOnStartup = 1, initParams = {@WebInitParam(name = "test", value = "aaa")},
description = "测试servlet")