《Head First JSP Servlet》笔记

一、前言和体系结构

一、Web服务器做些什么?

Web服务器接收客户请求,然后返回一些结果。

二、Web客户做些什么?

Web客户(浏览器)允许用户请求服务器上的某个资源,并且向用户显示请求的结果。

三、HTML

当服务器响应客户端的请求时,一般会向浏览器发送一组用HTML编写的指令。HTML告诉浏览器怎样向用户显示内容(根据响应的内容类型)。

四、HTTP

HTTP是web上客户和服务器之间进行通信所用的协议。服务器使用HTTP响应向客户发送HTML。HTML是HTTP响应的一部分。

Http请求分析:http://www.cnblogs.com/RascallySnake/archive/2010/05/05/1728007.html

五、web服务器自己不做的两件的事情

1、动态内容

Web服务器只提供静态页面,但是有一个“辅助”应用(web容器及在其中运行的组件)可以生成非静态的即时页面,而且这个辅助应用能与web服务器通信。

2、在服务器上保存数据

即使用户通过表单提交了数据,web服务器也只是交由辅助应用处理,辅助应用可能会保存到数据库中。

二、高层概述

一、什么是容器?

Servlet没有Main方法。它们受控于另外一个java应用,这个java应用成为容器。Tomcat就是这样一个容器。如果Web服务器(如Apache)得到一个指向某个Servlet的请求,此时服务器不是把这个请求交给Servlet本身,而是交给部署该Servlet的容器。要由容器向Servlet提供HTTP请求和响应,而且要由容器调用Servlet的方法,如doPost或doGet。

二、容器能提供什么?

1.通信支持:负责与web服务器之间的通信。

2.生命周期管理:控制Servlet的生与死。

3.多线程支持:容器会自动地为它接受的每个Servlet请求创建一个新的java线程。

4.声明方式实现安全:利用容器,可以使用XML部署描述文件(DD)来配置安全性,而不必将其硬编码写到Servlet类代码中。

5.JSP支持:负责将JSP代码翻译成真正的java。

P.S:容器如何处理请求?P42

三、一个Servlet可以有3个名字

1.客户知道的URL名

2.部署人员知道的密码内部名

3.实际的完全限定名

建立Servlet名的映射,这样有助于改善应用的灵活性和安全性。

四、使用部署描述文件将URL映射到Servlet

可以使用两个XML元素把URL映射到Servlet,其中一个将客户知道的公共URL名映射到你自己的内部名,另一个元素把你自己的内部名映射到一个完全限定类名。

P48,76

代码示例:

<?xml version="1.0" encoding="UTF-8"?>

<web-app …>

  <servlet> 

       <!-- 元素1:内部名映射到完全限定名 -->

       <servlet-name>SuiBianQuDe Name</servlet-name>

         <!-- 这个名字是随便取的,内部名字,客户看不到 -->

       <servlet-class>com.example.MyServlet</servlet-class>

       <!-- 在这里放置类的完全限定名(但是不加.class扩展名) -->

  </servlet>

  <servlet-mapping>

       <!-- 元素2:内部名映射到公共URL名 -->

       <servlet-name>SuiBianQuDe Name</servlet-name>

       <!--  和上面的内部名字一致-->

       <url-pattern>/public.do</url-pattern>

       <!--  这个是客户看到(并使用)的Servlet名,这是一个虚构的名字,并不是具体的Servlet类的名字。--!>

       <!--  不要忘记最前面的一个斜杠,相当于请求地址为:http://hostname:8080/WebAppName/public.do ,不加斜杠则变成http://hostname:8080/WebAppNamepublic.do  -->

  </servlet-mapping>

</web-app>

五、Servlet & JSP世界中的MVC

控制器:从请求获得用户输入,并明确这些输入对模型有什么影响。告诉模型自行更新,并且让视图(jsp)能得到新的模型状态。

