Servlet的学习笔记

Servlet



1.servlet的概念和运行流程

1.1 创建servlet

1.实现javax.servlet.Servlet接口
2.继承javax.servet.GenericServlet类 (适配器模式)
3.继承javax.servlet.http.HttpServlet类 (模板方法设计模式)(开发中常用方式)

继承关系:Servlet --> GenericServlet --> HttpServlet

注:在之后的笔记中,servlet均默认由继承HttpServlet进行创建

1.2 使用

1.创建普通的java类并继承HttpServlet
2.复写service方法
3.在service方法中书写逻辑代码
4.在webRoot下的WEB-INF文件夹下的web.xml中配置servlet

  • 运行流程
    浏览器发送请求到服务器,服务器根据请求URL地址中的URI信息在webapps目录下找到对应的项目文件夹,然后在web.xml中检索对应的servlet,找到后调用并执行Servlet

1.3 URL组成

服务器地址:端口号/项目名称/对应servlet的url-pattern

  • 亦可在项目的properties —— web project settings —— context root的属性中设置项目的别名
    注意:servlet类不能在web.xml中配置别名同时使用@webservlet注解


2.servlet的生命周期

完整生命周期是从第一次调用到服务器关闭
如果servlet在web.xml中配置了load-on-startup,生命周期为服务器启动到服务器关闭

2.1 具体方法

init()方法
初始化方法,在servlet第一次加载进存储时被调用

service()方法
真正处理请求的方法

destroy()方法
在servlet被销毁时执行,如servlet被卸载或服务器关闭时


3. service()和doGet()和doPost()方法的区别

3.1 HTTP协议中get和post请求方式的区别

  • get请求方式
    请求数据会以?的形式隔开拼接在请求头中,不安全,没有请求实体部分。HTTP协议虽然没有规定请求数据的大小,但是浏览器对URL的长度是有限制的,所以get请求不能携带大量的数据
  • post请求方式
    请求数据在请求实体中进行发送,在URL中看不到具体的请求数据安全。适合数据量大的数据发送

3.2 service()方法

可以处理get/post方式的请求,如果servlet中有service方法,会优先调用service方法对请求进行处理
在继承HttpServlet后,如果复写的service调用了父类的service()方法super.service(arg0,arg1),则在service方法处理完后,会再次根据请求方式相应doGet方法或doPost方法。所以,一般情况下,我们是不在复写的service()方法中调用父类的service()方法,避免出现405错误

3.3 doGet()方法

处理get方式的请求

3.4 doPost()方法

处理post方式的请求



4.Servlet常见报错总结

404错误

原因一:在请求地址中的servlet的别名书写错误
原因二:虚拟项目名称书写错误

500错误

原因一:web.xml中servlet类的全限定路径拼写错误
原因二:service方法体中的代码执行错误

405错误

原因:请求方式和servlet中的方法不匹配所造成的
解决:尽量使用service方法进行请求处理,并且不要在service方法中调用父类service方法



5.request&response

5.1 request

5.1.1 概述

服务器使用对象来存储请求,每接受一个请求,就创建一个对象专门的存储此次请求的请求数据

服务器接收到浏览器的请求后,会创建一个Request对象,对象中存储了此次请求相关的请求数据。服务器在调用Servlet时会将创建的Request对象作为实参传递给Servlet的方法,比如:service方法

5.1.2 作用

request对象中封存了当前请求的所有请求信息
注意:request对象由tomcat服务器创建,并作为实参传递给处理请求的servlet的service方法

5.1.3 使用
  • 获取请求头数据

获取请求方式 String method = req.getMethod();
获取请求URL StringBuffer url = req.getReqestURL();
获取URI String uri = req.getRequestURI();
获取协议 String h = req.geSchme();

  • 获取请求行数据
    获取指定的请求行信息 String value = req.getHeader("keyName")
    获取所有的请求行的键的枚举 Enumeration e = req.getHeaderNames();

  • 获取用户数据
    获取指定的用户数据(不能用来获取同健不同值情况)String value = req.getParameter("keyName")
    获取同键不同值的请求数据数组String[] values = req.getParameterValues("keyName")
    获取所有用户请求数据的枚举集合req.getParameterNames

