JavaServer

1 Tomcat

1.1 目录结构和配置

1.下载:http://tomcat.apache.org/

2.安装:解压压缩包即可。

	* 注意:安装目录建议不要有中文和空格

3.卸载:删除目录就行了

4.启动

  • bin/startup.bat ,双击运行该文件即可
  • 访问:浏览器输入:http://localhost:8080 回车访问自己
    http://别人的ip:8080 访问别人

5.启动过程中可能碰到的问题

1. 黑窗口一闪而过:
    * 原因: 没有正确配置JAVA_HOME环境变量
    * 解决方案:正确配置JAVA_HOME环境变量

2. 启动报错:
    1. 暴力:找到占用的端口号,并且找到对应的进程,杀死该进程
    	* netstat -ano
    2. 温柔:修改自身的端口号
    	* conf/server.xml
    	* <Connector port="8888" protocol="HTTP/1.1"
    		connectionTimeout="20000"
    		redirectPort="8445" />
    	* 一般会将tomcat的默认端口号修改为80。80端口号是http协议的默认端口号。
    	* 好处:在访问时,就不用输入端口号

6.关闭

  • 正常关闭

    • bin/shutdown.bat

    • CTRL+C

  • 强制关闭

    • 点击窗口上的X

7.配置

* 部署项目的方式:
    1. 直接将项目放到webapps目录下即可。
        * /hello:项目的访问路径-->虚拟目录
        * 简化部署:将项目打成一个war包,再将war包放置到webapps目录下。
        * war包会自动解压缩

    2. 配置conf/server.xml文件
    	在<Host>标签体中配置
        <Context docBase="D:\project" path="/iyhome" />
        * docBase:项目存放的路径
        * path:虚拟目录

    3. 在conf\Catalina\localhost创建任意名称的xml文件。在文件中编写
        <Context docBase="D:\project" />
        * 虚拟目录:xml文件的名称

8.Tomcat的目录结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lK0ZC98h-1623947454308)(F:\Note\1562554784809.png)]

9.动态web资源目录结构

* 静态项目和动态项目:
	* 目录结构
	* java动态项目的目录结构:
	-- 项目的根目录
		-- 静态页面(html\css\js\img)
		-- JSP页面
		-- WEB-INF目录:
            -- web.xml:web项目的核心配置文件(必须有)
            -- classes目录:放置字节码文件的目录
            -- lib目录:放置依赖的jar包

1.2 Tomcat配置虚拟主机

1.2.1 什么是虚拟主机

虚拟主机:在电脑上设置一个目录,使用一个名称(类似域名)与该目录进行绑定。这个路径称为是虚拟主机。主机是可以发布web项目的.虚拟主机是一个路径.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7VZLTMfS-1623947454316)(F:\Note\1562572301843.png)]

1.2.2 虚拟主机的配置

假定设置一个虚拟钓鱼网站,百度

1.抓取百度页面

2.创建一个路径(虚拟主机)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v8Nev6dY-1623947454322)(F:\Note\1562572455917.png)]

3.修改本地的host文件

192.168.16.45 www.baidu.com

当浏览器地址中输入 www.baidu.com:8080 时,访问的就是192.168.16.45:8080,在这台机器上的8080就是Tomcat

4.配置tomcat的虚拟主机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ysq0Dzqp-1623947454326)(F:\Note\1562573131302.png)]

在conf文件中配置好name=”www.baidu.com”,指向主机地址appBase=“C:\baidu”

5.启动服务器访问项目

http://www.baidu.com:8080/website/baidu.htm

其实就是访问:C:\baiud\website\baidu.htm

6.设置默认端口号

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nwwsEKxq-1623947454330)(F:\Note\1562574117066.png)]

7.配置虚拟路径,去掉website

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AkfCvNLu-1623947454331)(F:\Note\1562574043556.png)]

8.配置默认的首页

conf/web.xml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S4ONka88-1623947454334)(F:\Note\1562574163781.png)]

2. HTTP

2.1 概念

	Hyper Text Transfer Protocol 超文本传输协议
	* 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
	* 特点:
		1. 基于TCP/IP的高级协议
		2. 默认端口号:80
		3. 基于请求/响应模型的:一次请求对应一次响应
		4. 无状态的:每次请求之间相互独立,不能交互数据

	* 历史版本:
		* 1.0:每一次请求响应都会建立新的连接
		* 1.1:复用连接

2.2 HTTP协议之请求部分

请求消息数据格式

  1. 请求行
  2. 请求头
  3. 请求空行
  4. 请求体

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zBfxbnxo-1623947454335)(F:\Note\1562595315790.png)]

1.请求行
请求方式/请求url 		请求协议/版本
GET    /login.html	HTTP   /1.1
    
 * 请求方式:
	* HTTP协议有7中请求方式,常用的有2* GET:
			1. 请求参数在请求行中,在url后。GET /web_test/demo2.html?name=aaa HTTP/1.1
			2. 请求的url长度有限制的
			3. 不太安全
		* POST:
			1. 请求参数在请求体中
			2. 请求的url长度没有限制的
			3. 相对安全
2.请求头:客户端浏览器告诉服务器一些信息
请求头名称  :     请求头值
User-Agent:	    Mozilla/5.0 (Windows NT 6.1; Win64....20100101 Firefox/60.0
	*浏览器告诉服务器,浏览器版本信息
	*可以在服务器端获取该头的信息,解决浏览器的兼容性问题
	
Referer   :		http://localhost/login.html
	*告诉服务器,当前请求从哪里来
	*防盗链和统计工作
3.请求空行
空行,就是用于分割POST请求的请求头,和请求体的。
4.请求体(正文):Post/GET无
	username=zhangsan

2.3 HTTP协议之响应部分

响应消息数据格式

1.响应行

2.响应头

3.响应体

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LQLkiXN5-1623947454337)(F:\Note\1562595384017.png)]

1.响应行
协议版本	状态码		状态码描述
	200	:代表响应成功
	302	:需要进行重定向操作
	304	:需要查找本地缓存
	404	:请求资源不存在
	405	:请求方式没有对应的doXxx方法
	500	:服务器内部错误
2.响应头
	通常一个key对应一个value,也有一个key对应多个value
	Location	:重定向的路径。
	Refresh	:定时刷新。
	Content-Disposition:文件下载的时候使用
3.响应体
就是显示到浏览器上页面的代码

3. Servlet

3.1 概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y060Kkca-1623947454338)(F:\Note\1562583314796.png)]

概念:运行在服务器端的小程序

  • Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
  • 将来我们自定义一个类,实现Servlet接口,复写方法。

3.2 快速入门

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnsNExTY-1623947454340)(F:\Note\1562571288478.png)]

1.定义一个类实现Servlet接口,实现抽象方法

