知了堂学习笔记-MVC设计模式(Java实现)

 一.MVC软件设计模式

1:MVC简介

MVC即model(模型)-view(视图)-controller(控制器)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。 

2.图解

 

 

3.优点

耦合性低

视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。

模型是自包含的,并且与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。如果把数据库从MySQL移植到Oracle,或者改变基于RDBMS数据源到LDAP,只需改变模型即可。一旦正确的实现了模型,不管数据来自数据库或是LDAP服务器,视图将会正确的显示它们。由于运用MVC的应用程序的三个部件是相互独立,改变其中一个不会影响其它两个,所以依据这种设计思想能构造良好的松耦合的构件

重用性高

随着技术的不断进步,需要用越来越多的方式来访问应用程序。MVC模式允许使用各种不同样式的视图来访问同一个服务器端的代码,因为多个视图能共享一个模型,它包括任何WEB(HTTP)浏览器或者无线浏览器(wap),比如,用户可以通过电脑也可通过手机来订购某样产品,虽然订购的方式不一样,但处理订购产品的方式是一样的。由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面使用。例如,很多数据可能用HTML来表示,但是也有可能用WAP来表示,而这些表示所需要的命令是改变视图层的实现方式,而控制层和模型层无需做任何改变。由于已经将数据和业务规则从表示层分开,所以可以最大化的重用代码了。模型也有状态管理和数据持久性处理的功能,例如,基于会话的购物车和电子商务过程也能被Flash网站或者无线联网的应用程序所重用。

生命周期成本低

MVC使开发和维护用户接口的技术含量降低。

部署快

使用MVC模式使开发时间得到相当大的缩减,它使程序员(Java开发人员)集中精力于业务逻辑,界面程序员(HTML和JSP开发人员)集中精力于表现形式上。

可维护性高

分离视图层和业务逻辑层也使得WEB应用更易于维护和修改。

有利软件工程化管理

由于不同的层各司其职,每一层不同的应用具有某些相同的特征,有利于通过工程化、工具化管理程序代码。控制器也提供了一个好处,就是可以使用控制器来联接不同的模型和视图去完成用户的需求,这样控制器可以为构造应用程序提供强有力的手段。给定一些可重用的模型和视图,控制器可以根据用户的需求选择模型进行处理,然后选择视图将处理结果显示给用户。

4.缺点

没有明确的定义

完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考。同时由于模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难。每个构件在使用之前都需要经过彻底的测试。

不适合小型,中等规模的应用程序

花费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失。

增加系统结构和实现的复杂性

对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

视图与控制器间的过于紧密的连接

视图与控制器是相互分离,但却是联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。

视图对模型数据的低效率访问

依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。

一般高级的界面工具或构造器不支持模式

改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,会造成MVC使用的困难。

https://baike.baidu.com/item/MVC%E6%A1%86%E6%9E%B6/9241230?fr=aladdin&fromid=85990&fromtitle=MVC

 

二.html向Java发送数据

1.GET、POST方式

GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII.

POST请求一般是表单提交的请求,他具有一定的数据安全性,不会再地址栏中显示提交数据,并且对编码没有要求.

注意:GET请求不得对数据进行增删改查,敏感数据要用POST方式提交

 2.获得数据

1 @Override
2     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
3         System.out.println("进入GET请求");
4         String strG = req.getQueryString();
5         System.out.println(strG);
6 }
获得GET请求数据

如果URL传递中文后台得到的是类似%E4%BD%A0%E5的数据

1 @Override
2     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
3         System.out.println("进入POST请求");
4         req.setCharacterEncoding("utf-8");  // 设置中文编码
5         String strP = req.getParameter("strP");
6         System.out.println("strP = " + strP);
7 }
获得POST请求数据

req.getParameter("str")方法中name要和需要提取数据的<input>标签中name="str"属性一样,并且返回String类型

如果参数值是文中就要使用req.setCharaEncoding("UTF-8")方法设置中文编码来防止乱码.

 

三.后台目录搭建

1.系统文件放置

WEB-INF目录只有服务器可以访问到,未必避免用户通过URL直接访问系统页面,将后台页面放置在WEB-INF目录下.

