JavaWeb三大组件之Servlet

原创
2017/02/05 22:18
阅读数 201

###Servlet的生命周期###

与Servlet的生命周期相关的方法有:

  • void init(ServletConfig) 服务器会在Servlet第一次被访问时创建Servlet,或者是在服务器启动时创建Servlet。如果服务器启动时就创建Servlet,那么还需要在web.xml文件中配置。也就是说默认情况下,Servlet是在第一次被访问时由服务器创建的。 而且一个Servlet类型,服务器只创建一个实例对象,当客户端发送一个请求时,Servlet容器(Tomcat)会查找内存中是否存在Servlet实例,如果不存在,就创建一个Servlet实例。如果存在Servlet实例,就直接从内存中取出该实例来响应请求是直接使用上次创建的实例。 在Servlet被创建后,服务器会马上调用Servlet的void init(ServletConfig)方法。请记住, Servlet出生后马上就会调用init()方法,而且一个Servlet的一生。这个方法只会被调用一次。我们可以把一些对Servlet的初始化工作放到init方法中!
  • void service(ServletRequest,ServletResponse); 当服务器每次接收到请求时,都会去调用Servlet的service()方法来处理请求。服务器接收到一次请求,就会调用service() 方法一次,所以service()方法是会被调用多次的。
  • void destroy(); 在服务器被关闭时,服务器会去销毁Servlet,在销毁Servlet之前服务器会先去调用Servlet的destroy()方法,我们可以把Servlet的临终遗言放到destroy()方法中,例如对某些资源的释放等代码放到destroy()方法中。

###特性###

  • 单例,只创建一个对象,
  • 线程不安全,效率是高的
  • Servlet类我们来写,对象由服务器创建,并且由服务器调用其中的方法
  • 动态资源,处理请求

###Servlet接口###

####Servlet接口相关类型####

  • ServletRequest:service() 方法的参数,它表示请求对象,它封装了所有与请求相关的数据,它是由服务器创建的;
  • ServletResponse:service()方法的参数,它表示响应对象,在service()方法中完成对客户端的响应需要使用这个对象;
  • ServletConfig:init()方法的参数,它表示Servlet配置对象,它对应Servlet的配置信息,那对应web.xml文件中的<servlet>元素。

####ServletRequest和ServletResponse#### ServletRequest和ServletResponse的实例由服务器创建,然后传递给service()方法。如果在service() 方法中希望使用HTTP相关的功能,那么可以把ServletRequest和ServletResponse强转成HttpServletRequest和HttpServletResponse。这也说明我们经常需要在service()方法中对ServletRequest和ServletResponse进行强转,这是很繁琐的事情。不过后面会有一个类来帮我们解决这一问题的。

#####HttpServletRequest方法:#####

  • String getParameter(String paramName):获取指定请求参数的值;
  • String getMethod():获取请求方法,例如GET或POST;
  • String getHeader(String name):获取指定请求头的值;
  • void setCharacterEncoding(String encoding):设置请求体的编码!当调用request.setCharacterEncoding(“utf-8”)之后,再通过getParameter()方法获取参数值时,那么参数值都已经通过了转码,即转换成了UTF-8编码。所以,这个方法必须在调用getParameter()方法之前调用!