public class ServletDemo1 implements Servlet{
	@Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello servlet");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

2.配置Servlet

在web.xml中配置:
  <!--配置Servlet -->
  <servlet>
    <servlet-name>ServletDemo2</servlet-name>
    <servlet-class>com.itheima.servlet.demo3.ServletDemo2</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletDemo2</servlet-name>
    <url-pattern>/ServletDemo2</url-pattern>
  </servlet-mapping>

浏览器地址:http://localhost:8080/web_test/ServletDemo2
localhost:8080     :localhost本地ip地址 + 8080->应用程序(Tomcat)
/web_test		   :Tomcat\webapps目录下项目名称
/ServletDemo2	   :通过<servlet-mapping>映射找到<servlet-name>ServletDemo2</servlet-name>,					再找到<servlet-class>com.itheima.servlet.demo3.ServletDemo2
浏览器地址实际访问:
http://localhost:8080 /web_test                /ServletDemo2
本机/Tomcat目录/webapps/web_test/WEB-INF/classes/com.itheima.servlet.demo3.ServletDemo2

3.3 Sevelet执行原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KXqQg8Nj-1623947454342)(F:\Note\1562586973297.png)]

1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
2. 查找web.xml文件,是否有对应的<url-pattern>标签体内容。
3. 如果有,则在找到对应的<servlet-class>全类名
4. tomcat,通过反射(Class.forName())将字节码.class文件加载到内存中,并创建对象clz.newInstance();
5. 调用其方法service(),因为继承自Servlet接口,遵循了规则,所有一定有一个service()方法让对象调用

3.4 Servlet生命周期

一般顺序:init()->service()->destroy()

1. 被创建:执行init方法,只执行一次
		* Servlet什么时候被创建?
			* 默认情况下,第一次被访问时,Servlet被创建
			* 可以配置执行Servlet的创建时机。web.xml下
				* 在<servlet>标签下配置(见下图)
					1. 第一次被访问时,创建
                		* <load-on-startup>的值为负数
		            2. 在服务器启动时,创建
		                * <load-on-startup>的值为0或正整数
		    * Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
			* 多个用户同时访问时,可能存在线程安全问题。
			* 解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改值

	2. 提供服务:执行service方法,执行多次
		* 每次访问Servlet时,Service方法都会被调用一次。
	3. 被销毁:执行destroy方法,只执行一次
		* Servlet被销毁时执行。服务器关闭时,Servlet被销毁
		* 只有服务器正常关闭时,才会执行destroy方法。
		* 先执行destroy方法,然后Servlet才被销毁,一般用于释放资源

配置执行Servlet的创建时机:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8VYFK9Kw-1623947454344)(F:\Note\1562586019029.png)]

3.5 Servlet3.0注解配置

* 好处:
	* 支持注解配置。可以不需要web.xml了。
* 步骤:
	1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
	2. 定义一个类,实现Servlet接口
	3. 复写方法
	4. 在类上使用@WebServlet注解,进行配置
		* @WebServlet("资源路径") //不需要包名+类名了,因为注解就是作用在此类上,即只需要关心虚拟资源名
@Target({ElementType.TYPE})//作用在类上
@Retention(RetentionPolicy.RUNTIME)//保留到运行时期
@Documented//可以被生成到文档中
public @interface WebServlet {
    String name() default "";//相当于<Servlet-name>

    String[] value() default {};//代表urlPatterns()属性配置

    String[] urlPatterns() default {};//相当于<url-pattern>

    int loadOnStartup() default -1;//相当于<load-on-startup>

    WebInitParam[] initParams() default {};

    boolean asyncSupported() default false;

    String smallIcon() default "";

    String largeIcon() default "";

    String description() default "";

    String displayName() default "";
}

3.6 Idea和Tomcat相关配置

1. IDEA会为每一个tomcat部署的项目单独建立一份配置文件
	* 查看控制台的log:Using CATALINA_BASE:   		"C:\Users\dashuaibi\.IntelliJIdea2019.1\system\tomcat\Tomcat_8_5_31_Tomcat3_0"
	*虚拟目录文件:
"C:\Users\dashuaibi\.IntelliJIdea2019.1\system\tomcat\Tomcat_8_5_31_Tomcat3_0\conf\Catalina\localhost"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wz2eeARO-1623947454346)(F:\Note\1562593250499.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k8ez0rhT-1623947454348)(F:\Note\1562593387595.png)]

2.工作空间项目 和 tomcat部署的web项目
	*tomcat真正访问的是“tomcat部署的web项目”,"tomcat部署的web项目"对应着"工作空间项目" 的web目录下的所有资源
	工作空间项目是.java文件
		F:\ideaworspace\Tomcat3.0\src\cn\iyhome\Servlet3\Servlet3Demo.java
	tomcat部署的web项目是.clas文件
		F:\ideaworspace\Tomcat3.0\out\artifacts\Tomcat3_0_war_exploded\WEB-		INF\classes\cn\iyhome\Servlet3\Servlet3Demo.class
	
3.* WEB-INF目录下的资源不能被浏览器直接访问。	

3.7 Servlet体系结构

SUN设计之初,是有野心,以后的互联网不仅仅只使用http协议,可以通过GenericServlet实现。
HttpServlet是一个与协议相关的Servlet是专门用来处理HTTP协议的请求。通常编写一个Servlet一般都会让这个Servlet继承HttpServlet重写service方法。
在service方法内部根据请求方式不同执行不同的doXXX的方法(get请求执行doGet方法,如果是post请求就会执行doPost方法)。
所以往往继承了HttpServlet之后不需要重写service方法,只需要重写doGet和doPost方法即可。往往请求要处理的内容的代码都是一致的,所以需要让doGet和doPost相互调用可以简化编程。
	Servlet -- 接口
		|
	GenericServlet -- 抽象类
		|
	HttpServlet  -- 抽象类

	* GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
		* 将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可

	* HttpServlet:对http协议的一种封装,简化操作
		1. 定义类继承HttpServlet
		2. 复写doGet/doPost方法

3.8 Servlet相关配置

1. urlpartten:Servlet访问路径
	1. 一个Servlet可以定义多个访问路径 : @WebServlet({"/d4","/dd4","/ddd4"})
	2. 路径定义规则:
		1. /xxx:路径匹配
		2. /xxx/xxx:多层路径,目录结构
		3. *.do:扩展名匹配

3.9 ServletConfig对象

概述:

ServletConfig用来获得Servlet的相关的配置和对象

获得ServletConfig对象

ServeltConfig getServletConfig()

ServletConfig的常用方法

String getInitParameter(String name):获得Servlet的初始化参数的value,即值

Enumeration getInitParameterNames():获取初始化参数的key,即name

ServletContext getServletContext():获得ServletContext对象

String getServletName():获取的Servlet的名称

代码演示

配置初始化参数:
<servlet>

        <servlet-name>demo04</servlet-name>
        <servlet-class>cn.iyhome.web.servlet.ServletDemo4</servlet-class>

        <!--配置初始化参数-->
        <init-param>
            <param-name>username</param-name>
            <param-value>zhangsan</param-value>
        </init-param>

        <init-param>
            <param-name>password</param-name>
            <param-value>abc</param-value>
        </init-param>

    </servlet>

    <servlet-mapping>

        <servlet-name>demo04</servlet-name>
        <url-pattern>/demo04</url-pattern>

    </servlet-mapping>