模型:包含具体的业务逻辑和状态。换句话说,模型知道用什么规则来得到和更新状态。系统中只有这部分与数据库通信。

视图:负责表示方面。它从控制器得到模型的状态。另外视图还有获得用户的输入,并提交给控制器

六、以下各个任务谁来负责?


任务


Web服务器


容器


Servlet


创建请求和响应对象


在开始线程之前创建


调用service方法


然后service方法再调用doGet或doPost


开始一个新线程来处理请求


开始一个Servlet线程


把响应对象转换为一个HTTp响应


由响应对象中的数据生成HTTP响应流


了解HTTP


用于与客户浏览器对话


把HTML增加到响应对象


提供给客户的动态内容


有响应对象的一个引用


容器把它交给Servlet


用它打印响应


在部署描述文件中查找URL


找到对应请求的适当Servlet


删除请求和响应对象


Servlet一旦结束就删除请求和响应对象


协调生成动态内容


知道如何转发到容器


知道要调用什么方法


管理生命周期


调用服务方法

七、Web服务器与web容器的区别,tomcat到底是web服务器还是web容器?

独立的web容器通常配置为与一个HTTP Web服务器(如Apache)协作。不过Tomcat容器本身就能作为一个基本的HTTP服务器。但是在HTTP服务器功能方面,Tomcat没有Apache那么健壮,所以最常见的非EJB Web应用通常会结合使用Apache和Tomcat,Apache作为HTTP Web服务器,Tomcat作为Web容器。

三、MVC实战

一、请求分派机制

RequestDispatcher rd = request.getRequestDispatcher(“request.jsp”);

Rd.forward(request,response);

getRequestDispatcher的参数,如果不到斜杠,则表示这个jsp和Servlet在同一路径下;如果有斜杠,则代表当前web应用的根路径下的一个jsp页面。”/”表示Web应用的根。

这个应该和getServletContext().getResourceAsStream(“”)类似。

四、请求和响应

一、Servlet GenericServlet HttpServlet之间的关系

Servlet是接口。GenericServlet是一个抽象类,实现了Servlet接口。HttpServlet也是一个抽象类,继承自GenericServlet抽象类。

P98

二、每个请求都在一个单独的线程中运行

在一个JVM中,任何Servlet类都不会有多个实例,只有一种特殊情况除外(称为SingleThreadModel)。容器运行多个线程来处理对一个Servlet的多个请求。对应每个客户请求,会生成一对新的请求和响应对象(HttpServletRequest和HttpServletResponse)。

三、ServletContext

n  每个web应用有一个ServletContext。

n  用于访问web应用参数(这些参数是在部署描述文件中配置的)。

n  用于得到服务器信息,包括容器名和容器版本,以及所支持的API的版本等。

Servlet对象封装了一组上下文初始化参数和一组属性。对于上下文初始化参数,只提供了getter方法,对于属性则提供了getter/setter方法。

四、ServletConfig对象

n  每个Servlet都有一个ServletConfig对象。

n  用于向Servlet传递部署时信息,而你不想把这些信息硬编码到Servlet中。

n  用于访问ServletContext。

n  参数在部署描述文件中配置。

ServletConfig对象只是封装一组string类型的键值对(Servlet初始化参数)。容器从DD读出Servlet初始化参数,并把这些参数封装为一个ServletConfig对象,然后把ServletConfig传递给Servlet的init方法。Servlet初始化参数只能读一次,就是在容器初始化Servlet的时候。所以ServletConfig只提供了getter方法。

P158 Servlet初始化参数和上下文初始化参数之间的区别。

五、ServletRequest接口和ServletResponse接口

HttpServletRequest接口继承自ServletRequest接口。HttpServletResponse接口继承自ServletResponse接口。

HttpServletRequest接口和HttpServletResponse接口都是由容器(Tomcat)实现的。在调用Servlet的service方法时,容器会向该方法传递这两个接口的各自的实现类对象的引用。