#####HttpServletResponse方法:#####

  • PrintWriter getWriter():获取字符响应流,使用该流可以向客户端输出响应信息。例如 response.getWriter().print(“<h1>Hello JavaWeb!</h1>”);
  • ServletOutputStream getOutputStream():获取字节响应流,当需要向客户端响应字节数据时,需要使用这个流,例如要向客户端响应图片;
  • void setCharacterEncoding(String encoding):用来设置字符响应流的编码,例如在调用setCharacterEncoding(“utf-8”);之后,再response.getWriter()获取字符响应流对象,这时的响应流的编码为utf-8,使用response.getWriter()输出的中文都会转换成utf-8编码后发送给客户端;
  • void setHeader(String name, String value):向客户端添加响应头信息,例如 setHeader(“Refresh”, “3;url=http://www.baidu.com”),表示3秒后自动刷新到百度;
  • void setContentType(String contentType):该方法是setHeader(“content-type”, “xxx”)的简便方法,即用来添加名为content-type响应头的方法。content-type响应头用来设置响应数据的MIME类型,例如要向客户端响应jpg的图片,那么可以setContentType(“image/jepg”),如果响应数据为文本类型,那么还要台同时设置编码,例如setContentType(“text/html;chartset=utf-8”)表示响应数据类型为文本类型中的html类型,并且该方法会调用setCharacterEncoding(“utf-8”)方法;
  • void sendError(int code, String errorMsg):向客户端发送状态码,以及错误消息。例如给客户端发送404:response(404, “您要查找的资源不存在!”)。

#####ServletConfig##### ServletConfig对象对应web.xml文件中的<servlet>元素。例如你想获取当前Servlet在web.xml文件中的配置名,那么可以使用servletConfig.getServletName()方法获取! ServletConfig对象是由服务器创建的,然后传递给Servlet的init()方法,你可以在init()方法中使用它!

  • String getServletName():获取Servlet在web.xml文件中的配置名称
  • ServletContext getServletContext():用来获取ServletContext对象
  • String getInitParameter(String name):用来获取在web.xml中配置的初始化参数,通过参数名来获取参数值;
  • Enumeration getInitParameterNames():用来获取在web.xml中配置的所有初始化参数名称;

###配置###

正常是第一次访问服务器时创建servlet,启动时就完成创建

    <servlet> 
       <load-on-startup>非负整数</load-on-startup> 
    </servlet>

<url-pattern>访问路径中使用通配符

    <url-pattern>/*<url-pattern>匹配所有
    <url-pattern>*.do<url-pattern>匹配扩展名是.do的所有路径
    <url-pattern>/servlet/*</url-pattern>匹配/servlet路径候的所有的路径

###创建servlet###

  1. 实现javax.servlet.servlet接口
  2. 继承javax.servlet.genriticservlet类
  3. 继承javax.servlet.http.httpservlet类型

###Servlet三个域对象###

  • request
  • session
  • application(ServletContext)

####Servlet request#### Response/Request的概述及用法

####Servlet Session跟踪#### HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。但是仍然有以下三种方式来维持 Web 客户端和 Web 服务器之间的 session 会话:

#####Cookies##### 一个 Web 服务器可以分配一个唯一的 session 会话 ID 作为每个 Web 客户端的 cookie,对于客户端的后续请求可以使用接收到的 cookie 来识别。

这可能不是一个有效的方法,因为很多浏览器不支持 cookie,所以我们建议不要使用这种方式来维持 session 会话。

#####隐藏的表单字段##### 一个 Web 服务器可以发送一个隐藏的 HTML 表单字段,以及一个唯一的 session 会话 ID,如下所示:

<input type="hidden" name="sessionid" value="12345">

该条目意味着,当表单被提交时,指定的名称和值会被自动包含在 GET 或 POST 数据中。每次当 Web 浏览器发送回请求时,session_id 值可以用于保持不同的 Web 浏览器的跟踪。

这可能是一种保持 session 会话跟踪的有效方式,但是点击常规的超文本链接(<A HREF...>)不会导致表单提交,因此隐藏的表单字段也不支持常规的 session 会话跟踪。

#####URL 重写##### 可以在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。

例如,http://w3cschool.cc/file.htm;sessionid=12345,session 会话标识符被附加为 sessionid=12345,标识符可被 Web 服务器访问以识别客户端。

URL 重写是一种更好的维持 session 会话的方式,它在浏览器不支持 cookie 时能够很好地工作,但是它的缺点是会动态生成每个 URL 来为页面分配一个 session 会话 ID,即使是在很简单的静态 HTML 页面中也会如此。

#####HttpSession 对象##### 除了上述的三种方式,Servlet 还提供了 HttpSession 接口,该接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式。

Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求。

通过调用 HttpServletRequest 的公共方法 getSession() 来获取 HttpSession 对象,如下所示:

HttpSession session = request.getSession();

你需要在向客户端发送任何文档内容之前调用 request.getSession()。下面总结了 HttpSession 对象中可用的几个重要的方法:

  • public Object getAttribute(String name)该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。
  • public Enumeration getAttributeNames()该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。
  • public long getCreationTime()该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
  • public String getId()该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。
  • public long getLastAccessedTime()该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
  • public int getMaxInactiveInterval()该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。
  • public void invalidate()该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。
  • public boolean isNew()如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。
  • public void removeAttribute(String name)该方法将从该 session 会话移除指定名称的对象。
  • public void setAttribute(String name, Object value) 该方法使用指定的名称绑定一个对象到该 session 会话。
  • public void setMaxInactiveInterval(int interval)该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。

#####删除 Session 会话数据##### 当您完成了一个用户的 session 会话数据,您有以下几种选择:

  • 移除一个特定的属性:您可以调用 public void removeAttribute(String name) 方法来删除与特定的键相关联的值。
  • 删除整个 session 会话:您可以调用 public void invalidate() 方法来丢弃整个 session 会话。
  • 设置 session 会话过期时间:您可以调用 public void setMaxInactiveInterval(int interval) 方法来单独设置 session 会话超时。
  • 注销用户:如果使用的是支持 servlet 2.4 的服务器,您可以调用 logout 来注销 Web 服务器的客户端,并把属于所有用户的所有 session 会话设置为无效。
  • web.xml 配置:如果您使用的是 Tomcat,除了上述方法,您还可以在 web.xml 文件中配置 session 会话超时,如下所示:
      <session-config>
        <session-timeout>15</session-timeout>
      </session-config>

上面实例中的超时时间是以分钟为单位,将覆盖 Tomcat 中默认的 30 分钟超时时间。

在一个 Servlet 中的 getMaxInactiveInterval() 方法会返回 session 会话的超时时间,以秒为单位。所以,如果在 web.xml 中配置 session 会话超时时间为 15 分钟,那么 getMaxInactiveInterval() 会返回 900。

####ServletContext#### 服务器会为每个应用创建一个ServletContext对象:

  • ServletContext对象的创建是在服务器启动时完成的;
  • ServletContext对象的销毁是在服务器关闭时完成的。

ServletContext对象的作用是在整个Web应用的动态资源之间共享数据!例如在AServlet中向ServletContext对象中保存一个值,然后在BServlet中就可以获取这个值,这就是共享数据了。

#####获取#####

  • ServletConfig getServletContext()
  • GenericSevlet getServletContext()
  • HttpSession getServletContext()
  • ServletContextEvent getServletContext()

#####域对象功能##### 所有域对象都有存取数据的功能,因为域对象内部有一个Map,用来存储数据,下面是ServletContext对象用来操作数据的方法:

  • void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;
  • Object getAttribute(String name):用来获取ServletContext中的数据,当前在获取之前需要先去存储才行;
  • void removeAttribute(String name):用来移除ServletContext中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;
  • Enumeration getAttributeNames():获取所有域属性的名称;

#####方法#####

######获取初始化参数的方法###### String getInitParameter(String name)

######获取资源相关方法###### 获取绝对路径

    this.getServletContext.getRealPath("/a.txt")
    this.getServletContext.getRealPath("/WEB-INF/b.txt")

获取资源流

    InputStream in = servletContext.getResourceAsStream(“/a.txt”);
    InputStream in = servletContext.getResourceAsStream(“/WEB-INF/b.txt”);

获取指定资源下所有资源路径

    Set set = this.getServletContext.getResourcePaths("/WEB-INF")
    InputStream in =  this.getClassLoader().getResourceAsStream("a.txt")//相对于classes文件目录
    InputStream in =  this.getClass().getReasourceAsStream("a.txt")//相对于.class文件目录
    InputStream in =  this.getClsss().getReasourceAsStream("/a.txt")//相对于classes文件目录
展开阅读全文
打赏
0
5 收藏
分享
加载中
更多评论
打赏
0 评论
5 收藏
0
分享
返回顶部
顶部