2.通过转发访问WEB-INF后台页面

 1     @Override
 2     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 3         System.out.println("进入POST请求");
 4         req.setCharacterEncoding("utf-8");  // 设置中文编码
 5         String strP = req.getParameter("strP");
 6         System.out.println("strP = " + strP);
 7         
 8         //  通过转发的方式跳转页面,如果刷新会重复之前的操作
 9         req.getRequestDispatcher("/WEB-INF/jsp/Jsp.jsp").forward(req, resp);
10 }
转发

通过req.getRequsetDispatcher("路径").forward(req.resp).

刷新转发后的页面,会重复之前的操作.转发后的URL地址是隐藏的所以它的安全性很好,且速度较快

3.通过重定向访问其他服务器上的文件

1 @Override
2     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
3         System.out.println("进入GET请求");
4         String strG = req.getQueryString();
5         System.out.println(strG);
6         resp.sendRedirect("http://www.runoob.com/python/python-for-loop.html");
7     }
重定向

重定向由于是通过servlet1重定向到servlet2,servlet2对服务器的请求响应做出响应.所以速度较慢,且URL地址会显示在地址栏.

重定向无法直接访问WEB-INF目录下的文件,但可以由Servlet2转发访问WEB-INF目录下的文件

1 @Override
2     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
3         System.out.println("进入GET请求");
4         String strG = req.getQueryString();
5         System.out.println(strG);
6         resp.sendRedirect("Servlet2");
7     }
重定向到Servlet2
1     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException ,IOException {
2         System.out.println("进入Servler2程序的GET请求");
3         // 网页转发到WEB-INF后台页面
4         req.getRequestDispatcher("/WEB-INF/jsp/Jsp.jsp").forward(req,resp);
5     }
6     
Servlet2转发

 四.数据持久化

1.JDBC简介

JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。

https://baike.baidu.com/item/jdbc/485214

2.JDBC配置

下载相应数据库的链接文件,把jar文件放置在WEB-INF/lib目录下

3.查看数据库名称和版本号

 1 import java.sql.Connection;
 2 import java.sql.DatabaseMetaData;
 3 import java.sql.DriverManager;
 4 import java.sql.SQLException;
 5 
 6 import org.junit.Test;
 7 
 8 public class UserDao {
 9     
10     // 驱动信息
11     String username = "root";
12     String password = "123456";
13     String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false";
14     String driver = "com.mysql.cj.jdbc.Driver";
15     
16     
17     // 加载驱动
18     {
19         try {
20             Class.forName(driver);
21         } catch (ClassNotFoundException e) {
22             // TODO Auto-generated catch block
23             e.printStackTrace();
24         }
25     }
26     
27     // 查看连接数据库名称和版本号
28     @Test
29     public void m01() throws SQLException {
30         Connection conn = DriverManager.getConnection(url,username,password);
31         DatabaseMetaData dmd = conn.getMetaData();
32         String name = dmd.getDatabaseProductName();
33         String version = dmd.getDatabaseProductVersion();
34         System.out.println(name + "  " + version);
35     }
36     
37 }
查看MySQL

-MySQL 警告WARN: Establishing SSL connection without server's identity verification is not recommended.

首先恭喜,出现这个的时候MySQL说明已经安装成功了,这是警告不是错误,以后使用是不影响的。大概的意思就是说建立ssl连接,但是服务器没有身份认证,这种方式不推荐使用。

解决办法:

  原来的连接url:Connection connect = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "letmein");

  现在的连接url:Connection connect = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false","root", "letmein");

 

-java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized...

这是在使用MySQL 8.0以上版本(MySQL连接驱动和版本都是8.0以上)的时候出现的问题错误,我们需要在访问数据库的Url后面加上以下的语句即可:

?serverTimezone=GMT%2B8

比如,我原来的url是:

"jdbc:mysql://localhost:3306/shiro_test"

应该修改为:

"jdbc:mysql://localhost:3306/shiro_test?serverTimezone=GMT%2B8"

从错误上看应该是时区的错误,所以我们只需要设置完毕系统的时区即可。这里的GMT%2B8代表东八区。

还有一种解决办法就是设置整个数据库的时区,可以执行下面的语句来完成:

show variables like '%time_zone%'
set global time_zone='+8:00';

参考:

https://blog.csdn.net/qq_15581405/article/details/52403576?locationNum=13
https://blog.csdn.net/github_35186068/article/details/80919528

