Head First JSP---随笔二

11 篇文章 0 订阅
11 篇文章 0 订阅

作为Servlet

Servlet的存在就是为客户服务


Servlet 技术模型

1.1 对于每一种HTTP方法(如get、post、head等),描述该方法的用途,以及该HTTP方法协议的技术特性,并列出客户(通常是一个Web浏览器)会因为哪些原因使用这种方法,明确对应这种HTTP方法的HttpServlet方法

1.2 使用HttpServletRequest接口,编写代码从请求获取 HTML 表单参数,获取HTTP 请求首部信息,或者从请求获取cookie

1.3 使用HttpServletResponse接口,编写代码设置 HTTP 响应首部,设置响应内容类型,为响应获得一个文本流,为响应获得一个二进制流,把一个HTTP 请求重定向到另一个URL,或者向响应 增加cookie

1.4 描述serlvet生命周期的作用和事件序列

  • serlvet类加载
  • servlet实例化
  • 调用init()方法
  • 调用service方法
  • 调用destroy()方法

Serlvet 的生命周期

这里写图片描述


Servlet 继承树

这里写图片描述


Servlet 生命周期的三大重要时刻

方法何时调用作用是否覆盖
init()serlvet实例创建后,并在serlvet能为客户请求提供服务前,容器要对serlvet调用init()使你在serlvet处理客户请求之前有机会对其初始化有可能
service()第一个客户请求到来是,容器会开始一个新线程,或者从线程池分配一个线程,并调用servlet的service方法这个方法会查看请求,确定HTTP方法(get、post等),并在servlet上调用对应的方法不太可能
doGet()或doPost()service()方法根据请求的HTTP方法(get、post等)来调用doGet()或doPost写自己的业务逻辑至少覆盖其中之一

注意:是开启一个service()线程,也就是容器为每一个请求都开启一个独立的线程


构造函数不足以初始化servlet

在调用构造函数和init()方法之间,servlet处在一种薛定谔servlet状态。如果过早的初始化代码会导致失败,所以需要init()方法。


从servlet对象到一个真正的servlet

拥有2样东西

  1. ServletConfig对象
    1. 每个Servlet都有一个ServletConfig对象
    2. 用于向Servlet传递部署时信息(例如数据库名),而你不想把这个信息硬编码写到servlet中(servlet初始化参数)
    3. 用于访问ServletContext
    4. 参数在部署描述文件中配置(DD)
  2. ServletContext
    1. 每个Web应用有一个ServletContext(应该叫做AppContext才对)
    2. 用于访问Web应用参数(DD中配置)
    3. 相当于一种应用公告栏,可以在这里放置消息(称为属性),应用的其他部分可以访问这些消息
    4. 用于得到服务器信息,包括容器名和容器版本,以及所支持的API的版本等

请求的UML

这里写图片描述


响应的UML

这里写图片描述


谁来实现HttpServletRequest和HttpServletResponse接口?这些类在API中吗?

第一个答案是容器,第二个答案是“不”


Http方法

方法说明
GET要求得到所请求URL上的一个东西(资源/文件)
POST要求服务器接收附加到请求的体信息,并提供所请求URL上的一个东西
HEAD只要求得到GET返回结果的首部部分
TRACE要求请求消息回送,这样客户能看到另一端上接收了什么,以便测试或排错
PUT指出要把所包含信息(体)放在请求的URL上
DELETE指出删除所请求URL上的一个东西(资源/文件)
OPTIONS要求得到一个HTTP方法列表,所请求URL上的东西可以对这些HTTP方法做出响应
CONNECT要求连接以便建立隧道


幂等

对于HTTP/servlet来说“幂等”这个这个词表示同一个请求可以做出两次,而不会对服务器产生负面影响(所谓的影响可以是更改数据库中的数据)。

这里指出POST是“非幂等”的,并且可以是GET也成为“非幂等”


如何使浏览器发送POST或者GET

很多种方法,主要方法有:

  • form表单中的method属性设置为相应的方法
  • ajax发送相应方法的请求
  • a标签的href默认为get方法

getServerPort()、getLocalPort()和getRemotePort()区别

getServerPort()getLocalPort()getRemotePort()
获得服务器端口获得service()线程的本地端口获得客户端端口


