【Hibernate学习笔记】第二章节:JSP/Servlet及相关技术详解

JSP(Java Servr Page)和Servlet是Java EE规范的两个基本成员,他们是Java Web开发的重点知识,也是Java EE开发的基础知识。JSP和Servlet的本质是一样的,因此JSP最终必须编译成Servlet才能运行,或者说JSP只是生成Servlet的“草稿”文件。JSP的特点是在HTML页面中嵌入了Java代码片段,从而可以动态的提供页面内容。
 1.Web应用和web.xml文件
  JSP、Servlet、Listener和Filter等都必须运行在Web应用中。
  1.1. 构建Web应用
   下面我们将‘徒手’建立一个Web应用:
   (1):建立webDemo文件夹;
   (2):在webDemo文件夹中建立WEB-INF文件夹;
   (3):在其他任何一个Web应用下的WEB-INF文件夹中将web.xml文件复制到第二步中我们建立的WEB-INF文件夹下;
   (4):修改复制到的web.xml文件,将该文件修改成只有一个根元素的XML文件,修改后的文件如下所示:
    -=程序清单:wenDemo\WEB-INF\web.xml=-
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee"
     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd
     version="3.0">
    </web-app>
   (5):在WEB-INF路径下,新建两个文件夹:classes和lib,这两个文件夹的作用完全一样:都是保存Web应用所需要的Java类文件,区别是classes保存单个*.class文件,而lib保存打包后的JAR文件。
   经过以上五个步骤已经建立了一个空的Web应用。将该Web应用复制到Tomcat的webapps路径下,该Web应用将可以自动部署在Tomcat中。
   通常我们只需要将JSP放在Web应用的根目录下,然后就可以通过浏览器来访问这些页面了。
   根据以上的介绍,我们可以发现Web应用应该具有以下的文件结构:
   <webDemo>————这是Web应用的名称(名称可以改变)
   |—WEB-INF
   |       |—classes
   |       |—lib
   |       |—web.xml
   |—<a.jsp... ...>————这里存放多个JSP页面(名称可以改变)
  1.2. 配置描述符web.xml
   web.xml文件对于Web应用十分重要,而且必须放置在WEB-INF文件夹下。
   对于Servlet3.0而言,web.xml文件不再是必须的,但是通常还是建议保留该配置文件。
   对于Java Web应用而言,WEB-INF是一个特殊的文件夹,Web容器会包含该文件夹下的内容,但是客户端浏览器不会访问WEB-INF文件夹下的任何内容。
   Servlet2.5规范之前,Java Web应用的绝大部分组件都是通过web.xml文件来配置管理,Servlet3.0规范可以通过Annotation来配置管理Web组件,因此web.xml文件可以变得更加简洁。
   web.xml文件的根元素是<web-app.../>元素。
   在Servlet3.0规范中,新添加了metadata-complete属性,该属性接受true和false两个属性值。为true时,应用不会加载Annotation。
   在web.xml文件中,使用welcome-file-list元素及其子元素welcome-file,来配置一个首页。
   每个Web容器都会提供一个系统的web.xml文件,用于描述所有Web应用共同的配置属性。Tomcat的系统web.xml放置在conf路径下。
 2.JSP的基本原理
  JSP的本质是Servlet(一个特殊的Java类),当用户向指定Servlet发送请求时,Servlet利用输出流动态生成HTML页面,包括每一个静态的HTML标签和所有的HTML页面中出现的内容。
  JSP页面的内容由以下两部分组成:
  >> 静态部分:静态HTML页面;
  >> 动态部分:受Java程序控制的内容,这部分内容由Java程序来动态生成。(Java脚本,代码放置于<%...%>之间)
  对于Tomcat而言,JSP生成的Servlet(*_jsp.java类文件)放在work路径下的Web应用下,该Java类主要包含如下三个方法:
  >> init():初始化JSP/Servlet的方法;
  >> destroy():销毁JSP/Servlet之前的方法;
  >> service():对于用户的请求生成响应的方法。
  JSP页面中的所有内容都由*_jsp.java文件的页面输出流来生成。
  依据JSP页面的工作原理,可以得到以下四个结论:
  >> JSP文件必须在JSP服务器内运行;
  >> JSP文件必须被编译生成Servlet才能执行;
  >> 每个JSP页面的第一个访问者的访问速度很慢,因为必须等待JSP文件被编译成Servlet文件;
  >> JSP文件的访问者,无需安装任何客户端,甚至不需要可以运行Java的运行环境,因为JSP页面输送给客户端的是标准HTML页面。
 3.JSP注释
  JSP注释的格式:<%-- 注释内容 --%>
  HTML注释的格式:<!-- 注释内容 -->
 4.JSP声明
  JSP声明用于声明变量和方法。在JSP声明中,似乎不需要定义类就可直接定义方法,方法似乎可以脱离类独立存在,实际上,JSP声明会转换成对应的Servlet的成员变量和成员方法,因此JSP声明依然复合Java语法。
  JSP声明的语法格式:<%! 声明部分 %>
 5.输出JSP表达式
  JSP提供了一种输出表达式值的简单方法,输出表达式值得语法格式:<%=表达式%>
 6.JSP脚本
  JSP脚本里面可以包含任何可执行的Java代码。通常来说,所有可执行的Java代码都可以通过JSP脚本嵌入到HTML页面里。
  JSP脚本里面不能定义方法。
 7.JSP的3个编译指令
  JSP的编译指令是通知JSP引擎的消息,他不直接生成输出。编译指令都有默认值,开发人员不需要为每个编译指令设置值。
  常见的编译指令有如下3个:
  >> page:针对当前页面的指令;
  >> include:用于指定包含另一个页面;
  >> taglib:用于定义和访问自定义标签。
  使用编译指令的语法格式:<%@ 编译指令名 属性名="属性值"... ...%>
  7.1. page指令
   page指令通常位于JSP页面的顶部,一个JSP页面可以使用多条page指令。
   page编译指令的语法格式如下:
   <%@ page
   [language="java"]                                       <%-- 声明当前JSP页面使用的脚本语言 --%>
   [extends="package.class"]                         <%-- 指定JSP页面编译后所产生的Java类所继承的父类,或所实现的接口 --%>
   [import="package.class | package.*,......"]  <%-- 导入包 --%>
   [session="true | false"]                                <%-- 用于设定JSP页面是否需要HTTP Session --%>
   [buffer="none | 8KB | size KB"]                   <%-- 指定输出缓冲区的大小 --%>
   [autoFlush="true | false"]                            <%-- 当缓冲区即将溢出时,是否需要强制输出缓冲区的内容 --%>
   [isThreadSafe="true | false"]                      <%-- 设置该JSP页面是否线程安全 --%>
   [info="text"]                                                 <%-- 设置该JSP程序的说明 --%>
   [errorPage="relativeURL"]                          <%-- 设置错误处理页面(实质是JSP的异常处理机制,JSP脚本不要求强制处理异常) --%>
   [contentType="mimeType[;charset=characterSet]" | "text/html;charSet=ISO-8859-1"]  <%-- 用于设定生成网页的文件格式和编码字符集 --%>
   [pageEncoding="ISO-8859-1"]                   <%-- 生成网页的编码字符集 --%>
   [isErrorPage="true | false"]                         <%-- 设置该JSP页面是否为错误处理页面 --%>
   %>
  7.2 include指令
   include指令,可以将一个外部文件嵌入到当前的JSP文件中,同时解析这个页面中的JSP语句(如果有的话)。
   include既可以包含静态的文本,也可包含动态的JSP页面。静态的include编译指令会将被包含的页面加入到本页面,融合成一个页面,因此被包含的页面甚至不需要是一个完整的页面。需要指出的是,静态包含还会将被包含页面的编译指令也包含进来,如果两个页面的编译指令冲突,那么页面将会出错。
   include编译指令的语法格式:<%@ include file="relativeURLSpec"%>
   如果嵌入的文件经常需要更换,建议使用<jsp:include>操作指令,因为它是动态的include指令。
 8.JSP的7个动作指令
  8.1. 编译指令和动作指令的区别
  编译指令是通知Servlet引擎的处理消息,而动作指令只是运行时的动作。
  编译指令在将JSP编译成Servlet是起作用,而动作指令通常可以被JSP脚本替换,他只是JSP脚本的标准化写法。
  8.2. JSP动作指令主要有如下7个:
   >> jsp:forward:执行页面的转向,将请求的处理转发到下一个页面;
   >> jsp:param:用于传递参数,必须与其他支持参数的标签一起使用;
   >> jsp:include:用于动态引入一个JSP页面;
   >> jsp:plugin:用于下载JavaBean或Applet到客户端执行;
   >> jsp:useBean:创建一个JavaBean的实例;
   >> jsp:setProperty:设置JavaBean实例的属性值;
   >> jsp:getProperty:输出JavaBean实例的属性值。
 9.JSP脚本中的9内置对象
  这9个内置对象都是Servlet API接口的实例,只是JSP规范对它们进行了默认初始化(由JSP页面的Servlet的_jspService方法来创建这些对象),也就是说,他们已经是对象了,可以直接使用。
  >> application:javax.servlet.ServletContext的实例,该实例代表JSP所属的Web应用本身,可用于JSP页面或者在Servlet之间交换信息。常用的方法有getAttribute(String attName);
  >> config:javax.servlet.ServletConfig的实例,该实例代表JSP的配置信息。事实上,JSP页面无需配置,该内置对象更多的用在Servlet中;
  >> exception:java.lang.Throwable的实例,该实例代表其他页面中的错误和异常;
  >> out:javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面的输出流,用于输出内容,形成HTMl页面;
  >> page:代表该页面本身,通常没有太大用处,也就是Servlet中的this,其类型就是生成的Servlet类,能用page的地方就能用this;
  >> pageContext:javax.servlet.jsp.PageContext的实例,该对象代表JSP页面的上下文,使用该对象可以访问页面中共享的数据。常用的方法有:getServletCotext()和getServletConfig();
  >> request:javax.servlet.http.HttpServletRequest的实例,该对象封装了一次请求,客户端的请求参数都被封装在该对象中,获取客户端请求参数必须使用该对象。常用的方法有:setAttribute(String attrName, Object attrValue),getAttribute(String attrName),getParametet(String paramName),getParameterValues(String paramName),setCharacterEncoding(String env);
  >> response:javax.servlet.http.HttpServletResponsse的实例,该实例代表服务器对客户端的响应。通常很少使用该对象直接响应,而是使用out对象,除非需要生成非字符响应。response对象常用于重定向,常用的方法:getRedirect(java.lang.StringLocation),getOutputStream();
  >> session:javax.servlet.http.HttpSeesion的实例,该实例代表一次会话。当客户端浏览器与站点建立连接时会话开始;当客户端关闭浏览器时,会话结束。常用的方法:setAttribute(String attrName, Object attrValue),getAttribute(String attrName)。
  JSP内置对象的实质:它们要么是_jspService()方法的形参,要么是_jspService()方法的局部变量,所以我们可以直接在JSP脚本(脚本将对应Servlet的_jspService()方法部分)中调用这些对象,而无需创建他们。
  9.1. application对象
   在介绍application对象之前,我们先来简单了解一下Web服务器的实现原理。
   抛开Web应用直接看Web服务器和客户端浏览器,对于大部分浏览器而言,他们通常负责三件事情:
   >> 向远程服务器发送请求;
   >> 读取远程服务器返回的字符串数据;
   >> 负责根据字符串数据渲染出一个页面。(浏览器最大的技术难点)
   Web服务器运行机制中总是先由客户端浏览器发送请求,服务器接受请求后送回响应,所以也将这种架构称作“请求/响应”架构。
   Web服务器大致需要如下几步完成对客户端浏览器的请求响应:
   >> 启动单独的线程;    <%-- 通用 --%>
   >> 使用I/O流读取用户的请求数据; <%-- 通用 --%>
   >> 从请求数据中解析参数;   <%-- Web服务器调用Servlet的_jspService()方法处理 --%>
   >> 处理用户请求;     <%-- Web服务器调用Servlet的_jspService()方法处理 --%>
   >> 生成响应;      <%-- Web服务器调用Servlet的_jspService()方法处理 --%>
   >> 使用I/O流向客户端发送响应数据。 <%-- 通用 --%>
   当我们编写JSP页面时,页面中的静态内容、JSP脚本都会转换成_jspService()方法的执行代码,这些代码负责完成解析参数、处理用户的请求、生成响应等业务功能,而Web服务器负责完成多线程、网络通行等底层功能。
   Web服务器在执行了第3步解析请求参数后,将利用这些请求参数来创建HttpServletRequest、HttpServletResponse等对象,作为调用_jspService()方法的参数,实际上一个Web服务器必须为Servlet API中绝大部分接口提供实现类。
   从上面的介绍可以看出,Web应用中的JSP页面、Servlet等程序都是由Web服务器来调用,JSP和Servlet之间通常不会相互调用,那么JSP和Servlet之间如何交换数据?
   为了解决这个问题,几乎所有Web服务器都会提供4个类似Map的结构,分别是:application、session、request、page,并允许JSP和Servlet将数据放进这4个类似Map的结构中,并允许可以从这4个类似Map的结构中取出数据。这4个类似Map的结构的区别是范围不同。
   >> application:整个Web应用有效。一旦JSP、Servlet将数据放入application,该数据将可以被应用下的其他所有的JSP、Servlet访问;
   >> session:仅限一次会话有效。一旦JSP、Servlet将数据放入session,该数据将可以被该次会话下的其他所有的JSP、Servlet访问;
   >> request:仅对本次请求有效,一旦JSP、Servlet将数据放入request,该数据将可以被该次请求的其他所有的JSP、Servlet访问;
   >> page:仅对当前页面有效,一旦JSP、Servlet将数据放入page,该数据只能被当前页面的JSP脚本、声明部分访问。
   把数据放入application、session、request、page中,就相当于是扩大了该数据的作用范围。
   JSP中application、session、request、pageContext4个内置对象用于操作application、session、request、page范围中的数据。
   application对象代表Web应用本身,因此使用application来操作Web应用相关数据。application对象通常有如下两个作用:
    >> 在整个Web应用的多个JSP、Servlet之间共享数据;setAttribute(String attrName,Object values)、getAttribute(String attrName)这两个方法用于共享数据。需要指出的是,由于application代表整个Web应用,所以不要仅仅为了JSP、Servlet之间共享数据,就将数据放入application中,通常将Web应用的状态数据放入application中。
    >> 访问Web应用的配置参数。
  9.2. config对象
   config对象代表当前JSP页面配置信息,但JSP页面通常无需配置,因此也就不存在配置信息。该对象在JSP页面中很少使用,但在Servlet中用处较大,因为Servlet需要在web.xml文件中进行配置,可以指定配置参数。
   如果希望通过JSP页面获取web.xml配置文件中的配置信息,那么就需要将JSP页面当成Servlet来配置,并通过为该JSP页面配置的路径来访问该页面才能让配置参数起作用。
  9.3. exception对象
   exception对象是Throwable的实例,代表JSP脚本中产生的错误和异常,是JSP页面机制中的一部分。
   在JSP脚本中无需处理异常,即使该异常是checked异常。事实上,JSP脚本包含的所有的可能出现的异常都可以交给错误处理页面处理。
   exception对象仅仅在异常处理页面有效。
   JSP脚本和静态HTML部分都会转化为_jspService()方法中的可执行代码,这就是JSP页面无需处理异常的原因,因为这些脚本已经处在try块中,一旦try块中捕捉到JSP脚本的异常,并且_jspx_page_context部位null,就会由该对象来处理异常。
   当JSP页面page指令的isErrorPage属性为true时,该页面就会提供exception内置对象。
  9.4. out对象
   out对象代表一个页面输出流,通常用于在页面上输出变量值和常量。一般在使用输出表达式的地方,都可使用out对象来达到同样效果。
   out.print(...)
   <%=...%>表达式的本质就是:out.write(...)
  9.5. pageContext对象
   这个对象代表页面上下文,该对象主要用于访问JSP之间的共享数据。
   使用pageContext可以访问page、request、sssion、application范围中的变量。
   pageContext对象是PageContext类的实例,他提供了两个方法来访问page、request、sssion、application范围中的变量。
   >> getAttribute(String name):取得page范围内的name属性
   >> getAttribute(String name, int scope):取得指定范围内的name属性,其中scope可以使以下4个值:
    PageContext.PAGE_SCOPE、PageContext.REQUEST_SCOPE、PageContext.SESSION_SCOPE、PageContext.APPLICATION_SCOPE
   与此对应的有2个setAttribute()方法。(没有指定范围时,默认在page范围中)
   一旦在JSP、Servlet中获取了pageContext对象,就可通过他提供的方法获取其他的内置对象。
  9.6. request对象
   request对象是JSP中重要的对象,每个request对象封装着一次用户请求,其中的请求参数也在其中,因此request对象是获取请求参数的重要途径。除此之外,request对象可代表本次请求范围,因此可以操作request范围的属性。
   9.6.1. 获取请求头/请求参数
    浏览器发送请求时通常会附带一些请求头及请求参数,服务器端负责解析请求头及请求参数的就是JSP或Servlet,而JSP或Servlet获取请求参数的途径就是request。
    request对象是HttpServletRequest接口的实例,他提供了如下几个方法来获取请求参数:
     -> String getParameter(String paramName):获取paramName请求参数的值
     -> Map getParameterMap():获取所有请求参数名和参数值所组成的Map对象
     -> Enumeration getParameterNames():获取所有请求参数名所组成的Enumeration对象
     -> String[] getParameterValues(String name):获取所有请求参数值所组成的数组
    提供如下的方法来访问请求头:
     -> String getHeader(String name):根据指定请求头的值
     -> java.util.Enumeration<String> getHeaderNames():获取所有请求头的名称
     -> java.util.Enumeration<String> getHeaders(String name):获取指定头的多个值
     -> int getIntHeader(String name):获取指定请求头的值,并将该值转化为整数值
    对于开发人员而言,请求头和请求参数都是由用户发送到服务器的数据,请求头通常由浏览器自动添加,因此一次请求通常包含还几个请求头;而请求参数则通常需要开发人员控制添加。
    让客户端发送请求参数通常分2中情况:
     >> GET方式:GET方式的请求会将请求参数的名和值直接转换为字符串,并附加在原url之后,因此可以在地址栏中看到请求参数名和值,GET请求传送的数据一般不能大于2kb。(form元素的method属性为get,或不设置)
     >> POST方式:这种方式通常使用提交表单的方式发送,且需要设置form元素的method属性为post。通常认为post请求参数的数据量大小不受限制,但往往取决于服务器的限制,post方式发送的请求参数放置在HTML HEADER中传递,在地址栏看不见请求参数,安全性相对较高。
    比较以上两种请求方式,我们通常采用POST方式发送请求。
    表单用于收集用户信息,一旦用户提交请求,表单中的数据将会提交给对应的处理程序。
    并不是每个表单域都会生成请求参数,而是有name属性的表单域才会生成请求参数。关于表单域和请求参数的关系遵循以下四点:
     >> 每个有name属性的表单域对应一个请求参数
     >> 如果有多个表单域有相同的name属性,则多个表单域只生成一个请求参数,只是该请求参数中有多个值。
     >> 表单域的name属性指定请求参数名,value指定请求参数值
     >> 如果某个表单域设置了disabled="disabled"属性,则该表单域不再生成请求参数。
   9.6.2. 操作request范围的属性
    HttpServletRequest提供如下两个方法,用于设置和获取request范围的属性;
     -> setAttribute(String attrName, Object attValue):将attValue设置为request范围的属性attrName的值
     -> Object getAttribute(String attrName):获取request范围名为attrName的属性
    当forward用户请求时,请求的参数和属性都不会丢失。(即可携带参数)
   9.6.3. 执行foreard或include
    -> forward(ServletRequest request, ServletResponse response)
    -> include(ServletRequest request, ServletResponse response)
    以上的两个方法都是先执行方法:getRequestDispatcher(String path)以后再调用。
  9.7. response对象
   out生成字符串响应。
   response生成非字符串响应,还可用于重定向请求,以及用于向客户端增加cookie。
   9.7.1. response响应生成非字符串响应
    response是HttpServletResponse接口的实例,该接口提供了一个getOutputStream()方法,该方法返回响应输出字节流。
   9.7.2. 重定向
    与foward不同的是,重定向会丢失所有请求参数和request范围中的属性,因为重定向将生成第二次请求,与第一次请求不在同一个request范围内,所以导致第一次的所有请求参数和request范围中的属性丢失。
    sendRedirect(String path)方法用于重定向到path资源。
    forward与重定向的区别:
    --------------------------------------------------------+------------------------------------------------------
     转发(forward)                                         |             重定向(redirect)        
      执行forward之后依然是上一次请求           |   执行redirect之后生成第二次请求      
      原请求参数和request范围内的属性保留    |  原请求参数和request范围内的属性丢失  
      地址栏的url不会变化                                  |  地址栏的url变化                      
    --------------------------------------------------------+-----------------------------------------------------
   9.7.3. 增加cookie
    Cookie通常用户网站记录客户的某些信息。
    Cookie与session不同的是,session会随着浏览器的关闭而失效,而Cookie会一直保存在客户端机器上,除非超出了Cookie的生命周期。
    response 的方法void addCookie(Cookie cookie)用于增加Cookie
    *-?-* 详细介绍请百度 *-?-*
  9.8. session对象
   session对象代表一次会话,一次会话的含义是:从客户端浏览器链接服务器开始,到客户端浏览器与服务器断开为止。
   session通常用于跟踪用户的会话信息,如判断用户是否登录系统,或者购物车是否存在商品等。
   session范围内的数据可以在多个页面之间跳转共享。一旦浏览器关闭,即session结束,那么session范围中的属性也立即丢失。
   session是HttpSession的实例,常用的方法有如下两个:
    -> setAttribute(String attName, Object attValue):设置session范围内的属性attName的值为attValue
    -> getAttribute(String attName):获取session范围内的名为attName的属性的值
   考虑session本身的目的,通常只把与用户会话状态相关的信息放入session范围内。不要仅仅为了两个页面之间交换信息,就将该信息放入session范围内。如果仅仅是为了两个页面之间交换信息,可以将信息放入request范围内,然后forward请求即可。
   session的属性值可以是任何可序列化的Java对象。
 10.servlet介绍
  JSP的本质就是Servlet,开发者把编写好的JSP部署到Web容器中之后,Web容器就会将JSP编译成对应的Servlet。
  自从MVC规范出现以后,Servlet的责任开始明确下来,仅仅做为控制器使用。
  10.1. Servlet的开发
   Servlet通常被称为“服务器端小程序”,是运行在‘服务器端的程序’,用来处理来自客户端的请求及响应来自客户端的请求。
   Servlet是个特殊的Java类,这个类必须继承HttpServlet。Servlet提供了不同的方法用于响应来自客户端的请求。
    >> doGet:用于响应客户端的get请求
    >> doPost:用于响应客户端的post请求
    >> doPut:用于响应客户端的put请求
    >> doDelete:用于响应客户端的delete请求
   事实上,客户端的请求只有get和post两种,Servlet为了响应这两种请求,必须重写doGet()和doPost()两个方法。大部分的时候,Servlet对于所有的请求的响应都是完全一样的,可以采用重写一个方法来代替上面几个方法:只需要重写service()方法即可响应客户端的所有请求。
   另外,HttpServlet还提供了两个方法:
    >> init(ServletConfig config):创建Servlet实例时,调用该方法以初始化Servlet资源
    >> destroy():销毁Servlet实例时,自动调用该方法回收资源
   通常无需重写init()和destroy()方法。
   Servlet和JSP的区别在于:
    -> Servlet中没有内置对象,JSP中的内置对象都是由程序显示创建的;
    -> 对于静态的HTML标签,Servlet都必须使用输出流逐行输出。
   普通Servlet类的service()方法的作用,完全等同于JSP生成Servlet类的_jspService()方法。
   原JSP声明中的内容,对应生成的Servlet类中的成员变量和成员方法。
  10.2. Servlet配置
   编辑好的Servlet源文件并不能直接响应客户端的请求,还必须将其编译成class文件,放置在WEB-INF/classes路径下,并且在web.xml文件中配置Servlet。
   配置Servlet有两种方法(只能选择其中一种配置,不能同时配置):
    >> 在Servlet类中使用 @WebServlet Annotation进行配置
    >> 通过在web.xml文件进行配置
   10.2.1. 使用Annotation进行配置
    注意两点:
     -> 不要在web.xml文件的根元素(<web-app.../>)中指定metadata-complete="true"。
     -> 不要再web.xml文件中配置该Servlet 
    常用属性:
     @WebServlet Annotation(
      name     //制定该Servlet的名称
      asyncSupported   //指定该Servlet是否支持异步操作模式
      displayName    //指定该Servlet的显示名
      initParams    //用于为该Servlet配置参数
      loadOnStartup   //用于将该Servlet配置成load-on-startup的Servlet
      urlPatterns    //指定该Servlet处理的URL
      value     //指定该Servlet处理的URL
     )
   10.2.2. 使用web.xml文件进行配置
    两个部分:
     <servlet>
      <!-- 指定Servlet的名称 -->
      <servlet-name>... ...</servlet-name>
      <!-- 指定Servlet的实现类 -->
      <servlet-class>... ...</servlet-class>
     </servlet>
     <servlet-mapping>
      <!-- 指定Servlet的名称 -->
      <servlet-name>... ...</servlet-name>
      <!-- 指定Servlet映射的URL地址 -->
      <url-pattern>/... ...</url-pattern>
     </servlet-mapping>
  10.3. JSP/Servlet的生命周期
   开发者编写的JSP由Web容器编译成对应的Servlet后,运行在Web容器(服务器端)之中,其实例的创建和销毁由Web容器进行控制。
   创建Servlet实例有两种时机:
    -> 客户端第一次请求某个Servlet时,系统创建该Servlet的实例。(绝大部分Servlet采用这种)
    -> Web应用启动时立即创建Servlet实例,即:load-on-startup Servlet。
   Servlet生命周期:
    -> 创建Servlet实例
    -> Web容器调用Servlet的init()方法初始化Servlet
    -> Servlet初始化之后,一直存在于Web容器中,用于响应客户端的请求。客户端若是get请求,则调用doGet(),反之亦然 ...
    -> Web容器决定销毁Servlet,首先调用destroy()方法。通常在关闭Web应用之前销毁Servlet。
  10.4. load-on-startup Servlet
   应用启动时立刻创建Servlet,通常用于某些后台服务的Servlet,或者需要拦截很多请求的Servlet,这种Servlet通常作为应用的基础Servlet使用,提供重要的后台服务。
   配置load-on-startup Servlet的两种方式;
    -> web.xml文件中通过<servlet.../>元素的<load-on-startup.../>子元素进行配置
    -> @WebServlet Annotation的loadOnStartup属性指定(@WebServlet(loadOnStartup=1)单位是:min)
  10.5. 访问Servlet的配置参数
   配置Servlet时,还可以为Servlet添加其他的配置参数。方法有两种:
   >> 通过 @WebServlet的initParams属性来指定
   >> 通过web.xml文件的<servlet.../>元素中添加<init-param.../>子元素来指定
   访问Servlet配置参数的方法是通过ServletConfig对象完成的,ServletConfig对象提供以下方法:
   >> java.lang.String getInitParameter(java.lang.String name):用于获取初始化参数
   注意:JSP中的config内置对象就是这里的ServletConfig
   【示例】:
    @WebServlet:
     @WebServlet(name="testServlet",
        urlPatterns={"/testServlet"},
        initParams={
         @WebInitParam(name="driver", value="com.masql.jdbc.Driver"),
         @WebInitParam(name="url", value="jdbc:masql://localhost:3306/javaee"),
         @WebInitParam(name="username", value="root"),
         @WebInitParam(name="password", value="root")
        }
     )
    web.xml:
     <servlet>
      <init-param>
       <param-name>driver</param-name>
       <param-value>com.masql.jdbc.Driver</param-value>
      </init-param>
     </servlet>
    ... ...
    //获取ServletConfig对象
    ServletConfig sConfig = getServletConfig();
    //通过ServletConfig对象获取配置参数:driver、url、username、password
    String driver = sConfig.getInitParameter("driver");
    String url = sConfig.getInitParameter("url");
    String username = sConfig.getInitParameter("username");
    String password = sConfig.getInitParameter("password");
    Class.forName(driver);
    Connection connection = DriverManager.getConnection(url, username, paaword);
    ... ...
   ServletConfig是获取当前Servlet的配置参数,而ServletContext是获取整个Web应用的配置参数。
  10.6. 使用Servlet作为控制器
   使用Servlet作为表现层的工作量太大。
   Java EE应用架构遵循MVC模式,所以Servlet仅作为控制器使用,JSP仅作为表现层使用。
   使用JSP作为表现层有下面两个作用:
    >> 负责收集用户的请求参数
    >> 将应用的处理结果,状态参数呈现给用户
   Servlet的作用类似于调度员,所有用户的请求都必须发送给Servlet,由Servlet调用Model来处理用户的请求,并调用JSP来呈现处理结果;或者Servlet直接调用JSP将应用的状态数据呈现给用户。
   Model通常由JavaBean来充当,所有的业务逻辑、数据访问逻辑都在Model中实现。实际上隐藏在Model下的可能还有很多丰富的组件:例如DAO组件,POJO组件... ...
   控制器负责接收客户端的请求,他既不能直接对客户端输出响应,也不能处理请求,只能调用JavaBean来处理用户请求。
 11.JSP2的自定义标签
  11.1. 使用标签库
   在JSP页面中确定制定的标签库需要两点;
   >> 标签库uri:确定使用哪个标签库
   >> 标签名:确定使用哪个标签
   使用标签库需要两个步骤:
   >> 导入标签库:使用taglib编译指令导入标签库
   >> 使用标签:在JSP页面中使用自定义标签
   <%@ taglib uri="tagliburi" prefix="tagPrefix" %> 
   <!-- 其中uri确定一个标签库,prefix属性指定标签库的前缀 -->
 12.Filter介绍
  Filter可以认为是Servlet的一种“加强版”,他主要对用户的请求HttpServletRequest进行预处理,也可以对响应HttpServletResponse进行后处理,是一个典型的处理链。
  使用Filter完整的流程是:Filter对用户的请求进行预处理,接着将预处理后的请求交给Servlet进行处理并生成响应,最后Filter再对服务器进行后处理。
  Filter有如下几个用处:
  >> 在HttpServletRequest到达Servlet之前,拦截来自客户的HttpServletRequest
  >> 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据
  >> 在HttpServletResponse到达客户端之前,拦截来自服务器的HttpServletResponse
  >> 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据
  Filter有如下几个种类;
  >> 用户授权的Filter:该Filter负责检查用户请求,过滤用户的非法请求
  >> 日志Filter:详细记录某些特殊的用户请求
  >> 负责解码的Filter:包括对非标准编码的请求解码
  >> 能改变XML内容的XSLT Filter等
  >> 一个Filter可以负责拦截多个请求或响应:一个请求或响应也可以被多个Filter拦截
  创建一个Filter只需要两步:
  >> 创建一个Filter处理类
  >> 在web.xml文件中配置该Filter
  12.1. 创建Filter类
   创建Filter必须实现javax.servlet.Filter接口。该接口中定义了如下三个方法:
   -> void innit(FilterConfig config):用于完成Filter的初始化
   -> void destroy():用于Filter销毁前,完成某些资源的回收
   -> void doFilter(ServletRequest request, ServletResponse response, FilterChain chain):实现过滤功能
  12.2. 配置Filter
   配置Filter有如下两个部分:
   >> 配置Filter名
   >> 配置Filter拦截URL模式
   配置Filter和Servlet的无别在于:Servlet通常只需要配置一个URL,而Filter可以同时拦截多个请求的URL。因此,在配置Filter的URL模式时通常采用模式字符串,使得Filter可以拦截多个请求。
   配置Filter有如下两种方式:
   >> 在Filter类中通过Annotation进行配置
   >> 在web.xml文件中进行配置
   12.2.1. 使用Annotation进行配置
    注意两点:
     -> 不要在web.xml文件的根元素(<web-app.../>)中指定metadata-complete="true"。
     -> 不要再web.xml文件中配置该Servlet 
    常用属性:
     @WebFilter Annotation(
      name     //制定该Filter的名称
      dispatcherTypes   //制定该Filter仅对那种dispatcher模式的请求进行过滤
      asyncSupported   //指定该Filter是否支持异步操作模式
      displayName    //指定该Filter的显示名
      initParams    //用于为该Filter配置参数
      servletNames   //指定该Filter仅对这几个Servlet执行过滤
      urlPatterns    //指定该Filter处理的URL
      value     //指定该Filter处理的URL
     )
   12.2.2. 使用web.xml文件进行配置
    两个部分:
     <filter>
      <!-- 指定filter的名称 -->
      <filter-name>... ...</filter-name>
      <!-- 指定filter的实现类 -->
      <filter-class>... ...</filter-class>
     </filter>
     <filter-mapping>
      <!-- 指定filter的名称 -->
      <filter-name>... ...</filter-name>
      <!-- 指定filter需要拦截的URL -->
      <url-pattern>/... ...</url-pattern>
     </filter-mapping>
   实际上,Filter和Servlet极其相似,只是Filter的doFilter()方法中多了一个FilterChain的参数,通过该参数可以控制是否放行用户的请求。在实际项目开发中,Filter里doFilter()方法中的代码就是从多个Servlet的service()方法里面抽取的通用代码,通过使用Filter可以提高代码的复用性。
   由于Filter和Servlet极其相似,所以Filter具有和Servlet相同的生命周期行为。
   Filter也可以通过<init-param.../>元素或 @WebFilter的initParams属性来配置初始化参数,获取Filter的初始化参数则使用FilterConfig的getInitParameter()方法。
  12.3. 使用 URL Rewrite 实现网站的伪静态
   为什么要使用伪静态网站?
    对于以JSP为表现层开发的动态网站来说,用户访问的URL通常是如下形式:
    xxx.jsp?param=value...
    大部分搜索引擎都会优先收集静态HTML页面,而不是这种动态的*.jsp、*.php页面,所以大部分网站都会考虑使用伪静态。
   对于Java Web应用而言,如何实现网站伪静态?
    可以通过Filter拦截所有发向*.html的请求,然后按照某种规则将请求forward(转发)到实际的*.jsp或*.php页面即可。
   可以使用《URL Rewrite》实现网站的伪静态,具体参见网络。

你可能感兴趣的:(java,Hibernate,ee)