笔记代码

分割线

Servlet

HttpServletRequest

  • 例子: 在 index.jsp 提交表单信息给 /login,此 Servlet 后端读取发送来的表单信息并在页面输出显示.

    • 删掉并用 idea 重建 index.jsp,会补齐一些编码信息.

      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
      <%@ page
      contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
      <title>登录页面</title>
      </head>
      <body>
      <h1>登录</h1>

      <div style="text-align: center">
      <form action="/login" method="post">
      <label>
      用户名:
      <input type="text" name="username" placeholder="无"/><br>
      </label>
      <label>
      密码:
      <input type="password" name="password" placeholder=""/><br>
      </label>

      爱好:
      <label><input type="checkbox" name="hobbys" value="女孩"/>女孩</label>
      <label><input type="checkbox" name="hobbys" value="代码"/>代码</label>
      <label><input type="checkbox" name="hobbys" value="动漫"/>动漫</label>
      <label><input type="checkbox" name="hobbys" value="美食"/>美食</label><br>
      <input type="submit">
      </form>
      </div>
      </body>
      </html>

    • src/main/java/servlet/Login.java

      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
      import java.io.IOException;
      import java.io.PrintWriter;
      import java.util.Arrays;

      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;

      public class Login extends HttpServlet {
      /**
      *
      */
      private static final long serialVersionUID = -7958099474557186407L;

      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      req.setCharacterEncoding("utf8");
      resp.setContentType("text/html");
      resp.setCharacterEncoding("utf8");
      PrintWriter writer = resp.getWriter();

      String username = req.getParameter("username");
      String password = req.getParameter("password");
      String[] hobbys = req.getParameterValues("hobbys");

      writer.println("username: " + username);
      writer.println("password: " + password);
      writer.println("爱好: " + Arrays.toString(hobbys));
      }

      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      doGet(req, resp);
      }
      }

    • web.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      <!DOCTYPE web-app PUBLIC
      "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/dtd/web-app_2_3.dtd" >

      <web-app>
      <display-name>Archetype Created Web Application</display-name>
      <servlet>
      <servlet-name>login</servlet-name>
      <servlet-class>servlet.Login</servlet-class>
      </servlet>

      <servlet-mapping>
      <servlet-name>login</servlet-name>
      <url-pattern>/login</url-pattern>
      </servlet-mapping>
      </web-app>

分割线

Cookie、Session

  • Cookie 是服务端在客户端上做的标记,用请求和响应进行传递,用来记录用户的访问信息 (客户端技术)

  • session 是在服务端上保存用户的访问信息 (服务端技术)

  • 例子: 访问 /cookie 时,会显示上一次访问此 URL 的时间 (这个时间通过服务端传给客户端 Cookie 来记录)

    • src/main/java/servlet/HelloCookie.java

      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
      import javax.servlet.ServletException;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.PrintWriter;

      public class HelloCookie extends HttpServlet {
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      req.setCharacterEncoding("utf-8");
      resp.setCharacterEncoding("utf-8");
      resp.setContentType("text/html");
      PrintWriter writer = resp.getWriter();

      // 获取客户端请求中携带的cookie
      Cookie[] cookies = req.getCookies();
      boolean isFirst = true; // 标志是否是第一次访问

      writer.println("你上一次访问时间是: ");
      for (Cookie cookie : cookies) {
      if (cookie.getName().equals("LastLoginTime")) {
      isFirst = false;
      writer.println(cookie.getValue());
      }
      }
      if (isFirst) {
      writer.println("这次是第一次访问.");
      }

      // 响应携带cookie返回给客户端
      Cookie lastLoginTime = new Cookie("LastLoginTime", System.currentTimeMillis() + "");// 非字符串+"" = 字符串
      resp.addCookie(lastLoginTime);
      }

      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      doGet(req, resp);
      }
      }

    • web.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      <!DOCTYPE web-app PUBLIC
      "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/dtd/web-app_2_3.dtd" >

      <web-app>
      <display-name>Archetype Created Web Application</display-name>
      <servlet>
      <servlet-name>cookie</servlet-name>
      <servlet-class>servlet.HelloCookie</servlet-class>
      </servlet>

      <servlet-mapping>
      <servlet-name>cookie</servlet-name>
      <url-pattern>/cookie</url-pattern>
      </servlet-mapping>
      </web-app>

  • 常用方法

    1
    2
    3
    4
    5
    6
    Cookie[] cookies = req.getCookies(); //获得Cookie
    cookie.getName(); //获得cookie中的key
    cookie.getValue(); //获得cookie中的vlaue
    new Cookie("lastLoginTime", System.currentTimeMillis()+""); //新建一个cookie
    cookie.setMaxAge(24*60*60); //设置cookie的有效期
    resp.addCookie(cookie); //响应给客户端一个cookie
  • 一些细节

    • cookie 大小和数量

      • 不同浏览器支持的大小和数量不一样,大小都是 4K 左右,数量为每域名几十到无数个不等.

      cookie 大小限制

    • 设置存活期:

      • 不设置: 关闭浏览器自动失效

      • 设置为 0,立即失效.

    • 遇到传输的中文乱码问题,可以用 URLEncoder 编码

      1
      2
      URLEncoder.encode("齐下无贰","utf-8")
      URLDecoder.decode(cookie.getValue(),"UTF-8")

Session

