Servlet个人笔记

461 阅读13分钟

1.Servlet介绍

Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

image.png

2.Servlet作用

Servlet专门用来接收客户端的请求,专门接收客户端的请求数据,然后调用底层service处理数据并生成结果
浏览器http请求------》tomcat服务器-------》到达servlet-----》执行doget,dopost方法----》返回数据

HTTP服务器能调用的动态资源文件必须是一个Servlet接口实现类

                   class Student{
		     //不是动态资源文件,Tomcat无权调用
		   }

		   class Teacher implements Servlet{
		     //合法动态资源文件,Tomcat有权利调用

		     Servlet obj = new Teacher();
		     obj.doGet()
		   }

3.Servlet接口实现类

(1)创建一个Java类继承与HttpServlet父类,使之成为一个Servlet接口实现类

(2)重写HttpServlet父类两个方法。doGet或doPost

(3)将Servlet接口实现类信息【注册】到Tomcat服务器

//不直接实现Servlet接口的原因
//如果开发者直接实现Servlet接口,需要重写接口中所有方法,而我们需要使用的只有service方法

//抽象类作用:将接口中不需要使用的抽象方法交给抽象类进行完成,实现类只要对接口需要的方法进行重写
public abstract class HttpServlet extends GenericServlet

//GenericServlet帮我们空实现了接口中除service外的方法
public abstract class GenericServlet implements Servlet

doGet方法处理get请求,doPost方法处理post请求

GET和POST请求方式的区别

GET 方法是默认的从浏览器向 Web 服务器传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中。如果您要向服务器传递的是密码或其他的敏感信息,请不要使用 GET 方法。GET 方法有大小限制:请求字符串中最多只能有 1024 个字符。

POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中 ? 字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。消息以标准输出的形式传到后台程序。

//重写方法快捷键:ctrl+O
//HttpServlet重写的service方法会判断调用get还是post
//模板设计模式:通过父类决定在何种情况下调用子类方法

public class OneServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

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

在web.xml中注册Servlet信息

    <servlet>
        <servlet-name>myservlet</servlet-name>
        <servlet-class>Servlet路径</servlet-class>
    </servlet>
    <!--请求别名-->
    <servlet-mapping>
        <servlet-name>myservlet</servlet-name>
        <url-pattern>/别名</url-pattern>
    </servlet-mapping>

4.Servlet对象生命周期

由谁创建: 所有的Servlet接口实现类的实例对象,只能由Http服务器负责额创建。开发人员不能手动创建Servlet接口实现类的实例对象

创建时间: 在默认的情况下,Http服务器接收到对于当前Servlet接口实现类第一次请求时自动创建这个Servlet接口实现类的实例对象(可以手动配置 改变创建时间)

//可以手动配置 改变创建时间
<load-on-startup>1<load-on-startup><!--填写一个大于0的整数即可-->

创建个数: 在HTTP服务器运行期间,一个Servlet只能创建出一个实例化对象

销毁时间: 在HTTP服务器关闭时,自动销毁所有Servlet对象

5.HttpServletResponse接口

作用: HttpServletResponse接口负责将doGet/doPost方法执行结果写入到【响应体】交给浏览器

(1) 将执行结果以二进制形式写入到【响应体】

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
        //执行结果写入响应体
        String result="Hello";//执行结果
        //获取输出流
        PrintWriter out = resp.getWriter();
        //将执行结果以二进制写入到响应体
        out.print(result);
        //Tomcat负责关闭输出流
        
    }

(2) 设置响应头中[content-type]属性值,从而控制浏览器使用 对应编译器将响应体二进制数据编译为【文字,图片,视频,命令】

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

(3) 设置响应头中【location】属性,将一个请求地址赋值给location. 从而控制浏览器向指定服务器发送请求

        String result="http://www.baidu.com";//执行结果
        //将地址值赋值给响应头中location属性
        resp.sendRedirect(result);

响应对象: 将HttpServletResponse接口修饰的对象称为【响应对象】

6.HttpServletRequest接口

作用: HttpServletRequest接口负责在doGet/doPost方法运行时读取Http请求协议包中信息

(1)可以读取Http请求协议包中【请求行】信息

        //通过请求对象,读取请求行中的url
        String url = req.getRequestURL().toString();
        //通过请求对象,读取请求行中的method
        String method = req.getMethod();

(2)可以读取保存在Http请求协议包中【请求头】或则【请求体】中请求参数信息

浏览器get请求把参数保存在请求头,Tomcat会负责解码,默认utf-8字符集

Post请求将参数保存在请求体,当前对象(req)负责解码,默认ISO-8859-1

        //获取请求参数名称
        Enumeration paramNames=req.getParameterNames();
        while(paramNames.hasMoreElements()){
            String paramName=(String) paramNames.nextElement();
        }
    }