注意:如果要获取的请求数据不存在,不会报错,只会返回null

5.1.4 请求乱码问题解决
  • 使用String进行数据重新编码(适用于get和post)
    uname = new String(uname.getBytes("iso8859-1"),"utf-8")
  • 使用公共配置
    get方式: 步骤一:req.setCharacterEncoding("utf-8") 步骤二:在tomcat的目录下的conf目录中修改server.xml文件,然后在Connector标签中增加属性useBodyEncoding="true"
    post方式:
    req.setCharacterEncoding("utf-8")
5.1.5 请求转发
  • 作用:实现多个servlet联动操作处理请求,避免代码冗余,提高内聚性
  • 使用:req.getRequestDispatcher("转发目标地址").forward(req,resp)
    地址书写相对路径即可,即servlet的别名
  • 特点:一次请求,浏览器地址信息栏信息不改变
  • 注意:请求转发后直接return即可,之后业务由转发servlet进行处理
5.1.6 request对象作用域
  • 使用:
    request.setAttribute(object name,Object value);
    request.getAttribute(Object obj);
  • 作用:解决了一次请求内的不同Servlet的数据共享问题
  • 作用域:基于请求转发,一次请求中的所有Servlet共享
  • 注意:使用Request对象进行数据流转,数据只在一次请求内有效
  • 特点: 服务器创建;每次请求都会创建;生命周期一次请求
5.1.7 重定向
  • 需求:
    servlet无法处理当前请求
    请求转发造成表单数据(请求实体内容)重复提交
  • 使用:resp.sendRedirect(String uri)
  • 特点:
    两次请求,两个request对象
    浏览器地址栏信息改变
  • 时机:
    如果请求中有表单数据,而数据又比较重要,不能重复提交,建议使用重定向
    如果请求被Servlet接受后,无法进行处理,建议使用重定向定位到可以处理的资源
  • 改进:可以用session技术完成两次请求间无记忆的特点

5.2 response

5.2.1 作用

用来响应数据到浏览器的一个对象

5.2.2 使用
  • 设置响应头
    在响应头中添加响应信息,但是会同键覆盖resp.setHeader("key","value")
    在响应头中添加响应信息,但是不会覆盖resp.addHeader("key","value")
  • 设置响应编码格式
    resp.setHeader("content-type","text/html;charset=utf-8")
    resp.setContentType("text/html;charset=utf-8")
  • 设置响应状态码
    resp.sendError(int num,String msg)
  • 设置响应实体
    响应具体的数据给浏览器resp.getWriter().write("String str")

5.2.3 service请求处理代码流程

  • 设置响应编码格式
  • 获取请求数据
  • 处理请求数据(MVC思想)
    逻辑代码
    数据库操作
  • 响应处理结果


6.Servlet流程总结

1> 浏览器发起请求到服务器(请求)

2> 服务器接收浏览器的请求,进行解析,创建request对象存储请求数据

3> 服务器调用对应的servlet进行请求处理,并将request对象作为实参传递给servlet的方法

4> servlet的方法执行进行请求处理

设置请求编码格式
设置响应编码格式
获取请求信息
处理请求信息
  • 创建业务层对象
  • 调用业务层对象的方法
相应处理结果


7.Cookie

7.1 作用

解决了发送的不同请求的数据共享问题


7.2 使用


7.2.1 Cookie的创建和存储
7.2.1.1 创建Cookie对象

Cookie c = new Cookie("String name", "String value")

7.2.1.2 设置Cookie(可选)
  • 设置有效期
    c2.setMaxAge(int seconds)
  • 设置有效路径
    c2.setPath("uri")
7.2.1.3 添加Cookie信息给客户端

resp.addCookie(c)


7.2.2 Cookie的获取
7.2.2.1 获取Cookie信息数组

Cookie[] cks = req.getCookies()

7.2.2.2 遍历数组获取Cookie信息
if(cks!=null) {
    for(Cookie c:cks) {
        String name = c.getName();
        String value = c.getValue();
    	System.out.println(name+":"+value);
    }
}

7.3 特点