java代码:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("hello servlet");
        //getServletConfig()
        ServletConfig servletConfig = this.getServletConfig();
        //getInitParameter()
        String username = servletConfig.getInitParameter("username");//zhangsan
        String password = servletConfig.getInitParameter("password");//abc
        System.out.println(username+"->"+password);
        //getInitParameterNames()
        Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
            String key = initParameterNames.nextElement();
            String value = servletConfig.getInitParameter(key);
            System.out.println(key+"=="+value);
            //password=abc
            //username=zhangsan
        }
    }

3.10 ServletContext对象

3.10.1 概述

ServletContext:Servlet的上下文对象。ServletContext对象对Servlet之前和之后的内容都知道。这个对象一个web项目只有一个。在服务器启动的时候为每个web项目创建一个单独的ServletContext对象。

3.10.2 ServletContext对象的作用

3.10.2.1 一:获取web项目信息

因为一个web项目只有一个ServletContext对象,所以这个对象对整个项目的相关内容都是了解的。

方法

ServletContext getServletContext():获取ServletContext对象

String getMimeType(String file):获取文件的MIME对象

String getContextPath():获得web项目请求路径的工程名

String getInitParameter(String name):获得全局Servlet的初始化参数的value,即值

Enumeration getInitParameterNames():获取全局初始化参数的key,即name

备注:

MIME类型:在互联网通信过程中定义的一种文件数据类型

​ 格式:大类型/小类型 text/html image/jped

代码演示

@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*String getMimeType()
        String getContextPath()
        String getInitParameter(String name)
        Enumeration getInitParameterNames()
        */
        //获取ServletContext对象
        ServletContext servletContext = getServletContext();
        //getMimeType()
        String mimeType = servletContext.getMimeType("a.txt");
        //getContextPath()
        String contextPath = servletContext.getContextPath();
        //getParameter(String name)
        String username = servletContext.getInitParameter("username");
        //Enumeration getInitParameterNames()
        Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
            String key = initParameterNames.nextElement();
            String value = servletContext.getInitParameter(key);
            System.out.println(key + "->" + value);
        }
        //
        System.out.println("mimeType: " + mimeType);
        System.out.println("ContextPath: " + contextPath);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
sout:
password->abc
username->zhangsan
mimeType: text/plain
ContextPath: /Tomcat3_0_war_exploded
3.10.2.2 二:获取web项目下文件

之前使用IO流就可以读取文件(java项目中)。现在是一个web项目,web项目需要发布到tomcat下才能访问的。获取web项目下的文件如果使用传统的IO就会出现问题(原因:路径中使用的是相对路径,相对的是JRE环境)。

方法

String getRealPath(String path)

		服务端路径:不需要带工程名
		ServletContext context = this.getServletContext();
        //配置文件放在src下
        String arealPath = context.getRealPath("/WEB-INF/classes/a.txt");
		//"/WEB-INF/classes/a.txt"-> http:localhost:8080/web01/WEB-INF/classes/a.txt
        //配置文件放在WEB-INF下
        String brealPath = context.getRealPath("/WEB-INF/b.txt");

        //配置文件放在web下
        String crealPath = context.getRealPath("/c.txt");
//配置文件放在src下
F:\ideaworspace\Tomcat3.0\out\artifacts\Tomcat3_0_war_exploded\WEB-INF\classes\a.txt
//配置文件放在WEB-INF下
F:\ideaworspace\Tomcat3.0\out\artifacts\Tomcat3_0_war_exploded\WEB-INF\b.txt
//配置文件放在web目录下
F:\ideaworspace\Tomcat3.0\out\artifacts\Tomcat3_0_war_exploded\c.txt
3.10.2.3 三:域对象:共享数据

ServletContext是在服务器启动的时候为每个web项目单独创建一个ServletContext对象。当web项目从服务器中移除,或者是关闭服务器的时候ServletContext对象会被销毁。向ServletContext中保存的数据一直存在(当服务器关闭的时候ServletContext对象被销毁,然后里面数据才会失效)。范围:整个web应用。

方法

void setAtrribute(String name,Object value)

Object getAtrribute(String name)

void removeAttribute(String name)

代码演示

@WebServlet("/ServletDemo8")
public class ServletDemo8 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        servletContext.setAttribute("testAtr", "test");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
@WebServlet("/ServletDemo9")
public class ServletDemo9 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        Object username = servletContext.getAttribute("testAtr");
        System.out.println(username);//test
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

3.11 Servlet域对象总结

3.11.1 请求范围(ServletRequest)

何时创建和销毁

  • 创建:当用户向服务器发送一次请求的时候,服务器创建一个request对象
  • 销毁:当服务器对这次请求做出了响应,服务器就会销毁这个request对象

如何存取数据

set/get/remove

作用范围

一次请求(转发就是一次请求)

3.11.2 会话范围(HttpSession)

何时创建和销毁

  • 创建:服务器端第一次调用getSession()方法的时候
  • 销毁:三种情况
    • Session过期,默认时间为30分钟,在Tomcat的web.xml中中可以配置
    • 非正常关闭服务器(正常关闭服务器-session会被序列化到项目下)
    • 手动销毁,调用方法 session.invalidate()

如何存取数据

get/set/remove

作用范围

一次会话,多次请求

3.11.3 应用范围(ServletContext)

何时创建和销毁

  • 创建:服务器启用的时候创建,为每个web项目创建一个单独的ServletContext对象
  • 销毁:服务器关闭或者web项目被删除

如何存取数据

get/set/remove

作用范围

整个应用的范围

4.Requset

4.1 概述

4.1.1 requset和response原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jG1JZQEV-1623947454350)(F:\Note\1562684815646.png)]

注意:

1.Request和Response是由服务器创建的,程序猿是来使用它们
2.Request对象时来获取请求消息的,response对象时用来设置响应消息

4.1.1 Request继承体系

ServletRequest 接口
	|	继承
HttpServletRequest 接口
	|
org.apache.catalina.connector.RequestFacade(TomCat实现的类)
    
查看apache-tomcat源码可以看到
public class RequestFacade implements HttpServletRuquest{}

4.2 Request功能

4.2.1 获取请求消息数据

获取请求行数据

GET /Tomcat3_0_war_exploded/RequestDemo1?name=zhangsan HTTP/1.1

String getMethod():获取请求方式 GET

🔴String getContextPath():获取虚拟目录 Tomcat3_0_war_exploded

String getServletPath():获取Servlet路径 RequestDemo1

String getQueryString():获取请求参数 name=zhangsan GET

String getRequestURI():获取请求地址 Tomcat3_0_war_exploded/RequestDemo1 比URL范围更大

🔴String getRequestURL():URL http://localhost:8080/Tomcat3_0_war_exploded/RequestDemo1

String getProtocol:获取协议及版本 HTTP/1.1

String getRemoteAddr():获取客户机的IP地址 192.168.16.63

获取请求头数据

String getHeader(String name):通过请求头的名称获取请求头的值

Enumeration<String> getHeaderNames():获取所有请求头的名称

获取请求体数据(POST)

🔴BufferedReader getReader():获取字符输入流,只能操作字符数据

ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据

代码演示