(3)可以代替浏览器向Http服务器申请资源文件调用

将HttpServletRequest接口修饰的对象称为【请求对象】

7.请求对象和响应对象生命周期

(1).在Http服务器接收到浏览器发送的【Http请求协议包】之后,自动为当前的【Http请求协议包】生成一个【请求对象】和一个【响应对象】

(2).在Http服务器调用doGet/doPost方法时,负责将【请求对象】和【响应对象】作为实参传递到方法,确保doGet/doPost正确执行

(3).在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的【请求对象】和【响应对象】 销毁

请求对象响应对象.jpg

8.状态码

Http服务器在推送响应包之前,根据本次请求处理情况将Http状态码写入到响应包中【状态行】上

作用:

如果Http服务器针对本次请求,返回了对应的资源文件。 通过Http状态码通知浏览器应该如何处理这个结果

如果Http服务器针对本次请求,无法返回对应的资源文件 通过Http状态码向浏览器解释不能提供服务的原因

状态码分类

9.多个Servlet之间调用规则

9.1 重定向解决方案

原理: 用户第一次通过【手动方式】通知浏览器访问OneServlet。 OneServlet工作完毕后,将TwoServlet地址写入到响应头 location属性中,导致Tomcat将302状态码写入到状态行。 在浏览器接收到响应包之后,会读取到302状态。此时浏览器 自动根据响应头中location属性地址发起第二次请求,访问 TwoServlet去完成请求中剩余任务

//重定向
response.sendRedirect("请求地址")

重定向.jpg 重定向解决方案特征:

(1)请求地址: 既可以把当前网站内部的资源文件地址发送给浏览器 (/网站名/资源文件名) 也可以把其他网站资源文件地址发送给浏览器(http:// ip地址:端口号 / 网站名 / 资源文件名)

(2)请求次数: 浏览器至少发送两次请求,但是只有第一次请求是用户手动发送。后续请求都是浏览器自动发送的。

(3) 请求方式:重定向解决方案中,通过地址栏通知浏览器发起下一次请求,因此通过重定向解决方案调用的资源文件接收的请求方式一定是【GET】

(4).缺点: 重定向解决方案需要在浏览器与服务器之间进行多次往返,大量时间消耗在往返次数上,增加用户等待服务时间

9.2 请求转发解决方案

原理: 用户第一次通过手动方式要求浏览器访问OneServlet。OneServlet工作完毕后,通过当前的请求对象代替浏览器向Tomcat发送请求,申请调用TwoServlet。Tomcat在接收到这个请求之后,自动调用TwoServlet来完成剩余任务

RequestDispatcher  report = request.getRequestDispatcher("/资源文件名");
report.forward(当前请求对象,当前响应对象)

请求转发.jpg 特征

(1)请求次数: 在请求转发过程中,浏览器只发送一次请求

(2)请求地址: 只能向Tomcat服器申请调用当前网站下资源文件地址request.getRequestDispathcer("/资源文件名")

(3)请求方式: 在请求转发过程中,浏览器只发送一个了个Http请求协议包。参与本次请求的所有Servlet共享同一个请求协议包,因此这些Servlet接收的请求方式与浏览器发送的请求方式保持一致

10.Servlet数据共享

.Servlet规范中提供四种数据共享方案

10.1 ServletContext接口

ServletContext对象称为【全局作用域对象】

使用场景:两个Servlet来自于同一个网站

工作原理:

每一个网站都存在一个全局作用域对象。这个全局作用域对象【相当于】一个Map.在这个网站中OneServlet可以将一个数据存入到全局作用域对象,当前网站中其他Servlet此时都可以从全局作用域对象得到这个数据进行使用

数据共享.jpg

全局作用域对象生命周期:

1)在Http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象

2)在Http服务器运行期间时,一个网站只有一个全局作用域对象

3)在Http服务器运行期间,全局作用域对象一直处于存活状态

4)在Http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁处理

           OneServlet{
             public void doGet(HttpServletRequest request,HttpServletResponse response){
    	        //1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
        	ServletContext application = request.getServletContext();
                //2.将数据添加到全局作用域对象作为【共享数据】
		application.setAttribute("key1",数据)
			    
	}
			 
}

	TwoServlet{	 
	public void doGet(HttpServletRequest request,HttpServletResponse response){
			   
		//1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
		ServletContext application = request.getServletContext();
		//2.从全局作用域对象得到指定关键字对应数据
	        Object 数据 =  application.getAttribute("key1");
	 }
			 
}

10.2 Cookie类

使用场景:两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务

原理:

