Session - JSP - MVC

5/12/2021 WebJava

Session

和ServletContext类似,可以存各类信息(键为String,值为Object)

注意我们尽量不要用context存东西,服务器很容器炸掉,session同理,但储存用户信息足以

每次打开浏览器,会自动创建一个session(由服务器端创建),sessionID储存在cookie中(JSESSIONID)

HttpSession s = req.getSession();
//session的id用服务器自动生成,保存在客户端cookie中
s.getId();
s.setAttribute("key", new Object);
s.getAttribute("key");
1
2
3
4
5

一个浏览器(用户)独占一个session

使用场景:

  • 保存用户信息
  • 购物车信息
  • 整个网站会用到的信息

手动销毁session

req.getSession().invalidate();
1

自动销毁session,在web.xml中添加session配置

<!--配置session自动销毁时间,单位:分钟-->
<session-config>
    <session-timeout>1440</session-timeout>
</session-config>
1
2
3
4

JSP

什么是JSP

Java Server Pages:java服务器端页面,和servlet一样,是用于开发动态web的技术

  • 写JSP就像在写HTML
  • 区别:HTML只给用户提供静态数据,而JSP可以嵌入java代码,为用户提供动态数据

JSP原理

JSP到底怎么执行的

  • 代码层面全然是HTML的模样
  • 服务器内部工作:在tomcat中有个work目录,idea缓存中有个tomcat的work目录
C:\Users\NorthBoat\.IntelliJIdea2019.3\system\tomcat\Unnamed_NEUQHelper\work\Catalina\localhost\NEUQHelper\org\apache\jsp
1

发现,JSP最终转换成了一个java类

JSP本质上就是一个Servlet !

public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
    private static final long serialVersionUID = 1L;

    protected HttpJspBase() {
    }
    //中间省略无数内容
}
1
2
3
4
5
6
7

在JSP类中,通过 resp.getWriter.write() 一行行手写HTML页面

index_jsp.java部分源码:初始化、销毁、服务

public void _jspInit() {
}

public void _jspDestroy() {
}

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
    throws java.io.IOException, javax.servlet.ServletException {

    //判断请求类型
    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
        return;
      }
    }

    //内置的一些对象
    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
        //输出之前的配置,设置页面格式、文本格式等
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("<html>\n");
      out.write("<body>\n");
      out.write("<h2>Hello World!</h2>\n");
      out.write("</body>\n");
      out.write("</html>\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }throws java.io.IOException, javax.servlet.ServletException {

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
    final java.lang.String _jspx_method = request.getMethod();
    if ("OPTIONS".equals(_jspx_method)) {
      response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
      return;
    }
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
      response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
      return;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

做了什么事情:

1、判断请求

2、内置的一些对象

//这些对象可以直接在jsp中使用
final javax.servlet.jsp.PageContext pageContext;//页面上下文
javax.servlet.http.HttpSession session = null;//session
final javax.servlet.ServletContext application;//applicationContext
final javax.servlet.ServletConfig config;//config
javax.servlet.jsp.JspWriter out = null;//out
final java.lang.Object page = this;//page:当前
javax.servlet.jsp.JspWriter _jspx_out = null;//请求
javax.servlet.jsp.PageContext _jspx_page_context = null;//响应
1
2
3
4
5
6
7
8
9

3、输出之前的一些初始化

response.setContentType("text/html");//页面格式
pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
1
2
3
4
5
6
7
8

4、打印HTML页面

//out为jsp的内置对象:javax.servlet.jsp.JspWriter out = pageContext.getOut()
out.write("<html>\n");
out.write("<body>\n");
out.write("<h2>Hello World!</h2>\n");
out.write("</body>\n");
out.write("</html>\n");
1
2
3
4
5
6

总结:JSP页面 ——> jsp.java ——> jsp.class ——> 作为一个Servlet返回到客户端

大佬的封装类

简单操作

<div style="text-align: center">
    <h2>
        <%
            List<String> keys = (List<String>) session.getAttribute("keys");
            for(int i = 0; i < keys.size(); i++){
                String key = keys.get(i);
                List<String> ans = (List<String>) session.getAttribute(key);
                out.write(key + "<br>");
                for(int j = 0; j < ans.size(); j++){
                    out.write(ans.get(j) + "\n");
                }
            }
        %>
    </h2>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

MVC三层架构

什么是MVC: Model、View、Controller(模型、视图、控制器)

早些年的架构:

  • 用户 ——> Servlet/JSP ——> pojo(实体类) — jdbc —> DB

用户直接访问控制层,控制层就可以直接操作数据库

servlet--CRUD--数据库
弊端:程序十分臃肿,不利于维护
servlet代码:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

架构:没有什么是加一层解决不了的

程序员
|
JDBC
|
Mysql Oracle SqlServer
1
2
3
4
5
6
7
8
9
10
11

servlet和jsp都可以写java代码,但为了易于维护和使用:

  • servlet专注于处理请求以及控制视图跳转
  • jsp专注于显示数据
控制层(controller):Servlet:接受用户请求,交给业务层去做(返回数据),视图跳转——>业务层(service)——>pojo——>DB
		   |
用户————>视图层(view):JSP:展示数据模型,提供用户操作
1
2
3

我们将service和pojo统称为Model,并且通常在其中加一层Dao

service — Dao ——> DB
        |
       pojo
1
2
3

Moder

  • 业务处理:业务逻辑(Service)
  • 数据持久层:CRUD(Dao)

View

  • 展示数据
  • 提供连接发起Servlet请求(a、form、img...)

Controller(Servlet)

  • 接受用户请求:req请求参数、Session信息
  • 交给业务层处理对应的代码
  • 控制视图跳转
Last Updated: 7/16/2024, 4:06:40 AM
妖风过海
刘森