@WebServlet("/RequestDemo1")
public class RequestDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws  IOException {
        //System.out.println(request);
        //Enumeration<String> getHeaderNames()
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();

            String value = request.getHeader(key);
            System.out.println(key + "->" + value);
        }
        //String getHeader(String name)
        String referer = request.getHeader("referer");
        System.out.println(referer);

        //获取请求消息体
        //1.获取字符流
        BufferedReader reader = request.getReader();
        //2.读取字符流
        String len = null;
        while ((len = reader.readLine()) != null) {
            response.getWriter().println(len);
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
web页面:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
</head>
<body>
    <!--注意只有post方式有请求体-->
    <form action="/Tomcat3_0_war_exploded/RequestDemo1" method="post">
        <input type="text" name="username"/><br/>
        <input type="submit" value="登陆">
    </form>

    <a href="/Tomcat3_0_war_exploded/RequestDemo1">requestdemo1...</a>
</body>
</html>

4.2.2 其他功能

1.获取请求参数通用方法(无论是get还是post)

String getParameter(String name):根据参数名获取参数值

String[] getParameterValues(String name):根据参数名获取参数值的数组

Enumeration<String? getParameterNames():获取所有参数名

Map<String,String[]> getParameterMap():获取所有参数的map集合

代码演示

@WebServlet("/RequestDemo1")
public class RequestDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //getParameter(String name)
        String username = request.getParameter("username");
        System.out.println(username);
        System.out.println("-------------------");

        //String[] getParameter(String name)
        String[] hobbies = request.getParameterValues("hobby");
        System.out.println(Arrays.toString(hobbies));
        System.out.println("-------------------");

        //Enumeration<String> getParameterNames()
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String key = parameterNames.nextElement();
            String[] value = request.getParameterValues(key);
            System.out.println(key + "->" + Arrays.toString(value));
        }
        System.out.println("-------------------");

        //Map<String,String[]> getParameterMap()
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
        for (Map.Entry<String, String[]> entry : entries) {
            System.out.println(entry.getKey()+"->"+ Arrays.toString(entry.getValue()));
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
sout:
zhangsan
-------------------
[game, study]
-------------------
username->[zhangsan]
password->[abc]
hobby->[game, study]
six->[man]
-------------------
username->[zhangsan]
password->[abc]
hobby->[game, study]
six->[man]
login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
</head>
<body>

    <form action="/Tomcat3_0_war_exploded/RequestDemo1" method="post">
        <input type="text" name="username"/><br/>
        <input type="text" placeholder="input psw" name="password"/><br/>
        <input type="submit" value="登陆">

        <input type="checkbox" name="hobby" value="game">游戏
        <input type="checkbox" name="hobby" value="study">学习

        <input type="radio" name="six" value="man" checked="checked"><input type="radio" name="six" value="woman"></form>

    <a href="/Tomcat3_0_war_exploded/RequestDemo1">requestdemo1...</a>
</body>
</html>

2.请求转发

一种在服务器内部的资源跳转方式

步骤

1.通过Request对象获取[请求调度程序]对象:RequestDispatcher

RequestDispatcher getRquestDispatcher(String name): name是servlet的url-pattern

2.使用RequestDispatcher对象来进行转发

RequestDispatcher.forward(ServletRequest req, ServletResponse rep)

可以使用链式编程,Request.getRequestDispatcher(“/demo1”).forward(request,response);

特点

  • 浏览器地址栏不发生变化
  • 这是服务器内部的资源跳转方式,外部资源不能被转发访问的
  • 转发是一次请求

3.共享数据

域对象:一个有作用范围的对象,可以在范围内共享数据

request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据

方法:

void setAttribute(String name,Object obj)

Object getAttribute(String name)

void removeAttribute(String name)

4.获取ServletContext对象

方法:

ServletContext getServletContext()

4.2.3 Request对象接收中文

1.GET方式

Tomcat8以后已经解决了Request对象接收中文乱码的问题

在Tomcat8以前:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mI05hSbK-1623947454353)(F:\Note\1562906734262.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xA3esCJ5-1623947454355)(F:\Note\1562906877606.png)]

2.POST方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQn3PswC-1623947454372)(F:\Note\1562907790075.png)]

5. Response

5.1 概述

开发的软件是B/S结构的软件,可以通过浏览器访问服务器的软件。从浏览器输入一个地址访问服务器(将这个过程称为是请求)。服务器接收到请求,需要进行处理,处理以后需要将处理结果显示回浏览器端(将这个过程称为是响应)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5bRslnG5-1623947454376)(F:\Note\1562854379240.png)]

5.2 功能

设置响应行
格式: HTTP/1.1 200 ok

setStatus(int sc):设置状态码

设置响应头

void setHeader(String name ,String value)

void addHeader(String name,String value)

eg: 
setHeader(“content-Type,“text/plain”) 结果:content-Type:text/plain
addHeader("content-Type","text/html")  结果:content-Type:text/plain, text/html
//重定向
setStatus(302);
setHeader("location","/day15/responseDemo2");
//简单写法
sendRedirect(String location)

案例:定时刷新

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fkCPFOd6-1623947454378)(F:\Note\1562857663211.png)]

设置响应体

步骤:

1.获取输出流

  • 字符输出流: ServletOutputStream getOutputStream()
    • 一定会出现乱码现象,所以需要手动设置编码
@WebServlet("/servletDemo2")
public class ServletDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //设置服务器的编码方式
        // 1.response.setCharacterEncoding("uft-8");
        //中文操作系统使用的是gbk,如果我们知道浏览器的默认编码方式,那么直接使用句1的编码即可

        //告知浏览器采用哪种编码方式,其实这句话也会设置服务器编码,所以可以省略上面那一句
        //2.response.setHeader("content-type","text/html;charset=utf-8");
        //简单的写法,直接使用句2即可.
        //3.response.setContentType("text/html;charset=utf-8");

        /*总结
        * 1.知道浏览器的默认编码方式,使用句1
        * 2.不知道浏览器的默认编码方式
        *   a.使用句1,句2
        *   b.使用句2
        *   c.使用句3
        * */
        
        //getWriter()获取的流的默认编码是ISO-8859-1
        response.getWriter().println("从demo1获取到了demo2的地址,重新获取");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 字节输出流: PrintWriter getWriter()
    • 不一定出现乱码,要看浏览器的编码是否和服务器一致都为utf-8
@WebServlet("/servletDemo5")
public class ServletDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");

        //1.获取字节输出流
        ServletOutputStream sos = response.getOutputStream();
        //2.输出数据
        sos.write("您好".getBytes("utf-8"));

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

乱码图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MCN1CDfQ-1623947454379)(F:\Note\1562907032377.png)]

重定向

sendRedirect(String location)

@WebServlet("/servletDemo1")
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*response.setStatus(302);
        response.setHeader("Location", "/Tomcat3_0_war_exploded/servletDemo2");
        */
        response.sendRedirect("/Tomcat3_0_war_exploded/servletDemo2");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

**特点:**redirect

1.地址栏发生变化

2.重定向可以访问其他站点(服务器)的资源

