Servlet基础

现在学习Servlet,我的主要目的是做整体了解,作为学习SSM的热身,所以本篇的目的是以一篇文章实现对servlet的基本概括。

简介

java servlet是运行在Web 服务器或应用服务器上的程序,是一个中间层,介于web浏览器(HTTP客户端)——HTTP服务器上的数据库或应用程序之间

本质上,servlet是运行在web服务器上的java类,Servlet 可以使用 javax.servlet 和 javax.servlet.http 包创建

任务

Servlet主要执行以下任务:

  • 读取B/C发送的HTTP请求数据(表单、cookies等)
  • 处理请求生成结果,通过访问数据库、计算、远程调用等方式产生结果
  • 发送给B/C相关的HTTP答复

生命周期

  • init()

    进行Servlet初始化,方法只被调用一次;

    Servlet创建于用户第一次调用对应该Servlet的URL,当然也可以指定Servlet在服务器第一次启动时即加载;

    用户调用一个Servlet时,就会创建一个Servlet实例,每次请求都会产生一个新的线程,适当的时候交给doGet或doPost

  • service()

    执行任务的主要方法,容器调用service()处理客户端请求并将格式化的响应返回客户端;

    一个Servlet请求会有一个线程,线程内会调用本方法检查HTTP请求类型,并在适当时候调用doGet、doPost等方法

  • destroy()

    在此Servlet将终止,使得Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动,仅被调用一次;

    调用此方法后,Servlet对象被标记为垃圾回收

  • 回收

    Servlet由JVM的GC进行垃圾回收

Servlet-LifeCycle.jpg
  • 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器
  • Servlet 容器在调用 service() 方法之前加载 Servlet
  • Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。

Servlet部署

默认情况下,Servlet 应用程序位于路径 <Tomcat-installation-directory>/webapps/ROOT 下,且类文件放在 <Tomcat-installation-directory>/webapps/ROOT/WEB-INF/classes 中

举个例子,把aaa.class放入./ROOT/WEB-INF/classes中,并在位于./WEB-INF/下的web.xml中创建如下条目:

<web-app>
    <servlet>
        <servlet-name>aaa</servlet-name>        当前servlet的名字
        <servlet-class>aaa</servlet-name>       对应的aaa.class
    </servlet>
    
    <servlet-mapping>
        <servlet-name>aaa</servlet-name>
        <url-pattern>/AAA</url-pattern>         URL(表示需要在输入的网址的末尾添加/AAA标志特定的URL)
    </servlet-mapping>
</web-app>

在aaa.class类之前需要加上@WebServlet("/AAA")

使用Servlet读取表单数据

  • getParameter()

    调用 request.getParameter()来获取表单参数的值。

  • getParameterValues()

    如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框。

  • getParameterNames()

    调用该方法可以得到当前请求中的所有参数的完整列表

举个例子:

前端:
<form action="FormTest" method="GET">
名:<input type="text" name="name">
<br />
手机:<input type="text" name="url" />
<input type="submit" value="提交" />

分别输入:aaa   5656456

经get后的URL为:
.../URL?name=aaa&url=5656456

后台:
使用request.getParameter("name")获取name

Servlet过滤器

  • 使用过滤器的目的:

    1. 客户端请求到达时,拦截请求
    2. 服务器的响应发回客户端前,处理响应

过滤器通过Web部署描述符web.xml中的XML标签来声明,然后映射到应用程序的部署描述符中的Servlet名称或URL模式

当Web容器启动Web应用程序时,它会为web.xml中声明的每一个过滤器创建一个实例Filter的执行顺序与在web.xml配置文件中filter-mapping的配置顺序一致,一般把Filter配置在所有的Servlet之前

seq 方法&描述
1 public void doFilter (ServletRequest, ServletResponse, FilterChain)
该方法完成实际的过滤操作当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器(调用其doFilter()方法往后传)
2 public void init(FilterConfig filterConfig)
web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能(filter对象只会创建一次,init方法也只会执行一次)。通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
3 public void destroy()
Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类。javax.servlet.Filter 接口定义了三个方法:

seq 方法&描述
1 public void doFilter (ServletRequest, ServletResponse, FilterChain)
该方法完成实际的过滤操作当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器(调用其doFilter()方法往后传)
2 public void init(FilterConfig filterConfig)
web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能(filter对象只会创建一次,init方法也只会执行一次)。通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
3 public void destroy()
Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

关于使用filterConfig举个例子

web.xml中:
<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.kindol.test</filter-class>        test为相应的实现Filter接口的类
    <init-param>
        <param-name>testYo</param-name>
        <param-value>abc</param-value>
    </init-param>
</filter>