4.简单的增删改查

 1 // 添加
 2     @Test
 3     public void m02() throws SQLException{
 4         Connection conn = DriverManager.getConnection(url,username,password);
 5         String sql = "insert into user1 values(?,?)";
 6         PreparedStatement ps = conn.prepareStatement(sql); // 对即将执行的SQL语句进行预编译,安全快速
 7         ps.setInt(1,1); // 替换sql中第一个?为1
 8         ps.setString(2,"小明"); // 替换sql中第二个?为"小明"
 9         int i = ps.executeUpdate();
10         conn.close(); // 关闭连接,连接占用很大资源
11         System.out.println( "i == " + i);
12     }
增加
 1     // 删除
 2     @Test
 3     public void m03() throws SQLException{
 4         Connection conn = DriverManager.getConnection(url,username,password);
 5         String sql = "delete from user1 where user_id = ?";
 6         PreparedStatement ps = conn.prepareStatement(sql);
 7         ps.setInt(1, 1);
 8         int i = ps.executeUpdate();
 9         conn.close();
10         System.out.println("i == " + i);
11     }
删除
 1 // 更改
 2     @Test
 3     public void m05() throws SQLException{
 4         Connection conn = DriverManager.getConnection(url,username,password);
 5         String sql = "update user1 set user_name = '鑫鑫'  where user_id = 3";
 6         PreparedStatement ps = conn.prepareStatement(sql);
 7         int i = ps.executeUpdate();
 8         conn.close();
 9         System.out.println(i);
10     }
更改
 1 /**
 2      * 查询
 3      * Java数据类型   VS  数据库数据类型
 4      * int VS int
 5      * int VS  decimal
 6      * String VS varchar
 7      * Date VS timestamp
 8      * Date VS datetime 
 9      * @throws SQLException
10      */
11     @Test
12     public void m04() throws SQLException{
13         Connection conn = DriverManager.getConnection(url,username,password);
14         String sql = "select * from user1 ";
15         PreparedStatement ps = conn.prepareStatement(sql);
16         ResultSet rs = ps.executeQuery();
17         while(rs.next()) { // 循环往下移动,同时rs.next()返回布尔类型,只有布尔类型才能用到循环条件里面
18             int user_id = rs.getInt(1);
19             String user_name = rs.getString("user_name");
20             System.out.println(user_id + "  " + user_name);
21         }
22         conn.close();
23     }
查询

sql语句最好使用preparedStatement(sql)方法预编译,这样做可以提高速度,防止sql注入提高安全性.

数据库连接占用很大资源,使用完就要关闭连接.

五.Java建立model

1.model简介

Model是计算机程序设计中有两个概念:一个是三层架构中的实体类,另一个是MVC架构中的模型。
1、在“三层架构”中,为了面向对象编程,将各层传递的数据封装成实体类,便于数据传递和提高可读性。
2、在MVC(模型Model-视图View-控制器Controller)模式中,Model代表模型,是业务流程/状态的处理以及业务规则的制定,接受视图请求的数据,并返回最终的处理结果。业务模型的设计可以说是MVC最主要的核心。

一般一个Java类对应model中的一个实体,model只关心数据模型,不关心数据获取。

2.建立一个user模型

 1 public class UserModel {
 2     
 3     protected int user_id = -1;
 4     protected String user_name = null;
 5     protected String user_password = null;
 6     
 7     protected int getUser_id() {
 8         return user_id;
 9     }
10     protected void setUser_id(int user_id) {
11         this.user_id = user_id;
12     }
13     protected String getUser_name() {
14         return user_name;
15     }
16     protected void setUser_name(String user_name) {
17         this.user_name = user_name;
18     }
19     protected String getUser_password() {
20         return user_password;
21     }
22     protected void setUser_password(String user_password) {
23         this.user_password = user_password;
24     }
25 
26     
27     public void prin(){
28         System.out.println(user_id + "  " + user_name + "  " + user_password);
29     }
30     
31     
32 }
UserModel

Model中一个成员代表表中的一个字段。

Model要有Get和Set接口。

六.从数据库提取数据存放到model中

1.DAO简介

AO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。
 
在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象封装在一个公共API中。用程序设计的语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法。在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口在逻辑上对应这个特定的数据存储。
J2EE开发人员使用数据访问对象(DAO)设计模式把底层的数据访问逻辑和高层的业务逻辑分开.实现DAO模式能够更加专注于编写数据访问代码.