3.重定向是两次请求,不能用request对象来共享数据

注意:和request.getRequestDispatcher(“/demo”).forward(request,response);的区别

其他功能
  • 设定浏览器打开页面的采用的字符集: void setContentType(String type)

  • 设置响应字符流的缓冲区字符集: void setCharacterEncoding (String charset)

  • 服务器向浏览器写回Cookie的方法: void addCookie(Cookie cookie)

6. JSP

6.1 JSP运行原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xwgRATYT-1623947454381)(F:\Note\1562907923362.png)]

JSP文件翻译成Java文件,将这个Java文件编译生成class文件,运行class文件。

6.2 JSP的脚本元素

6.2.1 概述

JSP = HTML + Java代码 + JSP自身东西

JSP的脚本元素就是在JSP中嵌入Java代码。

6.2.2 脚本元素的分类

6.2.2.1 声明标签

语法:

<%! 变量或方法声明 %>
写在这个脚本中的代码,翻译成Servlet内部的成员变量或成员方法。

<%!
	//声明变量
	int i = 3 ;
%>
6.2.2.2 表达式标签

语法:

<%= 表达式 %>
写在这个脚本中的代码,翻译成方法内部的out.print();当中的内容。

<%= i %>
6.2.2.3程序代码标签

语法:

<% 程序代码 %>
写在这个脚本中的代码,翻译成方法内部的局部变量或方法内部代码片段

<%
	//代码块
	int x = 5 ;
	x++;
%>

6.3 JPS的指令元素

6.3.1 语法

<%@ 指令名称 属性名称=属性的值 属性名称=属性的值%

6.3.2 Page指令

写法

<%@ page 属性名=属性值%>

作用

  • Page指令用来定义JSP文件的全局属性
  • 这些属性可以单独用,也可以同时出现
  • 在JSP页面中,只有import属性可以出现多次

属性

	language属性:	声明使用脚本的语言。只能是java。
	extends属性:	标明JSP编译成Servlet的时候继承的类。默认值:HttpJspBase。
	session属性:		标明JSP中是否可以直接使用session对象。默认值是true。
	buffer属性:		标明JSP对客户端输出缓冲区大小。默认值8kb。
	autoFlush属性:	如果缓冲区大小溢出,是否自动刷出。默认true。
	import属性:		用于导入Java包或类。
	contentType属性:标明JSP被浏览器解析和打开的时候采用的默认的字符集。
	pageEncoding属性:JSP文件及JSP翻译后的Servlet保存到硬盘上采用字符集。
	isErrorPage属性:	处理JSP页面异常。
	errorPage属性:	处理JSP页面异常。
	isELIgnored属性:	通知JSP是否忽略EL表达式。

6.3.3 include指令

语法

<%@include 属性名=属性值%>

作用