浏览器端的数据存储技术
存储的数据声明在服务器端
默认Cookie信息存储好之后,每次请求都会附带,除非设置有效路径

  • 注意 :一个Cookie对象存储一条数据,多条数据可以通过创建多个Cookie对象进行存储

7.4 分类

临时存储:存储在浏览器的运行内存中,浏览器关闭即失效
定时存储:设置了Cookie的有效期,存储在客户端的硬盘中,在有效期内符合路径要求的请求都会附带该信息



8.Session


8.1 概述

8.1.1 需求

一个用户的不同请求处理的数据共享的场景

8.1.2 解决

使用session技术

8.1.3 原理

用户第一次访问服务器,服务器会创建一个session对象给此用户,并将该session对象的JSEESSIONID使用Cookie技术存储到浏览器中,保证用户的其它请求能够获取到同一个session对象,也就保证了不同请求能够获取到共享的数据

8.1.4 特点
  • 存储在服务器
  • 服务器进行创建
  • 依赖Cookie技术
  • 有效期为一次会话
  • 默认存储时间是30分钟
8.1.5 作用域
  • 一次会话。服务器会将JSESSIONID作为一个单独Cookie附加到response上返回给客户端(session主要基于cookie技术,虽然也可通过URL重写),而这个Cookie会默认存放在浏览器内存中而不是硬盘上,所以在关闭浏览器后,该Cookie对象也会被清除,浏览器从而不持有该JSESSIONID,此时虽然服务器端可能持有JSESSIONID的对应对象,但在应用方面基本等同于失效,因为浏览器失去了对象的“指针”
  • 在JSESSIONID和session对象不失效的情况下为整个项目内

8.2 使用

8.2.1 创建session对象/获取session对象

HttpSession hs = req.getSession();

  • 如果请求中拥有session的标识符也就是JSESSIONID,则返回其对应的session对象
  • 如果请求中没有session的标识符也就是JSESSIONID,则创建新的session对象,并将其JSESSIONID作为cookie数据存储到浏览器内存中
  • 如果session对象失效了,也会重新创建一个session对象,并将其JSESSIONID存储在浏览器内存中
8.2.2 设置session存储时间

hs.setMaxInactival(int seconds)
即在指定的时间内session对象没有被使用则销毁。如果使用了则重新计时

8.2.3 设置session强制失效

hs.invalidate()

8.2.4 存储和获取数据
  • 存储:hs.setAttribute(String name,Object value)
  • 获取:hs.getAttribute(String name) 返回数据类型为Object
  • 注意: 存储的动作和取出的动作发生在不同的请求中,但是存储要先于取出执行
8.2.5 使用时机

一般的,用户在登录web项目时会将用户的个人信息存储到session中,供用户的其它请求使用

8.2.6 session失效处理

将用户请求中的JSESSIONID和后台获取到的SESSIONID进行比对,如果一致,则session没有失效,如果不一致则证明session失效。失效后重定向到登录页面,让用户重新登录

8.2.7 JSESSIONID存储
  • JSESSIONID存储在了Cookie的临时存储空间中,浏览器关闭即失效。
  • 原因:服务器会将JSESSIONID作为一个单独Cookie附加到response上返回给客户端(session主要基于cookie技术,虽然也可通过URL重写),而这个Cookie会默认存放在浏览器内存中而不是硬盘上,所以在关闭浏览器后,该Cookie对象也会被清除,浏览器从而不持有该JSESSIONID,此时虽然服务器端可能持有JSESSIONID的对应对象,但在应用方面基本等同于失效,因为浏览器失去了对象的“指针”

8.3 总结

session解决了一个用户的不同请求的数据共享问题,只要在JSESSIONID不失效和session对象不失效的情况下,用户的任意请求在处理时都能获取到同一个session对象



9.ServletContext


9.1 概述

9.1.1 需求

Request解决了一次请求内的数据共享问题,session解决了用户不同请求的数据共享问题,而ServletContext对象则是要解决不同用户之间的数据共享问题

9.1.2 特点
  • 服务器进行创建
  • 用户共享
  • 一个项目只有一个
9.1.3 生命周期

服务器启动到关闭

9.1.4 作用域

项目内所有servlet


9.2 使用