2.编写一个UserDAO

 1 import java.sql.Connection;
 2 import java.sql.DriverManager;
 3 import java.sql.PreparedStatement;
 4 import java.sql.ResultSet;
 5 import java.sql.SQLException;
 6 
 7 import org.junit.Test;
 8 
 9 public class UserDao2 {
10     // 驱动信息
11     String username = "root";
12     String password = "123456";
13     String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false";
14     String driver = "com.mysql.cj.jdbc.Driver";
15     
16     //加载驱动
17     {
18         try {
19             Class.forName(driver);
20         } catch (ClassNotFoundException e) {
21             // TODO Auto-generated catch block
22             e.printStackTrace();
23         }
24     }
25     
26     
27     // 获得数据并将数据存储到UserModel中
28     @Test
29     public void m01() throws SQLException{
30         UserModel user = new UserModel(); // 实例化一个UserModel类
31         Connection conn = DriverManager.getConnection(url,username,password);
32         String sql = "select * from user1 where user_id = 3";
33         PreparedStatement ps = conn.prepareStatement(sql);
34         ResultSet rs = ps.executeQuery();
35         while(rs.next()){
36             user.setUser_id(rs.getInt(1));
37             user.setUser_name(rs.getString(2));
38             user.setUser_password(rs.getString(3));
39         }
40         conn.close();
41         user.prin();
42     }
43 }
UserDao

因为DAO层只关注数据访问,所以需要Model来提供数据存储。

如果需要多个相同的Model,请使用集合框架。

七.返回数据到html

1.Ajax简介

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术
Ajax = 异步 JavaScript 和 XML(标准通用标记语言的子集)。
Ajax 是一种用于创建快速动态网页的技术。
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

 

2.编写一个Service来实现业务逻辑

 1 import java.io.IOException;
 2 import java.io.PrintWriter;
 3 import java.sql.SQLException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 import com.google.gson.Gson;
12 
13 
14 
15 @WebServlet("/UserService")
16 public class UserService extends HttpServlet{
17     
18     UserDao2 ud = new UserDao2();
19 
20     @Override
21     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
22         System.out.println("进入GET方法");
23         // 创建用户表模型
24         UserModel user = new UserModel();
25         user.setUser_id(4);
26         user.setUser_name("小徐");
27         user.setUser_password("123456");
28         
29         // 将user对象转换成JSON文本(数据)
30         Gson gson = new Gson();
31         String json = gson.toJson(user); // 转换数据格式
32         
33         // 使用HttpServletResponse接口完成数据的响应处理
34         // 关键点:中文编码处理,数据响应格式的处理,输出数据到前端界面
35         resp.setCharacterEncoding("utf-8");
36         resp.setContentType("test/plain");
37         PrintWriter out = resp.getWriter();
38         out.println(json);
39         out.flush();
40         out.close();
41     }
42     
43     @Override
44     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
45         // TODO Auto-generated method stub
46         super.doPost(req, resp);
47     }
48     
49     
50 }
Service

Gson.toJson(Model)可以将Model转化成Json对象

resp.setCharacterEncoding("UTF-8")方法设置中文编码

3.编写一段AJAX来响应数据

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <title>MyHtml.html</title>
 5 <meta charset="UTF-8">
 6 <script src="../jquery-1.11.0.min.js"></script>
 7 <script>
 8 $(function(){
 9   $("#btn").click(function(){
10     $.ajax({
11       url: "../UserService",
12       type: "GET",
13       success: function(data){
14         console.log("发送成功");
15         var div = document.getElementById("div");
16         div.innerHTML += data.user_id + "  " + data.user_name + "  " + data.user_password;
17       },
18       dataType: "json"
19     });
20   });
21 });
22 </script>
23 </head>
24 <body>
25     This is my HTML page.
26     <br>
27     <a href="../servlet?strp=中文">连接</a>
28     <br>
29     <form action="../servlet" method="POST">
30         <input type="text" name="strP"> <input  type="submit">
31     </form>
32     <button id="btn">点击</button>
33     <div id="div"></div>
34 </body>
35 </html>
利用Jquery编写Ajax
 1 import java.io.IOException;
 2 import java.io.PrintWriter;
 3 import java.sql.SQLException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 import com.google.gson.Gson;
