华清远见-重庆中心-java web知识点梳理

目录

前言

Tomcat 的运行机制

http协议

1.servlet介绍

2.Servlet的开发步骤

3.servlet的简单实例 

3.1导入jar包

3.2servlet的配置

3.3web.xml中对servlet配置

3.4运行tomcat容器

3.5访问方式

4.servlet的地址的设置

5.Servlet的生命周期

JSP        

1.关于jsp

2.jsp的生命周期

3. servlet处理数据, jsp展示数据

4.转发和重定向

1.状态管理

2.cookie

增加一个cookie

获取cookie,修改cookie

2.1cookie的使用过程

2.2cookie的有效期

2.3cookie的路径问题

2.4cookie的特点

3.服务器端的状态管理(session)

session的使用

1.Filter

 Filter的生命周期

2. ServletContext的使用

 3.JSP 内置对象(隐式对象)

4. EL表达式

 5. jstl: jsp的标签库

5.1导入jstl的jar包

5.2:指令的使用

6.jsp的include指令

​​​​​​


前言

Java Web,是用Java技术来解决相关web互联网领域的技术总和。web包括:web服务器和web客户端两部分。本章主要讲与servlet相关的内容。


Tomcat 的运行机制

一、Tomcat运行原理分析

1.Tomcat 是运行在 JVM 中的一个进程。它定义为【中间件】,顾名思义,是一个在Java项目与JVM之间的中间容器。

2.Web 项目的本质,是一大堆的资源文件和方法。Web 项目没有入口方法 ( main 方法),,意味着 Web 项目中的方法不会自动运行起来。

3.Web 项目部署进 Tomcat 的 webapp 中的目的是很明确的,那就是希望 Tomcat 去调用写好的方法去为客户端返回需要的资源和数据。

4. Tomcat 可以运行起来,并调用写好的方法。那么,Tomcat 一定有一个 main 方法。

5. 对于Tomcat 而言,它并不知道我们会有什么样的方法,这些都只是在项目被部署进 webapp下后才确定的,由此分析,必然用到了 Java 的反射来实现类的动态加载、实例化、获取方法、调用方法。但是我们部署到 Tomcat 的中的Web项目必须是按照规定好的接口来进行编写,以便进行调用

6.Tomcat 如何确定调用什么方法呢。这取决于客户端的请求,http://127.0.0.1:8080/JayKing.Tomcat.Study/index.java?show 这样的一个请求,通过 http 协议,在浏览器发往本机的 8080 端口,携带的参数 show 方法,包含此方法的路径为 JayKing.Tomcat.Study,文件名为:index.java。

Tomcat的运行机制_w3cschool


http协议

  • http协议
    1. 通信方式
      1. 建立连接
      2. 发送请求(请求数据包)
      3. 发送响应(响应数据包)
      4. 断开连接
    2. 数据包格式
      • 请求数据包
      • 响应数据包
    3. 请求方式
      1. get 请求参数在url地址后显示;数据量比较小;不安全;不支持文件上传
        • get请求:①浏览器地址直接访问。②form的method设置为get
          ③超链接 ④异步请求时设置为get
      2. post 数据存在消息体中;数据量大;相对安全;支持文件上传
        • post请求:①form的method设置为post ②异步请求时设置为post
      3. put

1.servlet介绍

servlet是sun公司指定的一种用于扩展web服务器的功能的组件规范

  • web服务器通常只能处理静态的资源(html,css,js…),为了解决动态的处理数据,就需要对web服务器的功能进行扩展,servlet就是用于处理动态数据的组件规范。
  • 组件:符合一定规范,完成部分功能的软件模块。例如java中的servlet,jsp都属于组件。这些软件模块需要放在容器中运行。比如Tomcat就属于容器。因此,servlet,jsp都需要放在Tomcat容器中去允许。
  • 容器:符合一定规范,能够运行组件的一种软件。比如:Tomcat,jetty,Jboss…
  • Servlet规范:使用servlet的时候,自定义类继承HttpServlet,重新service方法,那么久符合Servlet规范。

Servlet 常称为服务器端小程序,即运行在服务器端的程序,用于处理及响应客户的请求。

Servlet类 是个特殊的java类,继承于HttpServlet。