在test类(实现Filter接口)中的init方法:
public void init(FilterConfig filterConfig)
{
    String testYo = config.getInitParameter("testYo");
    System.out.println("testYo: " + testYo);
}

在整个web.xml中配置如下

<web-app>  

<filter>
  <filter-name>myFilter</filter-name>
  <filter-class>com.kindol.test</filter-class>        test为相应的实现Filter接口的类
  <init-param>
    <param-name>testYo</param-name>
        <param-value>abc</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>myFilter</filter-name>
  <url-pattern>/*</url-pattern>         设置 filter 所拦截的请求路径,/*表示适合所有Servlet,可以指定特定Servlet路径(此时将url-pattern改为servlet-name)
  <dispatcher>REQUEST</dispatcher>      没有配置dispatcher就是默认request方式
    <dispatcher>FORWARD</dispatcher>  
    <dispatcher>ERROR</dispatcher>  
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>

<servlet>  
  <servlet-name>myServlet</servlet-name>        类名
  <servlet-class>com.kindol.myServlet</servlet-class>    所在的包
</servlet>  
<servlet-mapping>  
  <servlet-name>myServlet</servlet-name>  
  <url-pattern>/TomcatTest/myServlet</url-pattern>      url对应的所访问的网址
</servlet-mapping>  

</web-app>  

web.xml配置各节点说明

  • <filter>指定一个过滤器
    • <filter-name>过滤器的名字
    • <filter-class>过滤器的完整的限定类名
    • <init-param>初始化参数,子元素<param-name>指定参数的名字,<param-value>指定参数的值
  • </filter>
  • <filter-mapping>设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
    • <filter-name>设置filter的注册名称,该值必须是在<filter>元素中声明过的过滤器的名字
    • <url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
    • <servlet-name>指定过滤器所拦截的Servlet名称(与上面的二选一)
    • <dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是以下四种方式之一,默认REQUEST。用户可以设置多个<dispatcher>子元素用来指定 Filter 对资源的多种调用方式进行拦截
      • REQUEST:当用户直接访问页面时,Web容器将会调用过滤器;若通过如下两种方法访问则不调用此过滤器
      • INCLUDE:目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用
      • FORWARD:目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用
      • ERROR:目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用

Servlet异常处理(未看)

Servlet Cookie处理

Servlet Cookie 处理需要对中文进行编码与解码,方法如下:

String str = java.net.URLEncoder.encode("中文","UTF-8");            //编码
String str = java.net.URLDecoder.decode("编码后的字符串","UTF-8");   // 解码

Cookie通常设置在HTTP头消息中,比如下方:

HTTP/1.1 200 OK
Date: Fri, 04 Feb 2000 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT; 
                 path=/; domain=runoob.com
Connection: close
Content-Type: text/html

当中,Set-Cookie 头包含了一个名称值对、一个GMT日期、一个路径和一个域。名称和值会被 URL 编码。expires 字段是一个指令,告诉浏览器在给定的时间和日期之后"忘记"该 Cookie

在浏览器这边,如果浏览器被配置为存储 Cookie,它将会保留此信息直到到期日期。如果用户的浏览器指向任何匹配该 Cookie 的路径和域的页面,它会重新发送 Cookie 到服务器。

Servlet 通过请求方法 request.getCookies() 访问 Cookie,该方法返回一个 Cookie 对象的数组

部分Servlet操作Cookie的方法列表

seq 方法 & 描述
1 public void setDomain(String pattern)
该方法设置 cookie 适用的域,例如 runoob.com。(与之对应的还有getDomain()方法取得cookie适用的域)
2 public void setMaxAge(int expiry)
该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。(与之对应的还有getMaxAge(),如果返回-1则表示cookie将持续下去直到浏览器关闭)
3 public String getName()
该方法返回 cookie 的名称。名称在创建后不能改变。
4 public void setValue(String newValue)
该方法设置与 cookie 关联的值。(与之对应的有getValue()获取与cookie关联的值)
5 public void setPath(String uri)
该方法设置 cookie 适用的路径。如果不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。
6 public void setSecure(boolean flag)
该方法设置cookie表示其是否在加密的(即 SSL)连接上发送
7 public void setComment(String purpose)
设置cookie的注释。该注释在浏览器向用户呈现 cookie 时非常有用(与之对应的getComment()可以获得cookie的注释)

删除Cookie
先获得所要删除的cookie(可以通过getName判断是否为所要的cookie),通过setMaxAge()方法将cookie的年龄设为0,将cookie添加到响应头

Servlet Session跟踪

Servlet 提供了 HttpSession 接口,而且,在向客户端发送任何文档内容之前调用 request.getSession()

一些常用方法

使用request.getSession()得到HttpSession对象,当中可以设置参数true表示如果没有创建则创建一个HttpSession对象

seq 方法 & 描述
1 public Object getAttribute(String name)
该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。(对应removeAttribute()删除指定名称的对象、setAttribute(String name, Object value)在session绑定一个对象到指定名称中)
2 public Enumeration getAttributeNames()
该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称
3 public long getCreationTime()
该方法返回该session会话被创建的时间,以毫秒为单位
4 public String getId()
该方法返回一个包含分配给该session会话的唯一标识符的字符串。
5 public long getLastAccessedTime()
该方法返回客户端最后一次发送与该 session 会话相关的请求的时间,以毫秒为单位。
6 public int getMaxInactiveInterval()
该方法返回Servlet容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位(对应setMaxInactiveInterval(int interval)设置时间)。
7 public void invalidate()
该方法指示该session会话无效,并解除绑定到它上面的任何对象
8 public boolean isNew()
如果客户端还不知道该session会话,或者如果客户选择不参入该 session 会话,则该方法返回 true

删除Session会话数据

  • 移出特定属性:removeAttribute(String name)
  • 删除整个session会话:invalidate()
  • 设置会话过期时间:setMaxInactiveInterval(int interval)
  • web.xml配置(使用Tomcat时)
<session-config>
    <session-timeout>15</session-timeout>       Tomcat默认为30min,但此处可以覆盖
</session-config>

Servlet网页重定向

使用如下方法

public void HttpServletResponse.sendRedirect(String location) throws IOException

也可以通过 setStatus() 和 setHeader() 达到一个效果

String site = "www.a.com";
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", site); 

原本的URL访问http://abc.com/本servlet过滤器后,URL会变成www.a.com

Servlet点击计数器

步骤如下:

  • 在 init() 方法中初始化一个全局变量
  • 每次调用 doGet() 或 doPost() 方法时,都增加全局变量
  • 如果需要,使用一个数据库表来存储全局变量的值在 destroy()中。在下次初始化 Servlet 时,该值可在 init() 方法内被读取
  • 如果只想对一个 session 会话计数一次页面点击,那么使用 isNew() 检查该 session 会话是否已点击过相同页面

Servlet自动刷新页面

比如股票市场等,都需要自动刷新页面

Servlet中,使用此函数

public void setIntHeader(String header, int headerValue)
此方法把头信息 "Refresh" 连同一个表示时间间隔的整数值headerValue(以秒为单位)发送回浏览器

Servlet包

涉及到 WEB-INF 子目录的 Web 应用程序结构是所有的 Java web 应用程序的标准,并由 Servlet API 规范指定。给定一个顶级目录名 myapp,目录结构如下所示:

/myapp
    /images
    /WEB-INF
        /classes                包含了所有的Servlet类和其他类文件
        /lib

WEB-INF 子目录中包含应用程序的部署描述符(即web.xml)。所有的 HTML 文件都位于顶级目录 myapp 下。对于 admin 用户,会发现 ROOT 目录是 myApp 的父目录

WEB-INF/classes 目录包含了所有的Servlet类和其他类文件,类文件所在的目录结构与他们的包名称匹配。例如,如果有一个完全合格的类名称 com.myorg.MyServlet,那么这个 Servlet 类必须位于以下目录中:

/myapp/WEB-INF/classes/com/myorg/MyServlet.class

Servlet调试

  • println()
  • 消息日志(log4J)
  • log()——Servlet API提供的简单输出信息的方式,记录在Servlet容器的日志文件中,例子如下
ServletContext context = getServletContext( );

if (par == null || par.equals(""))
    context.log("No message received:",
      new IllegalStateException("Missing parameter"));  // 通过 Throwable 参数记录版本
else
    context.log("Here is the visitor's message: " + par);
  • 查看原始HTTP请求与相应
  • 使用注释

参考:

Servlet-菜鸟教程
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,591评论 18 139
  • 本文包括:1、Filter简介2、Filter是如何实现拦截的?3、Filter开发入门4、Filter的生命周期...
    廖少少阅读 7,247评论 3 56
  • 这部分主要是与Java Web和Web Service相关的面试题。 96、阐述Servlet和CGI的区别? 答...
    杂货铺老板阅读 1,397评论 0 10
  • “仅以此片献给最珍贵的你”最后一句话已经出现在大屏幕了,可是所有的人都还是不舍得走,直到整个屏幕黑下来,才缓缓擦去...
    恣岑呀阅读 1,380评论 3 9
  • 人就是这么贱,在的时候嫌唠叨,不在的时候又想念。 今天老爸出远门,清明回去的时候老爸说这说那,总觉得烦。可是他现在...
    傻小子97阅读 193评论 0 0