目录
表白墙引入数据库
再谈Cookie和session
得到Cookie
编辑
设置Cooie
使用Cookie编写一个登入的小界面
1.先引入数据库的依赖(驱动包),5.1.49
pom.xml中,在之前的两个之前,再去添加一个
mysql mysql-connector-java5.1.49 2.创建本地的数据库
create table messageWall(`from` varchar(20),`to` varchar(20),message varchar(1024));3.之前的代码中有一段可以删掉了
//此处把消息保存到内存中(一旦重启服务器,内存数据就会消失了。更科学的做法,应该是保存到数据库里面) private ListmessageList=new ArrayList<>(); 这个代码需要删除,因为我们已经决定使用数据库去存储了,就不需要本地去存了。
完整代码
import com.fasterxml.jackson.databind.ObjectMapper; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; class Message{ public String from; public String to; public String message; @Override public String toString() { return "Message{" + "from='" + from + '\'' + ", to='" + to + '\'' + ", message='" + message + '\'' + '}'; } } @WebServlet("/message") public class MessageServlet extends HttpServlet { //首先要把一个json转化为java对象 private ObjectMapper objectMapper=new ObjectMapper(); //此处把消息保存到内存中(一旦重启服务器,内存数据就会消失了。更科学的做法,应该是保存到数据库里面) private ListmessageList=new ArrayList<>(); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.需要能够读取请求body,转换成java对象 Message message=objectMapper.readValue(req.getInputStream(),Message.class); //2.得到message之后,需要把message保存到服务器中 try { save(message); } catch (SQLException e) { e.printStackTrace(); } System.out.println("服务器收到message:"+message.toString()); //3.返回响应,(其实没啥大必要,主要是返回一个200ok就行,body可以没有) resp.setStatus(200); //设置成功状态码,会更加清晰 resp.getWriter().write("ok"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { List messageList= null; try { messageList = load(); } catch (SQLException e) { e.printStackTrace(); } //1.把内存中的这些Message,组织成json格式,返回到响应中 String respJson=objectMapper.writeValueAsString(messageList); //这个代码十分关键,告诉浏览器,返回的响应的body是json格式(utf8编码) resp.setContentType("application/json; charset=utf8"); resp.getWriter().write(respJson); // 2.针对List/数组这种,jackon会自动把数据整理成json数组,里面每个对象,又会被jsckon转换成{}json对象(json对象属性名字,也是和Message类的成员名字对应的) } private void save(Message message) throws SQLException { //通过jdbc从数据库中存储数据。 DataSource dataSource=new MysqlDataSource(); //useSSL=false 此处的SSL就是HTTPS中的加密方案 ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/message?characterEncoding=utf8&&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("lcl15604007179"); //2.建立链接 Connection connection=dataSource.getConnection(); //3.构造SQL String sql="insert into messageWall values(?,?,?)"; PreparedStatement statement=connection.prepareStatement(sql); statement.setString(1, message.from); statement.setString(2, message.from); statement.setString(3, message.from); //4.执行SQL statement.executeUpdate(); //5.释放资源,关闭连接 statement.close(); connection.close(); } private List load() throws SQLException { //通过jdbc,从数据库读取数据 //1。创建数据源 DataSource dataSource=new MysqlDataSource(); ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/message?characterEncoding=utf8&&useSSL=false"); ((MysqlDataSource) dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("lcl15604007179"); //2.建立连接 Connection connection= dataSource.getConnection(); //3.构造SQL String sql="select *from messageWall"; PreparedStatement statement=connection.prepareStatement(sql); //4.执行SQL ResultSet resultSet= statement.executeQuery(); //5.遍历结果集合 List messageList=new ArrayList<>(); while (resultSet.next()){ Message message=new Message(); message.from=resultSet.getString("from"); message.to=resultSet.getString("to"); message.message=resultSet.getString("message"); messageList.add(message); } //关闭连接,释放资源 resultSet.close(); statement.close(); connection.close(); return messageList; } }
我们可以知道,表白墙上的东西,即使你关闭服务器,我们的数据也是保存的,这也是游戏停服了但是你的数据不丢失的原因。
Cookie是浏览器在本地持久化存储数据的一种机制
1.Cookie的数据从哪里来?
服务器返回给浏览器的
2.Cookie的数据长什么样子?
Cookie中是键值对结构的数据,并且这里的键值对都是程序员自定义的。
3.Cookie有什么用
Cookie可以在浏览器这边存储一些临时性数据
其中最典型的一种使用方式,就是用来存储“身份标识”
sessionId->Cookie和Session之间的联动了
4.Cookie到哪里去
Cookie的内容会在下次访问该网站的时候,自动被带到HTTP请求中
5.Cookie怎么存储的
浏览器按照不同的域名分别存储Cookie域名和域名之间不能打扰。
Cookie存储在硬盘上的
Cookie存储往往会有一个超时时间(看浏览器不同而定,支付宝很短,安全)
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/getcookie") public class GetCookieServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie[] cookies = req.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { System.out.println(cookie.getName() + ":" + cookie.getValue()); } } else { resp.getWriter().write("当前请求中没有cookie"); } resp.getWriter().write("ok"); } }
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/setcookie") public class SetCookieServlet extends HttpServlet { //期望通过doGet方法,把一个自定义的cookie数据返回到浏览器这边。 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie=new Cookie("date","2023-09-23"); resp.addCookie(cookie); Cookie cookie1=new Cookie("time","19:55"); resp.addCookie(cookie1); resp.getWriter().write("setCookie ok"); } }
我们需要是先设置Cookie之后,就可以此时拿到Cookie的内容,当然Cookie里面的数据,只是在浏览器休息休息,真正发挥作用,还是得在服务器这边的逻辑生效的。
Cookie结合Session实现登入效果,此时就能更清楚的看出来
sessionId是一个广义的概念,不同的库中具体实现过程会有一些细节的差异,在Servlet里,把这个属性具体叫做JSESSIONID
getSession背后做的事情(会话,就相当于账户,用户和服务器的交流,之前有没有这个账户)
1.读取请求中的Cookie,看Cookie里面是否有JESSIONID属性,以及值是什么,如果没有,就认为需要创建新的会话,如果有,就拿着这个ID去查询当前的session是否存在
要是session存在,就直接返回该session
要是session不存在,就准备创建新的会话。
2.如果当前确实需要创建会话,就会创建一个Session对象,同时生成唯一的一个JESSIONID,以JSESSIONID为key,SESSION对象为value,把这个键值对插入到服务器上述的哈希表中
3.刚才生成的JESSIONID又会通过addCookie方法,加入到响应中,此时响应里就会带有Set-Cookie字段,这里的值就是JSEEION=xxxxxxx通过响应,就把JSESSIOID返回到浏览器这边了。
这一行小小的,能量大大的🙉🙉🙉
HttpSession session=req.getSession(true);问题1:什么情况会有sessionId但是没有session呢
服务器这边存的session对象也是在内存中进行的
比如把sessionId返回给浏览器了,sessionId和session对象是保存在服务器内存的,此时如果服务器重启了,内存中这些会话数据就没了,但是浏览器中的Cookie还是存在的
session存在内存中不太合理,实践中往往会把这种会话保存到其他介质上,来达到持久化存储目的(mysql,redis)
简单的一个小的前端代码
Document