12 
13 
14 
15 @WebServlet("/UserService")
16 public class UserService extends HttpServlet{
17     
18     UserDao2 ud = new UserDao2();
19 
20     @Override
21     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
22         System.out.println("进入GET方法");
23         // 创建用户表模型
24         UserModel user = new UserModel();
25         user.setUser_id(4);
26         user.setUser_name("小徐");
27         user.setUser_password("123456");
28         
29         // 将user对象转换成JSON文本(数据)
30         Gson gson = new Gson();
31         String json = gson.toJson(user); // 转换数据格式
32         
33         // 使用HttpServletResponse接口完成数据的响应处理
34         // 关键点:中文编码处理,数据响应格式的处理,输出数据到前端界面
35         resp.setCharacterEncoding("utf-8");
36         resp.setContentType("test/plain");
37         PrintWriter out = resp.getWriter();
38         out.println(json);
39         out.flush();
40         out.close();
41     }
42     
43     
44 }
Service

url: Java服务程序地址

type: 请求方式

success: function(data){ }  回调函数

dataType: 返回的数据格式

4.编写一段Ajax来发送数据

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <title>MyHtml.html</title>
 5 <meta charset="UTF-8">
 6 <script src="../jquery-1.11.0.min.js"></script>
 7 <script>
 8 $(function(){
 9   $("#btn").click(function(){
10     user_id = document.getElementById("a1").innerHTML;
11     user_name = document.getElementById("a2").innerHTML;
12     $.ajax({
13       url: "../UserService",
14       type: "post",
15       dataType: "json",
16       data: {"user_id":user_id , "user_name":user_name }
17     });
18   });
19 });
20 </script>
21 </head>
22 <body>
23     This is my HTML page.
24     <br>
25     <a href="../servlet?strp=中文">连接</a>
26     <br>
27     <form action="../servlet" method="POST">
28         <input type="text" name="strP"> <input  type="submit">
29     </form>
30     <button id="btn">点击</button>
31     <div id="div"></div>
32     <div id="a1">5</div>
33     <div id="a2">小红</div>
34 </body>
35 </html>
Ajax
 1 import java.io.IOException;
 2 import java.io.PrintWriter;
 3 import java.sql.SQLException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 import com.google.gson.Gson;
12 
13 
14 
15 @WebServlet("/UserService")
16 public class UserService extends HttpServlet{
17 
18     
19     @Override
20     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
21         // 设置中文编码
22         req.setCharacterEncoding("UTF-8");
23         String user_id = req.getParameter("user_id");
24         String user_name = req.getParameter("user_name");
25         System.out.println(user_id + "  " + user_name);
26     }
27     
28     
29 }
Service

如果data:中传入dom对象会报 Maximum call stack size exceeded  

8.会话

1.什么是会话

Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份Session通过在服务器端记录信息确定用户身份

    一次会话指的是:就好比打电话,A给B打电话,接通之后,会话开始,直到挂断电话,该次会话就结束了,而浏览器访问服务器,就跟打电话一样,浏览器A给服务器发送请求,访问web程序,该次会话就已经接通,其中不管浏览器发送多少请求(就相当于接通电话后说话一样),都视为一次会话,直到浏览器关闭,本次会话结束。其中注意,一个浏览器就相当于一部电话,如果使用火狐浏览器,访问服务器,就是一次会话了,然后打开google浏览器,访问服务器,这是另一个会话,虽然是在同一台电脑,同一个用户在访问,但是,这是两次不同的会话。

2.会话解决了什么问题

    知道了什么是会话后,思考一个问题,一个浏览器访问一个服务器就能建立一个会话,如果别的电脑,都同时访问该服务器,就会创建很多会话,就拿一些购物网站来说,我们访问一个购物网站的服务器,会话就被创建了,然后就点击浏览商品,对感兴趣的商品就先加入购物车,等待一起付账,这看起来是很普通的操作,但是想一下,如果有很多别的电脑上的浏览器同时也在访问该购物网站的服务器,跟我们做类似的操作呢?服务器又是怎么记住用户,怎么知道用户A购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,不能放入用户B或用户C的购物车内的呢?所以就有了cookie和session这两个技术,就像第一行说的那样,cookie和session用来跟踪用户的整个会话,

3.Cookie和Session之间的区别和联系

      假如一个咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:

      1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。但是http协议本身是无状态的

      2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。也就是cookie。 顾客就相当于浏览器,cookie如何工作,下面会详细讲解

      3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。

      由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择

原文:https://blog.csdn.net/android_bar/article/details/70570216

 

 

2018-9-4

posted @ 2018-08-31 22:38  lemon-Xu  阅读(2179)  评论(0编辑  收藏  举报