2.Servlet的开发步骤

  • 新建的工程是一个java web项目(maven中的web app)
  • Servlet类,基础HttpServlet
    • 重写service方法
    • service(HttpServletRequest request , HttpServletResponse response)
    • request 请求
    • response 响应
  • java web工程中的web.xml文件
    • web.xml文件名不能修改。(tomcat容器找web.xml文件)
    • 将java类和浏览器访问的地址做一个映射(mapping)
    • 浏览器没办法直接访问java类中的方法,所以需要对java类映射为一个浏览器能访问的url地址。
  • 打包(辅助完成)
    • 把web项目运行所需要的文件按指定的文件结构保存
  • 部署(在idea中可以完成)
    • 把打包好的web程序放到Tomcat的过程,就称为部署
  • 启动容器
    • 容器启动后,可通过浏览器,访问这个java web 项目了。

3.servlet的简单实例 

3.1导入jar包

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

3.2servlet的配置

package action;

import javax.servlet.ServletException;
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 HelloServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
        //1.设置编码方式
        response.setContentType("text/html;charset=utf-8");//相应格式为html,编码采用utf-8
        request.setCharacterEncoding("utf-8");
        //2.获取请求参数(http://localhost:8080/web01_war/hello?name=alice)
        //      url         ? 参数
        String user = request.getParameter("name");//根据参数的值key,获取参数value
        //3.处理数据
        String word = user + ",你好";
        //4.响应结果
        PrintWriter writer =response.getWriter();//获取输出流
        writer.println("***********");
        writer.println(word);
        writer.println("***********");
    }
}

3.3web.xml中对servlet配置

    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>action.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <!--         引用存在的servlet-name的名字 -->
        <servlet-name>hello</servlet-name>
        <!--         servlet映射了一个url地址。
                        ①浏览器地址栏输入地址
                        ②form表单的action属性中,可以使用url地址。
                        ③超链接a标签的href属性中,可以使用url地址。
                        ④ajax - 异步请求中使用 -->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

3.4运行tomcat容器

于浏览器的url即地址栏中输入localhost:8080/web01_war/hello?name=alice

3.5访问方式

//html页面让用户输入数据,表单提交的时候访问servlet
public class BMIServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //1.设置编码
        resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        //2.获取参数  -- url    http://localhost:8080/bmi?tz=60&sg=1.7
        //      ?   key=value & key1+value1 ,& 用于风隔参数
        String tz = req.getParameter("tz");
        String sg = req.getParameter("sg");
        //3.处理数据
        double tz1 = Double.valueOf(tz);
        double sg1 = Double.valueOf(sg);
        double bmi = tz1 / (sg1 * sg1);
        //4.相应结果
        PrintWriter writer = resp.getWriter();
        String str = "";
        if (bmi<18){
            str="太瘦了";
        }else if(bmi<24){
            str="标准身材";
        }else if (bmi<28){
            str="太胖了";
        }else {
            str="肥胖状态";
        }
        writer.println("你的bmi是:"+bmi+"\n");
        writer.println("<b style = 'color:red'>"+str+ "</b>");
    }
}
<!--
<servlet>
用来声明一个servlet的数据,主要有以下子元素:
<servlet-name> 指定servlet的名称
<servlet-class> 指定servlet的类名称
...

<servlet-mapping>
用来定义servlet所对应的URL,包含两个子元素:
<servlet-name>指定servlet的名称
<url-pattern> 指定servlet所对应的URL

-->    

    <servlet>
        <servlet-name>bmi</servlet-name>
        <servlet-class>action.BMIServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>bmi</servlet-name>
        <url-pattern>/bmi</url-pattern>
    </servlet-mapping>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 绝对路径 :/开始的路径就是绝对路径-->
<!-- 相对路径: 不是/开始的路径,就是相对路径,根据当前路径拼接相对路径-->
        <label>请输入体重:</label>
<!-- 这里form 的action="bmi" 就是对应之前web.xml中配置的<url-pattern>/bmi</url-pattern>-->
    <form action="bmi" method="get">
        <input type="text" name="tz">
        <br>
        <label>请输入身高:</label>
        <input type="text" name="sg">
        <br>
        <input type="submit" value="计算bmi">
    </form>
</body>
</html>
先访问html 页面: http://localhost:8080/web01/bmi.html
然后通过表单提交访问: http://localhost:8080/web01/bmi?tz=60&sg=1.7

接收前端提交的数据

request.getParameter(key) , 获取请求参数。
getParameter(key) 的返回值是 String (使用的时候,需要注意数据类型的转换问题。)
如果前端没有传入某个参数, 使用 getParameter(key) ,那么返回值是 null.

响应结果