在jsp页面中静态包含一个文件,同时由该JSP解析包含的文件内容`

属性

file属性: 指示JSP页面包含的页面路径

原理(静态包含原理)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O9y8WGJB-1623947454383)(F:\Note\1563069707689.png)]

注意

  • 应该将被包含的页面的结构去掉。留下body

  • 在被包含的页面中定义变量,在包含的页面中还可以使用。

6.3.4 taglib指令

语法

<%@ taglib 属性名=属性值%>

作用

用于在JSP页面中引入标签库

属性

uri: 引入标签库的路径

prefix: 引入标签库的别名

6.4 JSP的内置对象

index.jsp翻译后的index_jsp.java ,实质就是一个servlet

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements ... {
      
      /*
       <%!
       		//声明标签
			//声明变量
			int i = 3 ;
		%>
      */
      int x =3;
       
	private static final ....//静态变量
	static{
		....//静态代码块
	}
	public ... getXXX(){}
	//重点
	public void _jspInit(){
	
	}
	
	public void _jspDestory(){
	
	}
	
	public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response){
		//内置元素
		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;charset=UTF-8");
      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("\n");
      out.write("<html>\n");
      out.write("  <head>\n");
      out.write("    <title>$Title$</title>\n");
      out.write("  </head>\n");
      out.write("  <body>\n");
      out.write("    ");
      out.write("\n");
      out.write("    ");
      out.print( x );//表达式标签<%= x %>
      out.write("\n");
      out.write("    ");
      
      /*
      	程序代码标签
      	<%
      		x++;
      	%>
      */
      x++;
      
    } catch (java.lang.Throwable t) {
    	...
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
	
}
3. 内置对象
	* 在jsp页面中不需要创建,直接使用的对象
	* 一共有9个:
			变量名					真实类型						作用
		* pageContext				PageContext					当前页面共享数据,还可以获取其他八个内置对象
		* request					HttpServletRequest			一次请求访问的多个资源(转发)
		* session					HttpSession					一次会话的多个请求间
		* application				ServletContext				所有用户间共享数据
		* response					HttpServletResponse			响应对象
		* page						Object						当前页面(Servlet)的对象  this
		* out						JspWriter					输出对象,数据输出到页面上
		* config					ServletConfig				Servlet的配置对象
		* exception					Throwable					异常对象

6.4.1 pageContext详解

pageContext对象直接翻译为“页面上下文”对象,代表的是当前页面运行的一些属性。它是javax.servlet.jsp.PageContext类的实例对象。

方法

get/set/remove/findAttribute(String name):属性

获取其他八个对象:

getExceptiongetPagegetRequestgetResponsegetServletConfiggetServletContextgetSessiongetOut

6.5 JSP的四个作用范围

6.5.1 概述

	PageScope		:页面范围。
	页面范围指的是在当前的页面内有效,出了这个页面,用pageContext保存的数据就无效了。
	RequestScope		:请求范围。
	从客户端向服务器发送一次请求,服务器对这次请求作出了响应之后,用request保存的数据就无效了。
	SessionScope		:会话范围。
	每个浏览器向服务器发送请求(多次请求)。将该会话结束。
	ApplicationScope	:应用范围。
	在整个应用中任意的地方都可以获取。

6.5.2 存取数据

存:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U11iOdPw-1623947454385)(F:\Note\1563073825269.png)]

取:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z1iq7PEZ-1623947454387)(F:\Note\1563073869568.png)]

pageContext.findAttribute(String name):查找属性方法:先根据小范围的名称进行查找,如果找到了就返回,如果没有找到就会去比其大一个域的范围进行查找。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pKdPqo4p-1623947454389)(F:\Note\1563073977816.png)]

6.6 JSP动作标签

JSP的动作标签用于在JSP页面中提供业务逻辑功能,避免在JSP页面中直接编写Java代码,造成jsp页面难以维护。

常用动作标签

	<jsp:forward/>	:请求转发。
	<jsp:include/>:包含(动态包含)。
	<jsp:param/>:传递参数。

动态包含的原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xh8bkLq7-1623947454390)(F:\Note\1563074775168.png)]

6.7 MVC模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iv9iotPM-1623947454392)(F:\Note\1563080471321.png)]

1. M:Model,模型。JavaBean
	* 完成具体的业务操作,如:查询数据库,封装对象
2. V:View,视图。JSP
	* 展示数据
3. C:Controller,控制器。Servlet
    * 获取用户的输入
    * 调用模型
    * 将数据交给视图进行展示

* 优缺点:
1. 优点:
	1. 耦合性低,方便维护,可以利于分工协作
	2. 重用性高

2. 缺点:
	1. 使得项目架构变得复杂,对开发人员要求高

7.Session

7.1 会话技术

7.1.1 会话技术的概念

会话简单理解为:用户打开一个浏览器,点击多个超链接访问服务器的web资源,然后关闭浏览器,整个过程称为是一次会话。

7.1.2 会话技术出现的原因

每个用户与服务器进行交互过程中,产生一些各自的数据,程序想要把这些数据进行保存,就需要使用会话技术。

例如:用户点击超链接购买一个商品,程序应该保存用户所购买的商品,以便于用户点击结账可以得到用户所购买的商品信息。

思考:用户购买的商品保存在request或ServletContext中是否可以?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gvKgFTYN-1623947454393)(F:\Note\1562893240890.png)]

7.1.3 Cookie和Session的区别

  • Cookie的局限性

    • 保存的数据和个数是有限制的
    • 数据是保存在客户端浏览器上,相对来说不是很安全
  • Session

    • 个数和大小是没有限制的
    • 数据是保存在服务器上的,相对安全

7.2 Session技术

7.2.1 概述

Session是保存在服务器端,利用这个技术,服务器在运行时为每一个用户的浏览器创建一个独享的session对象。由于session为用户浏览器独享,所有用户在访问服务器的时候,可以把各自的数据放在各自的session中,当用户再次访问服务器中的web资源的时候,其他web资源再从用户各自的session中取出数据为用户服务。

7.2.2 实现原理

  • 基于Cookie的,基于Cookie会写一个Session的ID

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-803lf6RF-1623947454395)(F:\Note\1562893784948.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9YzHr9eN-1623947454396)(F:\Note\1562900786477.png)]

7.2.3 Session域对象存取数据

7.2.3.1 作为域对象的API

Session getSession(): 用Request对象的getSession()方法创建Session对象,且只会创建一次

void setAttribute(String name,Object value)

Object getAttribute(String name)

void removeAttribute(String name)

7.2.3.2 作为域对象的作用范围

​ Session作为域对象,作用范围就是一次会话的范围.一次会话,指的是用户打开浏览器点击多个超链接,访问服务器资源,到最后关闭浏览器的过程.

8. Cookie

8.1 概述

Cookie是客户端技术,程序把每个用户的数据以cookie的形式保存到各自浏览器中。当用户使用浏览器再次访问服务器中的web资源的时候,就会带着各自的数据过去。这样,web资源处理的就是用户各自的数据了。

8.2 实现原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QQkHAA9o-1623947454397)(F:\Note\1562893629612.png)]

8.3 Cookie的API

8.3.1 方法

构造方法

Cookie(String name ,String value)

其他方法

String getName():获取Cookie的名称的方法

String getValue():获取Cookie的值

void setDomain(String pattern):设置Cookie的有效域名

void setPath(String uri):设置Cookie的有效路径

void setMaxAge(int expiry):设置Cookie的有效时长

操作Cookie的方法

Cookie[] getCookies():通过HttpServletRequest对象中的方法获取congress浏览器带过来的

void addCookie(Cookie cookie):通过HttpServletResponse对象中的方法向浏览器写回Cookie

8.3.2 案例

需求

记录用户上次访问时间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7piFLM1R-1623947454399)(F:\Note\1562894151523.png)]

代码实现

工具类:判断是否是第一次访问
Servlet:

8.3.3 使用细节

  • 一个Cookie只用标识一种信息,至少含有一个标识该信息的名称和值。
  • 一个web站点可以给一个浏览器发送多个Cookie。一个web浏览器可以存储多个web站点的Cookie。
  • 浏览器一般只允许存放300个Cookie,每个站点最多可以存放20个Cookie,每个Cookie的大小限制为4KB(老版本浏览器)。-----浏览器存放的Cookie的大小和个数是有限制的。
  • 如果创建了一个Cookie,并发送到浏览器,默认情况下它是一个会话级别的Cookie。用户退出浏览器就被删除。如果希望将这个Cookie存到磁盘上,需要设置有效时长调用setMaxAge(int maxAge)方法,以秒为单位
  • 需要手动删除持久性Cookie,可以将Cookie的有效时长设置为0.必须注意:删除Cookie时候,path必须一致,否则无法删除。

9. 登陆案例

案例需求分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E5tacAQp-1623947454400)(F:\Note\1562915214619.png)]

思路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mizb8cM3-1623947454402)(F:\Note\1562916994451.png)]

9.1 MVC准备

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YEz7uD2B-1623947454403)(F:\Note\1562915086047.png)]

9.2 创建数据库

CREATE DATABASE Web06;
USE Web06;
CREATE TABLE users(
	uid INT PRIMARY KEY AUTO_INCREMENT,
	usernames VARCHAR(32),
	passwrod VARCHAR(32)
);

INSERT INTO users VALUES (NULL,'zhangsan','123');
INSERT INTO users VALUES (NULL,'wangwu','123');

SELECT * FROM users

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G81YUTF9-1623947454405)(F:\Note\1562917815963.png)]

9.3 创建JDBCUtilss工具类

10. EL&&JSTL

10.1 EL

 jsp默认支持el表达式的。如果要忽略el表达式
     1. 设置jsp中page指令中:isELIgnored="true" 忽略当前jsp页面中所有的el表达式
     2. \${表达式} :忽略当前这个el表达式

10.1.1 EL获取数据

EL表达式语句在执行的时候,会调用pageContext.findAttribute()方法。分别从page、request、session、application范围查找相应对象,找到就会返回相应对象,找不到返回””(不是null,是空的字符串)。EL所获取的数据需要在四个作用范围中。

语法

1. ${域名称.键名}:从指定域中获取指定键的值
    * 域名称:
        1. pageScope		--> pageContext
        2. requestScope 	--> request
        3. sessionScope 	--> session
        4. applicationScope --> application(ServletContext)
    * 举例:在request域中存储了name=张三
    * 获取:${requestScope.name}

2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
3. 获取对象、List集合、Map集合的值
    1. 对象:${域名称.键名.属性名}
    * 本质上会去调用对象的getter方法

    2. List集合:${域名称.键名[索引]}

    3. Map集合:
    * ${域名称.键名.key名称}
    * ${域名称.键名["key名称"]}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l1yQaPTm-1623947454406)(F:\Note\1563087136169.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0N3nMhqD-1623947454407)(F:\Note\1563087495222.png)]

注意:n 如果map的key中包含了特殊字符,不能使用.必须使用[]。

.用来获取对象的属性的。[]用来获得下标。

10.1.2 执行运算

* 运算符:
    1. 算数运算符: + - * /(div) %(mod)
    2. 比较运算符: > < >= <= == !=
    3. 逻辑运算符: &&(and) ||(or) !(not)
    4. 空运算符: empty
        * 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
        * ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
        * ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0

10.1.3 获取web开发常用的对象

* el表达式中有11个隐式对象
	* pageContext:
    	* 获取jsp其他八个内置对象
        * ${pageContext.request.contextPath}:动态获取虚拟目录
	*pageScope			:获取指定域下的名称的数据
	*requestScope		:获取指定域下的名称的数据
	*sessionScope		:获取指定域下的名称的数据
	*applicationScope	:获取指定域下的名称的数据
	*param				:在页面中接收请求参数(接收一个名称对应一个值参数)。
	*paramValues		:在页面中接收请求参数(接收一个名称对应多个值参数)。
	*header				:在页面上获取请求头(获取一个key对应一个value 头)
	*headerValues		:在页面上获取请求头(获取一个key对应多个value 头)
	*cookie				:访问cookie的名称和值(${cookie.key.name} ${cookie.key.value})
	*initParam			:获取全局初始化参数的值

10.2 JSTL

10.2.1 概述

  1. 概念:JavaServer Pages Tag Library JSP标准标签库

    • 是由Apache组织提供的开源的免费的jsp标签
  2. 作用:用于简化和替换jsp页面上的java代码

  3. 使用步骤:

    1. 导入jstl相关jar包
    2. 引入标签库:taglib指令: <%@ taglib url=“ ” prefix=“c”%>
    3. 使用标签

10.2.2 常用标签

set标签

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cNqcNZpX-1623947454408)(F:\Note\1563089104551.png)]

if标签

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y6acnoxW-1623947454409)(F:\Note\1563089442673.png)]

	test属性	:条件
	var属性	:将test中的条件的值赋给一个变量,在var中定义变量
	scope属性:作用范围
foreach标签

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-69rfpQw9-1623947454410)(F:\Note\1563091531365.png)]

11 监听器

11.1 概述

11.1 什么是监听器

监听器就是一个实现了特定接口的Java类,这个Java类用于监听另一个Java类的方法调用或者属性的改变。当被监听对象发生上述事件后,监听器某个方法将会立即被执行。

11.2 用途

用来监听其他对象的变化的。主要应用在图形化界面开发上。

l Java中GUI,Android

11.3 术语

  • 事件源:被监听的对象(汽车)
  • 监听器:监听的对象(报警器)
  • 绑定:汽车上安装报警器
  • 事件:事件源对象的改变(汽车被踹了一脚)
    • 主要功能:用来获得事件源对象

11.2 Servlet中的监听器

11.1 简介

在Servlet中定义了多种类型的监听器,它们用于监听的事件源分别是ServletContext,HttpSession和ServletRequest这三个域对象

11.2.1 监听三个域对象的创建和销毁的监听器(三个)

11.2.1.1 ServletContextListener

ServletContextListener监听器的作用

  • 用来监听ServletContext域对象的创建和销毁

ServletContext创建和销毁

  • 创建:服务器启用的时候,服务器会为每一个web项目创建单独的ServletContext对象
  • 销毁在服务器关闭的时候,或者项目从web项目中移除的时候

ServletContextListener的方法

void contextDestroy(ServletContextEvent sce):监听销毁

void contextInitialized(ServeltContextEvent sce):监听创建

代码


/**
 * 事件源:ServletContext
 * 监听器:mylistener
 * 绑定:通过配置方式或者注解
 * */
@WebListener("")
public class mylistener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("initial...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("destroyed...");
    }
}
web.xml2.5配置:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <listener>
        <listener-class>cn.iyhome.listener.weblistener.mylistener</listener-class>
    </listener>
</web-app>


ServletContextListener企业用途

  • 加载框架的配置文件:

    Spring框架提供了一个核心监听器ContextLoaderListener。

  • 定时任务调度:

11.2.1.2 HttpSessionListener

作用

用来监听HttpSession对象的创建和销毁

HttpSession的创建和销毁

  • 创建:

    服务器端第一次调用getSession()方法时候。

  • 销毁:

    非正常关闭服务器(正常关闭服务器session会被序列化)。

    Session过期(默认过期时间30分钟)。

    手动调用session.invalidate()方法。

方法

void sessionCreated(HttpSessionEvent se)

void sessionDestroyed(HttpSessionEvent se)

代码

@WebListener("")
public class httpMylistener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("created...");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("destroyed...");
    }
}

注意:

访问HTML是否创建Session           :不会

访问JSP是否创建Session           	:会(编译成java文件后,创建了HtttpSeesion对象,并且使用了									getSession()方法赋值

访问Servlet是否创建Session         :不会(默认没有调用getSession方法)

11.2.1.3 ServletRequestListener

作用

用户监听ServletRequest对象的创建和销毁

ServletRequest的销毁和创建

  • 创建:从客户端向服务器发送一次请求,服务器就会创建request对象
  • 销毁:服务器对这次请求作出了响应之后,request对象就销毁了

方法

void requestInitialized(ServletRequestEvent sre)

void requestDestroyed(ServletRequestEvent sre)

代码

/**
 * 事件源:ServletRuquest
 * 监听器:requestMylistener
 * 绑定:通过配置方式
 * */
@WebListener("")
public class requestMylistener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("destroyed...");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("initial...");
    }
}

注意

访问HTML页面是否创建请求对象	:会
访问JSP页面是否创建请求对象		:会
访问Servlet是否创建请求对象	  :会
11.2.1.4 案例 在线人数
@WebListener
public class OnlineCountHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println(httpSessionEvent.getSession().getId()+"上线了");
        Integer count = (Integer) httpSessionEvent.getSession().getServletContext().getAttribute("count");
        count++;
        httpSessionEvent.getSession().getServletContext().setAttribute("count",count);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println(httpSessionEvent.getSession().getId()+"下线了");
        Integer count = (Integer) httpSessionEvent.getSession().getServletContext().getAttribute("count");
        count--;
        httpSessionEvent.getSession().getServletContext().setAttribute("count",count);
    }
}
@WebListener
public class OnlineCountServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //获得事件源
        //服务器启动的时候,设置在线人数初始值0
        servletContextEvent.getServletContext().setAttribute("count", 0);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <h1>在线人数:${count}</h1>
  </body>
</html>

11.2.2 监听三个域对象的属性变更的监听器(三个)

11.2.2.1 ServletContextAttributeListener

作用

监听ServletContext对象中的属性变更(属性添加,移除,替换)的监听器

11.2.2.2 ServletRequestAttributeListener

作用

监听ServletRequestt对象中的属性变更(属性添加,移除,替换)的监听器

11.2.2.3 HttpSessionAttributeListener

作用

监听HttpSession对象中的属性变更(属性添加,移除,替换)的监听器

代码

@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("属性添加了");
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("属性移除了");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("属性更改了");
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <%--<h1>在线人数:${count}</h1>--%>
  <%

    class Person{

      private String name;

      public String getName() {
        return name;
      }

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

    Person p = new Person();
    p.setName("zhangsan");
    session.setAttribute("Person",p);

    p.setName("lisi");
    session.setAttribute("Person",p);

    session.removeAttribute("Person");
  %>
  </body>
</html>

11.2.3 监听HttpSession中的JavaBean的状态的改变的监听器(两个)

保存在Session域中的Java类可以有多种状态:绑定到session中;从session中解除绑定;随session对象持久化到一个存储设备中(钝化);随session对象从一个存储设备中恢复(活化)。

Servlet对方中定义了两个特殊的监听的接口来帮助Java类了解自己在Session域中的状态:

HttpSessionBindingListener接口、HttpSessionActivationListener接口,

实现这两个接口的类不需要在web.xml中进行配置。

11.2.3.1 HttpSessionBindingListener

作用

监听Java类在HttpSession中的绑定和解除绑定的状态的监听器

方法

void valueBound(HttpSessionBindingEvent event)

void valueUnbound(HttpSessionBindingEvent event)

代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <%--<h1>在线人数:${count}</h1>--%>
  <%

    class Person implements HttpSessionBindingListener, Serializable {

      private String name;

      public String getName() {
        return name;
      }

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

      @Override
      public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("Java与Session绑定了");
      }

      @Override
      public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("Java与Session取消绑定了");
      }
    }

    Person p = new Person();
    p.setName("zhangsan");
    session.setAttribute("Person",p);
    session.invalidate();
  %>
  </body>
</html>
11.2.3.2 HttpSessionActivationListener

作用

监听HttpSession中Java类的钝化和活化监听器

方法

void sessionDidActivate(HttpSessionEvent se)

void sessionWillPassivate(HttpSessionEvent se)

代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <%

    class Person implements HttpSessionActivationListener, Serializable {

      private String name;

      public String getName() {
        return name;
      }

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

      @Override
      public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("Persion被钝化了");
      }

      @Override
      public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("Persion被活化了");
      }
    }

    Person p = new Person();
    p.setName("zhangsan");
    session.setAttribute("Person",p);
  %>
    ${sessionScope.p.name}
  </body>
</html>

配置完成session的序列化和反序列化

Context标签可以配置在:
tomcat/conf/context.xml         :所有tomcat下虚拟主机和虚拟目录下的工程都会序列化session

tomcat/conf/Catalina/localhost/context.xml :localhost虚拟主机下的所有项目会序列化session

工程/META-INF/context.xml         :当前工程才会序列化session

12 Filter

12.1 概述

Filter称为过滤器,它是Servlet技术中最实用的技术,web开发人员通过Filter技术,对web服务器所管理的资源(JSP,Servlet,静态图片或静态html文件)进行拦截,从而实现一些特殊的功能。

Filter就是过滤从客户端向服务器发送的请求。

图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vvczQgOv-1623947454412)(F:\Note\1563176255251.png)]

快速入门案例

@WebFilter("/*")
public class FilterDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter过来了");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("doFilter回去了");
    }

    @Override
    public void destroy() {

    }
}
web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <filter>
        <filter-name>FilterDemo1</filter-name>
        <filter-class>cn.iyhome.Fillter.FilterDemo1</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>FilterDemo1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

12.2 FilterChain对象

概述

FilterChain过滤器链:在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为是一个过滤器链。

执行顺序

1.注解配置:按照类名的字符串比较规则比较,值小的先执行

​ 如: AFilter 和 BFilter,AFilter就先执行了。

2.web.xml配置: 谁定义在上边,谁先执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-761Dr4fZ-1623947454414)(F:\Note\1563177032739.png)]

12.3 Filter生命周期

Filter的创建和销毁是由web服务器负责。Web应用程序启动的时候,web服务器创建Filter的实例对象。并调用其init方法进行初始化(filter对象只会创建一次,init方法也只会执行一次)。

每次filter进行拦截的时候,都会执行doFilter的方法。

当服务器关闭的时候,应用从服务器中移除的时候,服务器会销毁Filter对象.

12.4 FilterConfig对象

作用

用来获得Filter的相关的配置的对象。

方法

String getFilterName()

String getInitParameter(String name)

Enumeration getInitParameterNames()

ServletContext getServletContext()

代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VEFFezpC-1623947454415)(F:\Note\1563177963328.png)]

12.5 Filter相关配置

url-pattern配置

完全路径匹配		:以/开始   比如/aaa  /aaa/bbb
目录匹配		 :以/开始 以*结束  比如/*  /aaa/*  /aaa/bbb/*
扩展名匹配		:不能以/开始 以*开始 比如*.jsp  *.do   *.action

servlet-name的配置

专门以Servlet的配置的名称拦截Servlet

dispatcher的配置

默认的情况下过滤器会拦截请求。如果进行转发(需要拦截这次转发)。
dispatcher的取值
	REQUEST	:默认值。默认过滤器拦截的就是请求。
	FORWARD :转发。
	INCLUDE	:页面包含的时候进行拦截
	ERROR	:页面出现全局错误页面跳转的时候进行拦截

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ItDN6rFs-1623947454417)(F:\Note\1563179141676.png)]

e
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("doFilter过来了");
    filterChain.doFilter(servletRequest,servletResponse);
    System.out.println("doFilter回去了");
}

@Override
public void destroy() {

}

}


```xml
web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <filter>
        <filter-name>FilterDemo1</filter-name>
        <filter-class>cn.iyhome.Fillter.FilterDemo1</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>FilterDemo1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