20210330120835
  • cookie 用来传输一些字符串验证信息,并存放在客户端中.

  • 而 session 可以存放更宽泛的数据(对象,文件等等),其数据存放在服务端.

    • 服务端传给客户端一个名为 JSESSIONID 的 cookie 用来验证 session

    • 一个 Seesion 对象独占一个浏览器,不同浏览器有不同的 session


  • 例子: 开启服务器并访问第一个页面 localhost:8080 时,session 就被创建了,然后访问 /setSession设置 person 信息,再访问 /getSession会显示 person 信息.

    • src/main/java/servlet/SetSession.java

      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
      import javax.servlet.ServletException;
      import javax.servlet.http.*;
      import java.io.IOException;
      import java.io.PrintWriter;

      public class SetSession extends HttpServlet {
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

      //解决乱码问题
      req.setCharacterEncoding("UTF-8");
      resp.setCharacterEncoding("UTF-8");
      resp.setContentType("text/html");

      //得到Session和writer
      HttpSession session = req.getSession();
      PrintWriter writer = resp.getWriter();

      //给Session中存东西
      session.setAttribute("person", new Person("齐下无贰", 100));

      //获取Session的ID
      String sessionId = session.getId();

      //判断Session是不是新创建
      if (session.isNew()) {
      writer.println("session创建成功,ID: " + sessionId);
      } else {
      writer.println("session已经在服务器中存在了,ID: " + sessionId);
      }
      }

      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      doGet(req, resp);
      }
      }

      class Person {
      private String name;
      private int age;

      public Person(String name, int age) {
      this.name = name;
      this.age = age;
      }

      public void setName(String name) {
      this.name = name;
      }

      public void setAge(int age) {
      this.age = age;
      }

      @Override
      public String toString() {
      return "Person{" +
      "name='" + name + '\'' +
      ", age=" + age +
      '}';
      }
      }

    • src/main/java/servlet/GetSession.java

      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
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import javax.servlet.http.HttpSession;
      import java.io.IOException;
      import java.io.PrintWriter;

      public class GetSession extends HttpServlet {
      /**
      *
      */
      private static final long serialVersionUID = -4606977948300644893L;

      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //解决乱码问题
      req.setCharacterEncoding("UTF-8");
      resp.setCharacterEncoding("UTF-8");
      resp.setContentType("text/html");

      //得到Session和writer
      HttpSession session = req.getSession();
      PrintWriter writer = resp.getWriter();

      // 获取属性并输出
      Person person = (Person) session.getAttribute("person");
      writer.println(person);

      // 移除属性
      session.removeAttribute("name");

      //手动注销Session
      session.invalidate();
      }

      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      doGet(req, resp);
      }
      }

    • web.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      <!DOCTYPE web-app PUBLIC
      "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/dtd/web-app_2_3.dtd" >

      <web-app>
      <display-name>Archetype Created Web Application</display-name>
      <servlet>
      <servlet-name>setSession</servlet-name>
      <servlet-class>servlet.SetSession</servlet-class>
      </servlet>
      <servlet>
      <servlet-name>getSession</servlet-name>
      <servlet-class>servlet.GetSession</servlet-class>
      </servlet>

      <servlet-mapping>
      <servlet-name>setSession</servlet-name>
      <url-pattern>/setSession</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
      <servlet-name>getSession</servlet-name>
      <url-pattern>/getSession</url-pattern>
      </servlet-mapping>
      </web-app>

  • session 有效期问题

    • 默认失效时间是 30 分钟

    • 是从 session 断开连接(浏览器关闭开始计算的),而不是从 session 连接开始计算

    • 可以在 web.xml 中设置

      1
      2
      3
      <session-config>
      <session-timeout>1</session-timeout>
      </session-config>

    关于 session 的失效时间和过期

分割线

JSP

介绍

  • JSP (Java Server Pages),写法类似 HTML 的动态 Java 页面

  • 最终 JSP 会被转换为一个 Java 类,实际上本质就是 Servlet 的简化实现.

    • *.jsp -> *.java -> *.class

      20210403111103

  • jsp 转换为的 java 文件核心部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //初始化
    public void _jspInit() {
    }

    //销毁
    public void _jspDestroy() {
    }

    //JSPService
    public void _jspService(HttpServletRequest request,HttpServletResponse response)

  • JSPService 内初始化的对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    final javax.servlet.jsp.PageContext pageContext;  //页面上下文
    javax.servlet.http.HttpSession session = null; //session
    final javax.servlet.ServletContext application; //Context->application
    final javax.servlet.ServletConfig config; //config
    javax.servlet.jsp.JspWriter out = null; //writer->out
    final java.lang.Object page = this; //当前页面->page
    HttpServletRequest request //请求
    HttpServletResponse response //响应

    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;

  • JSP 中可以写 Java 代码,Java 代码会原封不动的正常执行

    • HTML 代码在 JSP->Java 时会被转换成 out.write("<html>\r\n"); 这种形式.

依赖导入

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
<!-- servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSP依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<!-- JSTL表达式依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Standard标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>

基本语法

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
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试</title>
</head>
<body>
<!-- 这是HTML的注释,会在客户端显示 -->
<%-- 这是JSP注释,不会在客户端显示 --%>

<!--
JSP表达式: 用来将程序输出到客户端
<%= "变量或者表达式"%>
-->
<%= new Date()%>

<!--
JSP脚本片段
<% jsp脚本片段 %>
-->
<%
int sum = 0;
for (int i = 1; i <=100 ; i++) { sum+=i; }
out.println("<h1>Sum="+sum+"</h1>");
%>

<!--
JSP声明
会被编译到JSP生成Java的类中!其他的,就会被生成到_jspService方法中!
-->
<%!
static {
System.out.println("Loading Servlet!");
}

private int globalVar = 0;

public void kuang(){
System.out.println("进入了方法Kuang!");
}
%>
</body>
</html>