通过 response 对象的 getWriter() 方法,得到输出流
通过输出流,输出字符串内容,作为响应结果
设置响应结果的类型和字符编码方式:
response.setContentType("text/html;charset=utf-8");
1. text/html , 这个是浏览器能解析的 html 格式
2. application/json, 这个是浏览器能解析的 json 格式 ( 后面会使用 )
3. 如果格式写错,浏览器不能解析,就会提示你下载。
比如 test/html , 就是浏览器不认识的格式,就会提示下载这个响应结果。

4.servlet的地址的设置

public class UrlPatternServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.设置编码
        resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        //2.获取请求参数
        //3.获取请求的url
        //--ContextPath :应用程序的访问路径(Application Context)
        String contextPath = req.getContextPath();
        //--ServletPath:访问servlet的路径(配置的servlet的url)
        String servletPath = req.getServletPath();
        System.out.println("contextPath:"+contextPath);
        System.out.println("servletPath:"+servletPath);
        if (servletPath.equals("/add.do")){
            System.out.println("add增加业务");
        }else if (servletPath.equals("/update.do")){
            System.out.println("update修改业务");
        }else if(servletPath.equals("/delete.do")){
            System.out.println("delete删除业务");
        }else if(servletPath.equals("/list.do")){
            System.out.println("list查询业务");
        }
        else {
            System.out.println("请求地址错误,不支持此操作");
        }
        //4.数据处理
        //5.响应结果
        PrintWriter writer = resp.getWriter();
        writer.println("访问路径:"+servletPath);
        writer.println("\n 当前被访问的类:UrlPatternServlet");
    }
}

    <servlet>
        <servlet-name>urlp</servlet-name>
        <servlet-class>action.UrlPatternServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>urlp</servlet-name>