复习:servlet生命周期和API

  1. 容器要加载类、调用servlet的无参构造函数、并调用servlet的init()方法,从而初始化servlet
  2. init()方法(开发人员可以覆盖)在servlet一生中只调用一次,往往在servlet为客户请求提供服务之前调用。
  3. init()方法使servlet可以访问ServletConfig和ServletContext对象,servlet需要从这些对象的恩爱到有关servlet配置和Web应用的信息。
  4. 容器通过调用servlet的destroy()方法来结束servlet的生命
  5. servlet一生的大多数时间都是在为某个客户请求运行service()方法。
  6. 对servlet的每个请求都在一个单独的线程中运行,任何特定servlet类都只有一个实例
  7. 你的servlet一般都会扩展javax.servlet.http.HttpServlet,并由此继承service()方法的一个实现,它取一个HttpServletRequest和一个HttpServletResponse作为参数
  8. HttpServlet扩展了javax.servlet.GenericServlet,这是一个抽象类,实现了大多数基本servlet方法。
  9. GenericServlet实现了Servlet接口。
  10. Servlet相关的类都在以下两个包中 : javax.servlet 或 javax.servlet.http
  11. 可以覆盖init()方法,而且必须覆盖一个服务方法

复习:HTTP和HttpServletRequest

  1. HttpServlet的doGet()和doPost()方法去一个HttpServletRequest和一个HttpServletResponse作为参数
  2. service()方法根据HTTP请求的HTTP方法(get、post等)来确定运行doGet()还是doPost()。
  3. POST请求由一个;GET请求没有,不过GET请求可以把请求参数追加到请求URL的后面(又是称为“查询串”)。
  4. GET请求本质上讲(根据HTTP规范)是幂等的。它们应当能多次运行而不会对服务器产生任何副作用。GET请求不应该修改服务器上的任何东西。但是你也可以写一个非幂等的doGet()方法
  5. POST本质上讲不是幂等的,所以要由你来适当地设计和编写代码,如果客户错误地把一个请求发送了两次,你也能正确地加以处理。
  6. 如果HTML表单没有明确的指出“method=”POST””,请求就会作为一个GET请求发送,而不是POST请求。如果你的servlet中没有doGet(),这个请求就会失败。
  7. 可以用getParameter(paramname)方法从请求得到参数,返回值是String。
  8. 如果对应一个给定的参数名有多个参数值,要使用getParameterValues(paramname)方法来返回一个String数组。
  9. 从请求对象还可以得到其他东西,包括首部、cookie、会话、查询串和输入流

HttpServletResponse响应的输出流

有两种:

  1. PrintWriter对象,用于输出字符
  2. OutputStream对象,用于输出字节

内容类型

//响应一个应用或者jar包给客户
response.setContentType("application/jar");

设置响应首部和增加 响应首部

setHeader(String,String) 会覆盖现有值
setIntHeader(String,Integer) 会覆盖现有值
addHeader(String,String) 会增加另外一个值


重定向与请求分派

重定向response.sendRedirect(String url),是返回给客户端,响应状态码会是301

请求分派request.getRequestDispatcher(String url).forward(request,response),这里的url是发送给服务器,而不是客户端,响应状态码200

表示为表格形式:

方法返回对象状态码
重定向客户端301
请求分派服务器200


复习:HttpServletResponse

  1. 使用响应向客户发回数据
  2. 对响应对象(HttpServletResponse)调用的最常用的方法是setContentType()和getWriter()。
  3. 要当心——很多开发人员都认为应该是getPrintWriter(),但实际上得到书写器的方法是getWriter()
  4. 利用getWriter()方法可以完成I/O,向流写入HTML(或其他内容)
  5. 还可以使用响应来设置首部、发送错误、以及增加cookie
  6. 在实际中,可能会使用JSP发送大多数HTML响应,但仍有可能使用一个响应流向客户发送二进制数据
  7. 要得到二进制流,需要在响应上调用getOutputStream()。
  8. setContentType()方法告诉浏览器如何处理随响应到来的数据。常见的内容类型为”text/html”、”application/pdf”和”image/jpeg”。
  9. 不用记住内容类型。
  10. 可以使用addHeader()或setHeader()设置响应首部。二者区别是这个首部是否已经是响应的一部分。如果是,setHeader()会替换原来的值,而addHeader()会向现有的响应增加另一个值。
  11. 如果你不想对一个请求做出响应,可以把请求重定向到另一个URL。浏览器会负责把新请求发送到你提供的URL。
  12. 要重定向一个请求,需要在响应上调用sendRedirect(String URL)。
  13. 不能再响应已经提交之后才调用sendRedirect()。
  14. 请求重定向与请求分派完全是两码事。请求分派在服务端发生,而重定向在客户端进行。请求分派把请求传递给服务器上的另一个组件(通常在同一个Web应用中)。请求重定向只是告诉浏览器去访问另一个URL。

本章完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值