六、HTTP的各个方法

GET

POST

HEAD

TRACE

PUT

DELETE

OPTIONS

CONNECT

七、GET和POST的区别

1.数据大小问题。GET方式对参数数据有限制,参数数据只能放在请求行的内容。POST方式则没有限制,参数放在消息体中。

2.安全性问题。使用GET方式时,请求参数会被浏览器放在实际URL的后面(用一个“?”分隔,参数之间以”&”分隔)。

3.书签问题。GET方式可以使最终用户对请求页面建立书签,而POST方式则不行。

4.幂等问题。GET请求是幂等的,只是要得到东西,不会修改服务器上的任何内容。POST是非幂等的,POST体中的提交数据可能用于修改服务器上的某些东西。

幂等:对于HTTP/servlet,这个词表示同一个请求可以做两次,而不会对服务器产生负面作用。并不是说同样的请求总会得到同样的响应,也不是说一个请求没有副作用。

八、除了参数,能从HttpServletRequest得到什么?

1.客户的平台和浏览器信息:String client = httpServletRequest.getHeader("User-Agent");

2.与请求相关的cookie:Cookie[] Cookies = httpServletRequest.getCookies();

3.与客户会话相关(Session):HttpSession session = httpServletRequest.getSession();

4.请求的HTTP方法:String method = httpServletRequest.getMethod();

5.请求的输入流:ServletInputStream inputStream = httpServletRequest.getInputStream();

httpServletRequest.getServerPort();服务器监听的端口

httpServletRequest.getLocalPort();服务器为每个线程找的一个不同的本地端口

httpServletRequest.getRemotePort();获取客户的端口

九、HttpServletResponse的常用方法

httpServletResponse.setContentType(String);

httpServletResponse.getWriter();处理文本数据。

httpServletResponse.getOutputStream();处理其他任何内容。

httpServletResponse.addHeader("key", "value");没有对应的key则新建,否则会覆盖现有的值

httpServletResponse.setHeader("key", "value");没有对应的key则新建,否则会增加另外一个值

十、在sendRedirect()中使用相对URLs

httpServletResponse.sendRedirect("http://www.google.com"); Servlet让浏览器重定向

可以使用相对URL作为sendRedirect()的参数,而不是指定完整的"http://www.... "。相对URL有两种:前面有斜线”/”和没有斜线。

假设客户原来键入的是:http://www.hehe.com/myApp/cool/bar.do

当请求到达名为“bar.do”的Servlet时,这个Servlet会基于一个相对URL来调用sendRedirect(),这个相对URL没有用斜线开头: sendRedirect(“foo/stuff.html”);

容器会新建一个URL:http://www.hehe.com/myApp/cool/ foo/stuff.html

如果sendRedirect()的参数以一个斜线开头:sendRedirect(“/foo/stuff.html”);

则容器会新建一个URL:http://www.hehe.com/ foo/stuff.html

这里的”/”代表web容器的根。

P136

十一、请求分派(转发)和重定向的区别

RequestDispatcher rd = httpServletRequest.getRequestDispatcher(“/request.jsp”);

Rd.forward(request,response);

httpServletResponse.sendRedirect(“/foo/stuff.html”);

1.请求分派中的”/”代表“web应用的根”。重定向中的”/”代表“web容器的根”。如果都不带”/”,则表示相对于当前的Servlet所在目录而言。

2.请求分派发生在服务器端,而重定向在客户端进行。请求分派把请求传递给服务器上的另一个组件。重定向只是告诉浏览器去访问另一个URL。

    请求数量   地址栏
转发    1       不变
重定向   2       变化

比如:添加、修改、删除成功后 要重定向到列表功能,这样在刷新页面时才不会出现“又做一次增、删、改”的操作。

五、属性和监听者

一、ServletContextListener