9.2.1 获取ServletContext对象
  • 第一种方式
    ServletContext sc = this.getServletContext()
  • 第二种方式
    ServletContext sc2 = this.getServletConfig().getServletContext()
  • 第三种方式
    ServletContext sc3 = req.getSession().getServletContext()

9.2.2 使用ServletContext对象完成数据共享
  • 数据存储
    sc.setAttribute(String name, Object value)
  • 数据获取
    sc.getAttribute(String name) 返回的是Object类型
  • 注意
    不同的用户可以对ServletContext对象进行数据的存取
    获取的数据不存在则返回null,不会报错

9.2.3 获取项目中web.xml文件中的全局配置数据
9.2.2.1 web.xml配置方式
<context-param>
    <param-name>name</param-name>
    <param-value>zhangsan</param-value>
 </context-param>

注意:一组 < context-param >标签只能存储一组键值对信息,多组数据可以通过声明多个< context-param >来进行存储

9.2.2.2 获取方法
  • sc.getInitParameter("String name")
    根据键的名字返回web.xml中配置的全局数据的值,返回String类型
    如果数据不存在则返回null
  • sc.getInitParameter()
    返回键名的枚举
9.2.2.3 作用

将静态数据和代码进行解耦


9.2.4 获取项目webroot下的资源的绝对路径

String path = sc.getRealPath(String path)
获取的路径为项目根目录,path参数为项目根目录中的路径,即从项目根目录下开始写则可,无需书写项目名


9.2.5 获取项目webroot下的资源的流对象

InputStream is = sc.getResourceAsStream(String path)
获取的路径为项目根目录,path参数为项目根目录中的路径
注意:此种方式只能项目根目录下的资源流对象,class文件的流对象需要使用类加载器



10.ServletConfig


10.1 作用

ServletConfig对象是Servlet的专属配置对象,每个Servlet都单独拥有一个ServletConfig对象,用来获取web.xml中的配置信息


10.2 使用

10.2.1 web.xml配置方式
  <servlet>
  	<servlet-name>ServletConfigServlet</servlet-name>
  	<servlet-class>servlet.ServletConfigServlet</servlet-class>
  	<init-param>
  		<param-name>config</param-name>
  		<param-value>utf-8</param-value>
  	</init-param>
  </servlet>
10.2.2 获取ServletConfig对象

ServletConfig sc = this.getServletConfig()

10.2.3 获取web.xml中的配置数据

sc.getInitParameter(String name)



11.web.xml文件


11.1 作用

  • 存储项目相关的配置信息,保护servlet
  • 解耦一些数据对程序的依赖

11.2 两个web.xml

11.2.1 使用位置
  • 每个Web项目中
  • Tomcat服务器中(在服务器目录conf目录中)
11.2.2 区别
  • Web项目下的web.xml文件为局部配置,针对本项目的位置
  • Tomcat下的web.xml文件为全局配置,配置公共信息

11.3 内容(核心组件)

11.3.1 组件列表
  • 全局上下文配置(全局配置参数)
  • servlet配置
  • 过滤器配置
  • 监听器配置
11.3.2 加载顺序

Web容器会按ServletContext -> context-param -> listener -> filter -> servlet这个顺序加载组件,这些元素可配置在web.xml文件中的任意位置

11.3.3 加载时机

服务器启动时



11.server.xml文件


11.1 概述

11.1.1 问题

浏览器发起请求后,服务器根据请求在webapps目录下调用对应的servlet进行请求处理,那么为什么是webapps目录难道不能是其它的目录吗?

11.1.2 解决

了解server.xml文件的配置信息


11.2 核心组件

<Server>
    <Service>
        <!-- Conector标签可以有多个 -->
        <Connector>
        </Connector>
        <!-- 单个Service标签下只能有一个Engine标签 -->
        <Engine>
            <Host>
                <Context/>
            </Host>
        </Engine>
    </Service>
</Server>
  • 热部署
    <Context path="/项目名" reloadable="true" doBase="项目直至webapps下的绝对路径">
    此种部署方式下,如果单个项目的绝对路径下文件被删除,则此项目会使服务器启动失败,导致服务器上的其他独立项目也不会启动


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值