用户通过浏览器第一次向MyWeb网站发送请求申请OneServlet。 OneServlet在运行期间创建一个Cookie存储与当前用户相关数据, OneServlet工作完毕后,【将Cookie写入到响应头】交还给当前浏览器。 浏览器收到响应响应包之后,将cookie存储在浏览器的缓存, 一段时间之后,用户通过【同一个浏览器】再次向【myWeb网站】发送请求申请TwoServlet时。 【浏览器需要无条件的将myWeb网站之前推送过来的Cookie,写入到请求头】发送过去, 此时TwoServlet在运行时,就可以通过读取请求头中cookie中信息,得到OneServlet提供的共享数据

OneServlet{
		   public void doGet(HttpServletRequest request,HttpServletResponse resp){
		    
		            //1.创建一个cookie对象,保存共享数据(当前用户数据)
			    Cookie card = new Cookie("key1","abc");
			    Cookie card1= new Cookie("key2","efg");
			    //cookie相当于一个map
			    //一个cookie中只能存放一个键值对
			    //这个键值对的key与value只能是String
			    //键值对中key不能是中文
			    //2.将cookie写入到响应头,交给浏览器
			    resp.addCookie(card);
			    resp.addCookie(card1)
		    }
		
		}
  TwoServlet{
		    public void doGet(HttpServletRequest request,HttpServletResponse resp){
		    
		         //1.调用请求对象从请求头得到浏览器返回的Cookie
                         Cookie  cookieArray[] = request.getCookies();
                         //2.循环遍历数据得到每一个cookie的key 与 value
			 for(Cookie card:cookieArray){
			         String key =  card.getName(); 读取key  "key1"
				 Strign value = card.getValue();读取value "abc"
			  }
		    }
		 }

在默认情况下,Cookie对象存放在浏览器的缓存中。因此只要浏览器关闭,Cookie对象就被销毁掉

10.3 HttpSession接口

HttpSession接口修饰对象称为【会话作用域对象】

使用场景:两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于HttpSession对象进行数据共享

HttpSession 与 Cookie 区别:

存储位置:
Cookie:存放在客户端计算机(浏览器内存/硬盘)
HttpSession:存放在服务端计算机内存

数据类型:
Cookie对象存储共享数据类型只能是String
HttpSession对象可以存储任意类型的共享数据Object

数据数量:
一个Cookie对象只能存储一个共享数据
HttpSession使用map集合存储共享数据,所以可以存储任意数量共享数据

OneServlet将数据传递给TwoServlet

             OneServlet{	      
		public void doGet(HttpServletRequest request,HttpServletResponse response){ 
			//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
			HttpSession   session = request.getSession();
                        //2.将数据添加到用户私人储物柜
			session.setAttribute("key1",共享数据)
	}		      
}
            TwoServlet{	      
		public void doGet(HttpServletRequest request,HttpServletResponse response){
			//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
			HttpSession   session = request.getSession();
                        //2.从会话作用域对象得到OneServlet提供的共享数据
			Object 共享数据 = session.getAttribute("key1");
	}		      
}

10.4 HttpServletRequest接口

实现HttpServletRequest的对象被称为【请求作用域对象】

在同一个网站中,如果两个Servlet之间通过【请求转发】方式进行调用, 彼此之间共享同一个请求协议包。而一个请求协议包只对应一个请求对象 因此servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个 Servlet之间实现数据共享

 OneServlet{
				 
		public void doGet(HttpServletRequest req,HttpServletResponse response){
				   
			//1.将数据添加到【请求作用域对象】中attribute属性
			req.setAttribute("key1",数据); //数据类型可以任意类型Object
                        //2.向Tomcat申请调用TwoServlet                                                       req.getRequestDispatcher("/two").forward(req,response)
	 }
				 
 }
 TwoServlet{
		public void doGet(HttpServletRequest req,HttpServletResponse response){
                                            
			//从当前请求对象得到OneServlet写入到共享数据
			Object 数据 = req.getAttribute("key1");
	}			 				 
}

11.监听器

作用: 监听器接口用于监控【作用域对象生命周期变化时刻】以及【作用域对象共享数据变化时刻】

Servlet规范下作用域对象:

ServletContext: 全局作用域对象
HttpSession : 会话作用域对象
HttpServletRequest:请求作用域对象

监听器接口实现类开发步骤

(1)根据监听的实际情况,选择对应监听器接口进行实现
(2)重写监听器接口声明【监听事件处理方法】
(3)在web.xml文件将监听器接口实现类注册到Http服务器

12.过滤器

Filter接口在Http服务器调用资源文件之前,对Http服务器进行拦截

作用:

(1)拦截Http服务器,帮助Http服务器检测当前请求合法性 (2)拦截Http服务器,对当前请求进行增强操作

Filter接口实现类开发步骤

(1)创建一个Java类实现Filter接口
(2)重写Filter接口中doFilter方法
(3)web.xml将过滤器接口实现类注册到Http服务器