由于上下文参数只能是String。毕竟你不能将一个Dog对象硬塞到XML中。如果希望在ServletContext初始化的时候创建一个供各个Servlet共享的数据库连接对象怎么办呢?

javax.servlet.ServletContextListener这个接口的实现类的对象能监听ServletContext一生中的两个关键事件,初始化和撤销。

适合如下需求场景:希望在ServletContext初始化的时候使用初始化参查找名建立一个数据库连接。把数据库连接存储为一个属性,使得web应用的各部分都能访问。当ServletContext撤销的时候关闭数据库连接。

其他监听者以及应用场景。P182

二、到底什么是属性?

属性就是一个对象,可能设置到另外3个Servlet API对象中的某一个,包括ServletContext、HttpServletRequest或者HttpSession。可以把它简单地认为是一个映射实例对象中的名/值对(名是一个String,值是一个Object)。

三、属性和参数的区别

P186

四、三个作用域:上下文、请求和会话

P187

五、上下文作用域不是线程安全的

P192

解决方案:对ServletContext对象枷锁P197

会话作用域也不是线程安全的

P199

解决方案:对HttpSession对象枷锁P200

实现SingleThreadModel的两种方案:实例池策略和排队策略P201

推荐方案和理由 P202

只有请求属性和局部变量是线程安全的!


变量类型


是否线程安全


上下文作用域属性



会话作用域属性



请求作用域属性



Servlet中的实例变量


否(除非实现了STM)


Servlet中的静态变量


否(实现了STM也是非线程安全的)


service方法中的局部变量


六、会话管理

一、在响应中发送一个会话cookie与从请求中得到会话id的代码一样

HttpSession session = request.getSession();

二、getSession(boolean)与getSession()的区别

P235

二、客户禁用Cookie,从而导致客户和服务器无法传递sessionid的处理办法

P237

URL重写:httpServletResponse.encodeUrl(“/user.do”)

使用sendRedirect()的URL重写:httpServletResponse.encodeRedirectURL(“/user.do”)

三、HttpSession的生命周期事件

P255

四、会话迁移

P257

七、使用JSP

一、

<% %> scriptlet,这里面声明的变量都是局部变量。

<%@ %>指令,<%@ page import=”com.model.*,java.util.*” %> 这是带有import属性的page指令。

<%= expression%>表达式,不要在表达式后面加上分号。等价于<% out.print(expression) %>

<%! %> JSP声明,可以声明变量和方法。

<%-- --%>JSP注释

<jsp:useBean ... /> 动作

二、JSP的生命周期

P306

三、初始化JSp

配置jsp的初始化参数,覆盖jspInit方法。       P310

四、pageContext

除了标准的Servlet请求、会话和上下文作用域外,jsp还增加了第四个作用域,即页面作用域,可以从pageContext对象得到。pageContext封装了其他隐式对象。P298、311-313

五、在DD中使用<scripting-invalid>标记禁止在页面中使用scriptlet,使用<el-ignored>元素禁用EL。

P321-322

时间: 2024-08-24 11:37:29

《Head First JSP Servlet》笔记的相关文章

SQL 笔记 By 华仔

-------------------------------------读书笔记------------------------------- 笔记1-徐 最常用的几种备份方法 笔记2-徐 收缩数据库的大小的方法 笔记3-徐 设置数据库自动增长注意要点 笔记4-徐 模仿灾难发生时还原adventurework数据库 示例 stopat 笔记5-徐 检查日志文件不能被截断的原因 笔记6-徐 检测孤立用户并恢复孤立用户到新的服务器 解决数据库镜像孤立用户问题 笔记7-徐 SQLSERVER日志记录

SQL笔记---多表左联