12.2 FilterChain对象

概述

FilterChain过滤器链:在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为是一个过滤器链。

执行顺序

1.注解配置:按照类名的字符串比较规则比较,值小的先执行

​ 如: AFilter 和 BFilter,AFilter就先执行了。

2.web.xml配置: 谁定义在上边,谁先执行

[外链图片转存中…(img-761Dr4fZ-1623947454414)]

12.3 Filter生命周期

Filter的创建和销毁是由web服务器负责。Web应用程序启动的时候,web服务器创建Filter的实例对象。并调用其init方法进行初始化(filter对象只会创建一次,init方法也只会执行一次)。

每次filter进行拦截的时候,都会执行doFilter的方法。

当服务器关闭的时候,应用从服务器中移除的时候,服务器会销毁Filter对象.

12.4 FilterConfig对象

作用

用来获得Filter的相关的配置的对象。

方法

String getFilterName()

String getInitParameter(String name)

Enumeration getInitParameterNames()

ServletContext getServletContext()

代码

[外链图片转存中…(img-VEFFezpC-1623947454415)]

12.5 Filter相关配置

url-pattern配置

完全路径匹配		:以/开始   比如/aaa  /aaa/bbb
目录匹配		 :以/开始 以*结束  比如/*  /aaa/*  /aaa/bbb/*
扩展名匹配		:不能以/开始 以*开始 比如*.jsp  *.do   *.action

servlet-name的配置

专门以Servlet的配置的名称拦截Servlet

dispatcher的配置

默认的情况下过滤器会拦截请求。如果进行转发(需要拦截这次转发)。
dispatcher的取值
	REQUEST	:默认值。默认过滤器拦截的就是请求。
	FORWARD :转发。
	INCLUDE	:页面包含的时候进行拦截
	ERROR	:页面出现全局错误页面跳转的时候进行拦截

[外链图片转存中…(img-ItDN6rFs-1623947454417)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZpRhm8bf-1623947454418)(F:\Note\1563179203673.png)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值