<!--
    测试地址是否符合要求,静态资源是否被拦截。
    *** 浏览器发送请求时,Tomcat通过web.xml文件,优先 访问servlet文件,找到servlet类就访问其service方法
                      如果没有servlet,就找静态资源,如果找不到静态资源,响应404.
    *** Tomcat,优先精确匹配,如果没有精确的地址,就模糊匹配,没有模糊匹配,就找静态资源,都找不到返回404.
    *** web.xml中配置servlet的url地址的时候,尽量避免特殊后缀名,例如.jps , .html , .css
    ① /  :模糊匹配,除了jsp以外,其他都会被servlet匹配到。<url-pattern>/</url-pattern>
    ② /* :模糊匹配,所有地址都会被匹配到<url-pattern>/*</url-pattern>
    ③ *.xx :模糊匹配,以某个固定后缀名结尾的地址,按后缀名匹配。<url-pattern>*.do</url-pattern>
    ④ /xx :精确地址,<url-pattern>/mm</url-pattern>该访问地址固定为/mm
    ⑤ /xx.yy :精确地址, <url-pattern>/mm.do</url-pattern>访问地址固定为: /mm.do

    ⑥ xx :错误
    ⑦ /*.xx :错误
    ⑧ xx.yy :错误
-->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

<!--    全局参数(context) 当前项目中的servlet都可以调用-->
    <context-param>
        <param-name>count</param-name>
        <param-value>1000</param-value>
    </context-param>

5.Servlet的生命周期

(1). 创建Servlet实例。

(2). Web容器调用Servlet的init()方法,对Servlet进行初始化。

(3). Servlet初始化后,将一直存在于容器中,用于响应客户端请求,如果客户端发送GET请求,容器调用Servlet的doGet()方法处理并响应请求;如果客户端发送POST请求,容器调用Servlet的doPost()方法处理并响应请求。或者统一使用service()方法处理来响应用户请求。

(4). Web容器决定销毁Servlet时,先调用Servlet的destory()方法,通常在关闭Web应用时销毁Servlet实例。

1.实例化(使用构造方法创建对象)

2.初始化 执行init方法(只执行一次)

3.请求服务 执行service方法

4.销毁方法 执行destroy方法

特别注意:

一个Servlet同一时刻只有一个实例化对象(实例)。 
当多个请求发送到同一个Servlet,服务器会为每个请求创建一个新线程来处理。 


JSP        

1.关于jsp

jsp是sun公司制定的一种用于服务器端的动态页面的技术规范,也是一种组件依赖于容器(例如tomcat)进行运行。

jsp不需要再web.xml中进行配置,直接通过它的路径和文件名进行访问。

jsp是一种运行在服务器端的页面,它里面可以包含html , 嵌入一些java代码,通过在tomcat容器中经过解析,输出为html页面。

  • servlet : 数据的处理和数据的展示(拼html标签)
  • servlet + jsp : servlet做数据处理, jsp做数据的展示。
    • servlet做数据展示的时候,不方便(编写代码的时候, 维护代码的时候)
    • jsp : 让数据的处理和数据的展示进行分离(解耦)

JSP文件后缀名为  .jsp 。

page 指令: 指定页面的类型和页面的编码方式 ( 一般在第一行)

2.jsp的生命周期

jsp的本质就是servlet。

jsp的生命​周期​​​​​​从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。

  • 编译阶段:

    servlet容器编译servlet源文件,生成servlet类

  • 初始化阶段:

    加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法

  • 执行阶段:

    调用与JSP对应的servlet实例的服务方法

  • 销毁阶段:

    调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例

JSP生命周期代码实例如下所示:(来自:JSP 生命周期 | 菜鸟教程 (runoob.com))

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<title>life.jsp</title>
</head>
<body>

<%! 
  private int initVar=0;
  private int serviceVar=0;
  private int destroyVar=0;
%>
  
<%!
  public void jspInit(){
    initVar++;
    System.out.println("jspInit(): JSP被初始化了"+initVar+"次");
  }
  public void jspDestroy(){
    destroyVar++;
    System.out.println("jspDestroy(): JSP被销毁了"+destroyVar+"次");
  }
%>

<%
  serviceVar++;
  System.out.println("_jspService(): JSP共响应了"+serviceVar+"次请求");

  String content1="初始化次数 : "+initVar;
  String content2="响应客户请求次数 : "+serviceVar;
  String content3="销毁次数 : "+destroyVar;
%>
<h1>菜鸟教程 JSP 测试实例</h1>
<p><%=content1 %></p>
<p><%=content2 %></p>
<p><%=content3 %></p>

</body>
</html>
注意:jsp 页面导入 java ​​​​​​​
jsp 页面上,使用 java 类的时候,都需要先导入,然后再使用。
<%@ page import="java.util.Date" %>

3. servlet处理数据, jsp展示数据

// servlet中查询数据
List<BookInfo> bookInfos = service.queryAll();
// 把数据bookInfos ,转发到jsp页面,jsp页面显示数据。
// *** 把需要转发到jsp页面上的数据,保存再request对象中.
req.setAttribute("books" , bookInfos); //
setAttribute(String , Object)
// 当前这个请求对应的路径: http://localhost:8080/web04/list.do
RequestDispatcher dispatcher =
req.getRequestDispatcher("./book/show.jsp"); //参数是
转发的路径
dispatcher.forward(req,resp); // 转发- forward
<%@ page import="java.util.List" %>
<%@ page import="entity.BookInfo" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>显示书的信息</title>
<style>
td,th{border: 1px solid black ; padding: 5px;}
</style>
</head>
<body>
<table style="border: 1px solid black" cellspacing="0"
cellpadding="0">
<tr>
<th>书的id</th>
<th>书的名字</th>
<th>书的作者</th>
<th>书的价格</th>
<th>出版日期</th>
<th>书的数量</th>
<th>书的类型id</th>
<th>操作</th>
</tr>
<%
// 1. 从request对象中获取数据。
Object books = request.getAttribute("books");
// 2. 转换数据的类型
if(books!=null){
if(books instanceof List){
List<BookInfo> list = (ArrayList<BookInfo>)books;
// 3. 遍历数据
for(BookInfo bi:list){
// 4. 输出数据
%>
<tr>
<th><%=bi.getBookId()%></th>
<th><%=bi.getBookName()%></th>
<th><%=bi.getBookAuthor()%></th>
<th><%=bi.getBookPrice()%></th>
<th><%=bi.getBookDate()%></th>
<th><%=bi.getBookNum()%></th>
<th><%=bi.getTypeId()%></th>
<th>
<a href="toUpdate.do?bookId=
<%=bi.getBookId()%>">修改</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="delete.do?bookId=
<%=bi.getBookId()%>">删除</a>
</th>
</tr>
<%
}
}
}
%>
</table>
</body>
</html>

4.转发和重定向

转发和重定向的代码

else if(servletPath.equals("/delete.do")){
            String bookId = req.getParameter("bookId");
            if(bookId == null){
                req.setAttribute("msg" , "只能根据id删除数据。");
                RequestDispatcher rd = req.getRequestDispatcher("./book/info.jsp");
                rd.forward(req ,resp);
            }else{
                Boolean aBoolean = service.deleteOne(Integer.valueOf(bookId));
                if(aBoolean == false){
                    req.setAttribute("msg" , "删除失败");
                    RequestDispatcher rd = req.getRequestDispatcher("./book/info.jsp");
                    rd.forward(req ,resp);
                }else{ // 删除成功,重定向到list.do
//                    req.getRequestDispatcher("list.do").forward(req,resp);//转发
                    resp.sendRedirect(req.getContextPath() + "/list.do"); //sendRedirect--重定向
                }
            }
  • 转发:一个请求完成部分功能,希望剩下的功能由另一个请求完成,这种时候使用转发
    • ​​​​​​​一般使用servlet完成数据处理, 转发数据到jsp页面,实现数据的展示。
    • 转发可以通过request对象,把数据转发给另一个请求
    • 转发的本质是一个请求,因为request对象不变(可以共享request中的数据)。
    • 转发之后,浏览器地址栏显示的是第一个请求的地址。
  • 重定向 :某个请求完成之后,希望浏览器自动发起另一个请求,则使用重定向。​​​​​​​
    • 使用重定向的时候,浏览器消息头中收到一个 302 状态码和 url地址。浏览器根据这个状态码和 url 地址,自动发起请求。
    • ​​​​​​​重定向是完全不同的两个请求,是两个 request 对象,两个请求的数据无法共享。
    • ​​​​​​​浏览器地址栏显示的是第二个请求的地址。
  • 重定向:两次请求,是两个不同的request对象,不能数据共享

  • 转发:本质就是一次请求,是同一个request对象,能共享数据。

  • 路径的写法:
    • ​​​​​​​​​​​​​​ 绝对路径的代码:
      /路径, 表示绝对路径。
      /web04/add.do --- 绝对路径, 属于硬编码。不方便维护。
      String appContext = request.getContextPath();// 获取到application
      context 的路径。
      appContext + /add.do --- 绝对路径。 维护更方便。
    • 相对路径的代码:
      ../ 表示推出当前目录,到上层目录,然后拼接路径。
      ./ 表示当前目录,直接拼接路径。 可以省略./

1.状态管理

状态(数据)管理(数据存储):浏览器和服务器的多次交互作为一个整体,这个过程中有一些需要使用的数据,这些数据(状态)需要保存起来,用于表示某种状态。

  • 客户端状态管理:cookie技术,数据保存在浏览器中。
  • 服务器端状态管理:session技术,数据保存在服务器的session对象中。

2.cookie

增加一个cookie

//cookie :服务器中可以设置cookie数据,保存在浏览器中。
public class AddCookieServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        //保存一个count=100 在cookie中
        Cookie cookie = new Cookie("count",100+"");//创建一个cookie对象
        cookie.setMaxAge(180);//设置cookie的最大有效期。
        resp.addCookie(cookie);//把cookie添加到浏览器中

        Cookie cookie1 = new Cookie("ip","localhost");//有一个默认的有效期。
        resp.addCookie(cookie1);

        resp.getWriter().println(""+cookie.getValue()+",ip:"+cookie1.getName());

    }
}

获取cookie,修改cookie

//cookie :每次访问服务器的时候,请求中会把这个服务器域名相关的cookie数据发送到服务器端,
//         服务器端就可以获取到这些cookie数据。
public class GetCookieServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        Cookie[] cookies = req.getCookies();
        if (cookies != null){
            for(Cookie c : cookies){
                //键值对 c.getName():cookie 的key   c.getValue():cookie的value
                System.out.println(c.getName()+":"+c.getValue());
                //修改cookie的数据,重新保存在浏览器中
                if (c.getName().equals("count")){
                    c.setValue(Integer.valueOf(c.getValue())+1+"");
                    resp.addCookie(c);//修改了浏览器中的cookie
                }
            }
            resp.getWriter().println("cookie的数量:"+cookies.length);
        }else{
            resp.getWriter().println("没有cookie。");
        }
    }
}

2.1cookie的使用过程

  • 服务器端创建cookie对象,再添加到浏览器中。

    Cookie c = new Cookie(key ,value);
    response.addCookie(c)
    
  • 浏览器保存响应结果中要求你需要add的cookie对象,每个cookie和自己的请求的域名一致。

  • 浏览器每次给服务器发送请求的时候,会将对应的域名中保存的cookie数据一起发送到服务器。

  • 服务器通过request获取cookie对象的数据,根据cookie 的name ,找到value值,进而使用value。

2.2cookie的有效期

cookie.setMaxAge(秒) --设置cookie的有效期
  • 没有调用setMaxAge():表示会话期间有效,浏览器关闭,cookie失效。(默认设置)
  • setMaxAge(正数) : 有效期就是当前时间 + 正数的秒数。
  • 会话期间: 浏览器第一次访问某个服务器,到浏览器关闭的期间,称为一个会话。

2.3cookie的路径问题

  • 子路径下可以找到父路径下的cookie

    cookie.setPath(url) -- 创建cookie对象之后,可以修改cookie的路径,然后再添加到浏览器中。
    比如: http://localhost:8080/web04/xx/yy/aa.do - 这个路径中添加了一个cookie(count
    ,"100")
    http://localhost:8080/web04/xx/bb.do - 这个访问不了count.
    

2.4cookie的特点

  • 用户可以删除cookie
  • 用户可以禁止cookie
  • 存储小于4k的内容
  • cookie的个数不宜超过300个,有上限
  • 只能存储字符串
  • cookie不安全

3.服务器端的状态管理(session)

​ 把整个对话期间所有请求,看做一个整体,这个过程中如果有数据共享,把数据保存到session对象中。

  • request对象:连接断开就无效了。

  • session对象:会话期间都有效。

  • java

    //登录成功,把用户信息,保存在session对象中
    HttpSession session = req.getSession();//获取session对象
    session.setAttribute("myuser",us);//吧数据设置到session对象中。
    
  • jsp

    <%
        //session是jsp页面的内置对象,可以直接使用。
        Object myuser = session.getAttribute("myuser");
        User us = new User();//new 一个User 避免空指针
        if (myuser != null && myuser.getClass() == User.class){
            us = (User) myuser;
        }
    %>
    
    <h3><%=us.getUname()%>,欢迎使用图书管理系统。</h3>
    <hr>

session的使用

  • 状态管理

    • cookie:客户端状态管理
    • session:服务器端状态管理
  • session对象的获取

    • session对象的获取,和请求中从浏览器中传输到服务器中的cookie(JSESSIONID)有关系
    • 根据JSESSIONID 这个cookie,去查找当前请求对应的session对象。
    //根据sessionId获取session对象,如果没有获取到,就创建一个session。
    HttpSession session = request.getSession();
    
    HttpSession session = request.getSession(boolean);
    
  • session中保存数据

    session.setAttribute(String, Object);
    
  • session中获取数据

    Object obj = session.getAttribute(String);
    
  • session中删除数据

        session.removeAttribute(String); //根据key,删除数据
    
  • session默认在会话期间有效

  • session会话超时

    • 设置session的有效期

      session.setMaxInactiveInterval(秒);
      
    • 没有设置有效期,默认为会话有效期。

  • 设置session无效

    • 一般系统有一个退出功能,可以清空session中保存的数据,使用session的invalidate方法,设置session无效。

          session.invalidate();
      

1.Filter

Filter、FilterChain、FilterConfig 介绍 | 菜鸟教程 (runoob.com)

sun公司提供的一种特殊的组件规范,主要用于拦截容器的调用过程。​​​​​​​

  • 规范: 实现Filter接口(实现doFilter方法)
  • 特殊:过滤器不能单独使用,需要和servlet进行配合使用
  • 组件:实现软件的某个模块功能,需要在容器中运行
  • 容器: 一个特殊的软件,可以运行组件 支持多个Filter ,以在web.xml中的配置的顺序进行过滤。

Filter对Servlet 程序进行拦截处理时,它可以决定是否将请求继续传递给 Servlet 程序,以及对请求和响应消息是否进行修改,容器不再直接调用 Servlet 的 service 方法,而是调用 Filter 的 doFilter 方法,再由 doFilter 方法决定是否去激活 service 方法。

 Filter的生命周期

  • 实例化 (调用构造函数) – 1次
  • 初始化(调用init函数) – 1次
  • 就绪(调用doFilter函数) – 任意次
  • 销毁(调用destroy函数)-- 1次

2. ServletContext的使用

应用程序执行期间都是同一个ServletContext对象,可以在所有请求中,获取到该对象,操作该对象中的数据。

// servletContext: 容器运行程序期间都有效,可以共享数据。
// 容器停止运行,servletContext就无效了。
ServletContext servletContext = request.getServletContext();
// 获取数据
Object total = servletContext.getAttribute("total");
// 设置数据
servletContext.setAttribute("total" , 1);

servlet中数据可以存储的区域:

  • servlet的service方法中的变量
  • request对象:可以通过转发的方式,把数据转发到其他的请求中
  • session对象:可以让一个用户在会话期间,直接使用session中的数据。
  • servletContext对象:可以让所有请求在容器运行期间,直接使用servletContext中的数据。

 3.JSP 内置对象(隐式对象)

JSP 隐式对象 | 菜鸟教程 (runoob.com)

对象描述
requestHttpServletRequest 接口的实例
responseHttpServletResponse 接口的实例
outJspWriter类的实例,用于把结果输出至网页上
sessionHttpSession类的实例
applicationServletContext类的实例,与应用上下文有关
configServletConfig类的实例
pageContextPageContext类的实例,提供对JSP页面所有对象以及命名空间的访问
page类似于Java类中的this关键字
ExceptionException类的对象,代表发生错误的JSP页面中对应的异常对象

4. EL表达式

expression language: el表达式

el表达式, 主要用于替换掉 <%=xx %>输出语句 。

jsp 页面中, 可以直接通过 el 表达式,获取到存储在 pageContext, request, session ,
application 中的数据。

语法规则

  • ${对象} [<%=xx %>]
  • ${对象.属性名} [<%=xx.getXXX() %>]
    • 对象符合java bean的规范(描述类的属性私有化,提供公开的get/set方法。
      • 比如 属性名叫abc , 对应的方法叫getAbc / setAbc)
      • ${对象.属性名} ,这里的本质是调用属性名对应的get方法。

el表达式的查找数据方式

  • 从pageContext, request, session , application等对象中,查找需要输出的对象
  • pageContext, request, session , application如果出现了同名的key , 那么查找按小范围优选的原则查找
  • 可以通过pageScope, requestScope , sessionScope, applicationScope 指定查找范围。
jsp和el的有关介绍实例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isErrorPage="true" %>
<html>
<head>
    <title>jsp的内置对象介绍</title>
    <style>
        table{border: 1px solid brown}
        th,td{border: 1px solid black;padding: 3px}
    </style>
</head>
<body>
    <table>
        <tr><th>内置对象的名字</th><th>作用</th></tr>
        <tr><td>out</td><td>在jsp页面上输出内容</td></tr>
        <tr><td>pageContext</td><td>存储数据,这个数据只在当前页面使用</td></tr>
        <tr><td>request</td><td>请求对应的request对象,获取request中的数据,在jsp页面使用</td></tr>
        <tr><td>session</td><td>session对象,服务器端状态管理</td></tr>
        <tr><td>application</td><td>存储数据,可以在整个应用程序运行期间使用</td></tr>
        <tr><td>response</td><td>响应结果的对象</td></tr>
        <tr><td>page</td><td>类似于this</td></tr>
        <tr><td>config</td><td>初始化参数,存在config中</td></tr>
        <tr><td>exception</td><td>异常对象,需要使用page指令</td></tr>
    </table>

<%
    //在四个对象中(作用域不同),存储相同的key
    //** 可用范围: application > session > request > pageContext
    pageContext.setAttribute("computer","pc computer|");
    request.setAttribute("computer","request computer|");
    session.setAttribute("computer","session computer|");
    application.setAttribute("computer","app computer|");
    ServletContext servletContext = config.getServletContext();
    String key = servletContext.getInitParameter("key");
    try{
        int i = 0;
        int k = 10/i;
    }catch (Exception e){
        exception = e;
    }

%>
    <h3><%= exception.getMessage()%></h3>
    <h3><%=key%></h3>
    <%=pageContext.getAttribute("computer")%>
    <%=request.getAttribute("computer")%>
    <%=session.getAttribute("computer")%>
    <%=application.getAttribute("computer")%>
    <hr>
    <h4>使用el表达式获取变量值</h4>
    <%--    根据key找value,范围从小开始扩大直到找到为止--%>
    ${computer} :从最小域开始查找。
    <h4>el表达式,指定查找范围</h4>
    request : ${requestScope.computer}
    session : ${sessionScope.computer}
    application : ${applicationScope.computer}
</body>
</html>

 el表达式的使用:

<%@ page import="entity.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el表达式的使用</title>
</head>
<body>
<%
    User user = new User();
    user.setUid(1005);
    user.setUname("小红");
    user.setUpwd(null);
    request.setAttribute("user",user);
%>
<h3>el表达式输出对象的值</h3>
    <%--    el表达式本质是去找对应的get方法。
            user.getUid() 方法--%>
    uId: ${user.uid}
    uName: ${user.uname}
    uPwd: ${user.upwd}
<hr>
    uPwd: <%=user.getUpwd()%>
<h3>条件运算</h3>
    ${user.uid > 1000}
<h3>数学运算</h3>
    ${user.uid + 1000}
<h3>逻辑运算</h3>
    ${user.uid > 1000 || 3>2 }
<h3>empty运算</h3>
    ${empty user}
</body>
</html>

el表达式的输出结果

  • 如果没有这个key , 输出是空字符串
  • 如果有这个key,但是key对应的value值是null , 输出的是空字符串
  • 其他情况,输出的是key对应的value值。​​​​​​​​​​​​​​

el表达式使用cookie

${cookie.cookieName.value}
<h3>
根据 cookie 的名字找 value
</h3>
<h3> jsessionid: ${cookie.JSESSIONID.value} </h3>

 el表达式绝对路径的写法​​​​​​​

${pageContext.request.contextPath}
替换掉: <% = request . getContextPath ()%>

 5. jstl: jsp的标签库

jstl标签,用于替换掉jsp页面上的<% java代码%>

jsp页面上,如果有太多的java代码,对于jsp页面的修改维护,不友好。

5.1导入jstl的jar包

<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>

5.2:指令的使用

jsp页面上,使用taglib指令 ,把想用的标签,导入到jsp页面上,让jsp支持标签的使用

  • taglib jsp的导入标签库的指令​​​​​​​
  • prefix : 前缀, 给标签添加上前缀之后,可以和其他的重名标签进行区分。
  • uri: 标签的访问地址​​​​​​​

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ page import="java.util.List" %>
<%@ page import="entity.BookInfo" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>jsp的标签库</title>
</head>
<body>
<%
    int age = 19 ;//判断是否是成年人
    int sex = 0 ;//0为女生,1为男生,其他提示性别错误
    List<BookInfo> bs = new ArrayList<>();
    BookInfo b1 = new BookInfo();
    b1.setBookName("book1");
    b1.setBookNum(20);
    bs.add(b1);
    BookInfo b2 = new BookInfo();
    b2.setBookName("book2");
    b2.setBookNum(30);
    bs.add(b2);
    bs.add(new BookInfo());
    bs.add(null);
    request.setAttribute("age",age);
    request.setAttribute("sex",sex);
    request.setAttribute("bs",bs);
%>
<h1>c:if</h1>
<c:if test="${age > 18}">
    成年人
</c:if>
<h1>c:choose</h1>
<c:choose>
  <c:when test="${sex == 0 }">女生</c:when>
  <c:when test="${sex == 1 }">男生</c:when>
    <c:otherwise>性别错误</c:otherwise>
</c:choose>
<h3>c:forEach</h3>
<c:forEach items="${bs}" var="book" varStatus="status">
    <p>
            ${status.index + 1},
        <c:if test="${!empty book}">
            书名:${book.bookName},
            数量:${book.bookNum}
        </c:if>
    </p>
</c:forEach>
</body>
</html>

 更多详细内容请参考:JSP 标准标签库(JSTL) | 菜鸟教程 (runoob.com)

6.jspinclude指令​​​​​​​

 head.jsp

<% @ page contentType = "text/html;charset=UTF-8" language = "java" %>
<h3 style = "color: green" > xx , 下午好, 欢迎使用本系统! </h3>

 其他.jsp文件调用head.jsp

 <%@ include file="head.jsp"%>


 

1.阐述JSP的作用域

  • page:代表与一个页面相关的对象和属性。
  • request:代表与客户端发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个 Web 组件;需要在页面显示的临时数据可以置于此作用域。
  • session:代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的 session 中。
  • application:代表与整个 Web 应用程序相关的对象和属性,它实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域。

2.session 和 cookie 有什么区别?

区别:
(1)存储位置不同:session 存储在服务器端;cookie 存储在浏览器端。
(2)安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改。
(3)容量和个数限制:cookie 有容量限制,每个站点下的 cookie 也有个数限制。
(4)存储的多样性:session 可以存储在 Redis 中、数据库中、应用程序中;而 cookie 只能存储在浏览器中

3.创建线程有哪几种方式?区别是什么?

创建线程有3种方式
(1)继承 Thread 重写 run 方法;
(2)实现 Runnable 接口;
(3)实现 Callable 接口。
区别:
Thread 实现Runnable 接口无返回值, Callable 接口有返回值。
Callable 、Runnable 是接口,Thread 是实现类。

4.线程有哪些状态?

线程的状态:
(1)NEW 尚未启动
(2)RUNNABLE 正在执行中
(3)BLOCKED 阻塞的(被同步锁或者IO锁阻塞)
(4)WAITING 永久等待状态
(5)TIMED_WAITING 等待指定的时间重新被唤醒的状态
(6)TERMINATED 执行完成

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值