这是实际场景当中的一个例子,拿出来分析总结思路. -- SQL 查询 --SELECT  orderQuery.Rk_SkuCode ,        orderQuery.SkuName,        SUM(ISNULL(orderQuery.OrderTotal, 0))        - SUM(ISNULL(removeQuery.RemoveTotal, 0))        - SUM(ISNULL(pickQuery.PickTotal, 0))        - SUM(IS

SQL笔记---分页

随用随想,随用随记. 通过实际应用掌握SQL语句. 一. SQL分页 1. 第一种方法:利用ID大于多少进行筛选 SELECT TOP 20        *FROM    dbo.WMS_StockWHERE   ( Rk_SkuCode > ( SELECT MAX(Rk_SkuCode)                         FROM   ( SELECT TOP 40                                            *           

《HeadFirst SQL》笔记

规范化 0 约束 1 原子性 2 第一范式 1NF 3 数据模式 4 依赖 5 联接查询 6 交叉联接(AKA 笛卡尔联接,叉积) 7 内联接 8 子查询 9 外联接 10 自联接 11 集合 12 事务 13 ACID 14 管理事务 15 常用语句 16 注意 17 规范化 约束 NOT NULL UNIQUE PRIMARY KEY DEFAULT FOREIGN KEY:引用父表的某个唯一值引用完整性:插入外键列的值必须已经存在于父表的来源列中 --创建外键 create table i

SQL笔记1:SELECT及SELECT高级应用

T-SQL笔记1:SELECT及SELECT高级应用 本章摘要 1:安装AdventureWorks 2:基本运算符和表达式 3:between 4:like 5:escape 6:TOP 7:GROUP BY 7.1:GROUP BY ALL 7.2:HAVING 8:SELECT字句技术 8.1:使用DISTINCT消除重复值 8.2:返回拼接的结果 8.3使用INTO字句 9:子查询 9.1:子查询类型 9.2:代替表达式的查询 9.3:多层嵌套 10:比较使用 EXISTS 和 IN 的

金典 SQL笔记(6)

page223-索引 --利用SQL 语句创建索引 --CREATE INDEX 索引名称on 表名(字段 ,字段, 字段字段n) --索引名称必须为唯一的,字段 ,字段, 同意一个到多个 --范例为T_person 表中给FName创建索引索引名为 idx_person_name CREATE INDEX idx_person_name ON T_Person (FName) --删除索引 --drop index 表名索引名 DROP INDEX T_person.idx_person_na

Mybatis 项目开发实际常用SQL笔记总结

parameterType 和 resultType parameterType:单个参数用String,多个参数用map resultType:   可以是 Integer.String.Object    <select id="countGroupMasterByUid" parameterType="String" resultType="Integer">      SELECT              COUNT(id)

sql笔记/分页存储过程

[email protected]c#中进行++操作可以是整数或小数,sql中只能对整数进行++操作.char类型 适合存储长度波动较小不回收效率高varchar 类型 适合存储长度波动较大可以回收nchar代表unicode 存储内容包括汉字时候考虑加n SQL语句特点1不区分大小写2没有双引号所有字符串都包含在单引号3没有逻辑相等,逻辑相等和赋值一样都是用=4没有bool值得概念,但是在视图中可以输入true/false5也有关系运算符.6也有逻辑运算符 &&-- and || --o

sql笔记

1. 看下面sql,重点有两个,一个是distinct  ,一个是树形结构查询 select DISTINCT t.unit_code from t_unit_relation t where t.corp_tn='jiaozhougongan' start with t.unit_code='0001' connect by prior t.unit_code = t.unit_upcode 分析: ① distinct:去重复值 ② 树形结构查询,这个博客:http://www.cnblog

HeadFirst SQL 读书摘要

数据库都是用 圆柱形表示的. 数据库中包含表 表中包含行和列 行又叫记录record,  列又叫 字段field 创建数据库 create database mypipe_l; 选择数据库 use mypipe_l; 创建表 create table doughnut( name VARCHAR(10), type VARCHAR(6) ); 查看表 desc doughnut; 删除表 drop table doughnut; 插入数据 insert into doughnut (name,