servlet学习

一  servlet概述

狭义的Servlet指javax.servlet包中的一个接口,而广义的Servlet则是指实现了这个接口的类。一个Servlet应用有一个或多个Servlet程序。

Jsp是在传统的HTML代码中插入java程序段(Scriplet)与jsp标记(tag).

servlet应用需要在servlet容器中运行,典型容器如Jetty、Tomcat 运行servlet应用。在一个容器中可以同时运行Servlet与静态内容。

servlet/JSP应用架构

servlet API 主要由以下几个工具包

1.javax.Servlet  其中包含Servlet和Servlet容器之间契约的类和接口

2.javax.Servlet.http 其中包含定义HTTP Servlet(采用了HTTP协议的Servlet)和Servlet容器之间契约的类和接口。

3.avax.servlet.annotation,其中包含标注Servlet、Filter、Listener的标注。它还为被标注元件定义元数据。

javax.servlet.descriptor,其中包含提供程序化登录web应用程序的配置信息的类型。


javax.Servler包中的接口

二  Servlet接口

其中的方法包括:

        1.init(ServletConfig config)  当该Servlet被一次请求时,调用该方法,此后不再调用。参数传入的是Servlet的配置信息

        2.service(ServletRequest req,ServletResponse res) 每当请求Servlet时,Servlet容器就会调用这个方法。编写代码时,假设Servlet要在这里  被请求。第一次请求Servlet时,Servlet容器调用init方法和Service方法。后续的请求将只调用Service方法。

        3.destroy() 当要销毁Servlet时,Servlet容器就会调用这个方法。当要卸载应用程序,或者当要关闭Servlet容器时,就会发生这种情况。一般会在这个方法中编写清除代码。

      4. ServletConfig getServletConfig() 这个方法会返回由Servlet容器传给init方法的ServletConfig

     5. String getServletInfo() 这个方法会返回Servlet的描述。

ServletRequest接口 封装请求数据

1. Object getAttribute(String name)  返回以name为名字的属性的值,如果不存在,返回null

2. Enumeration getAttributeNames(); 返回请求中所有可用的属性的名字。返回一个枚举集合

3. void removeAttribute(String name); 移除请求中名字为name的属性

4. void setAttribute(String key,Object val); 在请求中保存一个键值对。

5. getCharacterEncoding() 返回请求正文使用的字符编码的名字

6. int getContentLength() 以字节为单位,返回请求正文的长度。

7. String getContentType() 返回正文的MIME类型

8. ServletInputStream getInputStream()

9. BufferedReader getReader()

10.String getLocalAddr() 返回接收到请求的网络接口的IP地址。

11.String getRemoteAddr() 返回发送请求的客户端或最后一个代理服务器的IP地址

12. String getRemoteHost() 返回发送请求的客户端或者最后一个代理服务器的完整限定名

13. String getLocalName() 返回接收到请求的IP接口的主机名

14. int getLocalPort() 返回接收到请求的网络接口的IP端口号

 15. int getRemotePort() 返回发送请求的客户端或最后一个代理服务器的IP源端口。

16  String getParameter(String name) 返回请求中name参数的值,如果name参数有多个值,该方法返回值列表中的第一个值。如果请求中没有找到该参数,返回null

17 Enumeration getParameterNames() 返回请求中包含的所有的参数的名字。

18 String[] getParameterValues(String name); 返回请求中name参数所有的值

19 String getProtocal() 返回请求使用的协议的名字和版本 例如: HTTP/1.1

20. RequestDispatcher getRequestDispatcher(String path) 返回RequestDispather对象,作为path所定位的资源的封装。

21. String getServerName()  返回请求发送到服务器的主机名

 22 int getServerPort() 返回请求发送到服务器的端口号

23. setCharacterEncoding(String env) 覆盖在请求正文中所使用的字符编码的名字。(链接:http://www.jianshu.com/p/d718a5f4a850)

ServletResponse接口,用来封装响应数据

flushBuffer()             强制把任何在缓存中的内容发送到客户端

int getBufferSize()          返回实际用于响应的缓存的大小,如果没有使用缓存,这个方法返回0

String getCharacterEncoding() 返回响应中发送的正文所使用的字符编码(MIME字符集)

String getContentType()返回响应中发送的正文所使用的MIME类型

ServletOutputStream getOutputStream()

PrintWriter getWriter()

boolean isCommitted()      返回一个布尔值,指示是否已经提交了响应。

void reset()                清除在缓存中的任何数据,包括状态代码和消息报头。

void resetBuffer()          清除在缓存中的响应内容,保留状态代码和消息包头。

void setBufferSize(int size) 设置响应正文的缓存大小。

void setCharacterEncoding(String charset) 设置发送到客户端的响应的字符编码

void setContentLength(int len) 设置内容正文的长度

void setContentType(String type)  设置要发送到客户端的响应的内容类型。例如:"text/html;charset=UTF-8"

ServletConfig

Servlet容器使用ServletConfig对象在Servlet初始化期间向它传递配置信息,一个ServletConfig对象。

String getInitParameter(String name); 返回名字为name的初始化参数的值,初始化参数在web.xml配置文件中进行配置。

Enumeration getInitParameterNames()  返回Servlet所有初始化参数的名字的枚举集合。

ServletContext getServletContext() 返回Servlet上下文对象的引用。

String getServletName() 返回Servlet实例的名字,这个名字是web应用程序的部署描述符中指定。

编写一个Servlet实际上就是编写一个实现了javax.servlet.Servlet接口的类。

GenericServlet

如果要编写一个通用的Servlet,只需要从GenericServlet继承,并且实现抽象方法service();

String getInitParameter(String name)

Enumeration getInitParameterNames();

ServletContext getServletContext()

init(ServletConfig config)

HttpServlet

在绝大多数的网络应用中,都是客户端通过HTTP协议去访问服务器端的资源我们编写的Servlet也主要是应用于HTTP协议的请求和响应,为了快速开发应用于HTTP协议的Servlet类,sun公司在javax.servlet.http包中给我们提供了一个抽象类HttpServlet,它继承自GenericServlet类,用于创建适合WEB站点的HTTP Servlet

public void service(ServletRequest req,ServletResponse res);

protected void service(HttpServletRequest req,HttpServletResponse resp)

针对HTTP1.1定义的7种请求方法GET,POST,HEAD,PUT,DELETE,TRACE,OPTION,

HttpServlet提供了7个处理方法

doGet(HttpServletRequest req,HttpServletResponse resp)

doPost(HttpServletRequest req,HttpServletResponse resp)

......

当容器接受到一个针对HttpServlet对象的请求时,调用该对象中的方法顺序如下

调用公共的service()方法

在公共的service()方法中,首先将参数类型转换为HttpServletRequest和HttpServletResponse,然后调用保护的service()方法,将转换后的对象作为参数传递进去

在保护的service方法中,首先调用HttpServletRequest对象的getMethod方法,获取HTTP请求方法的名称,然后根据请求方法的类型,调用相应的doXxx()方法

HttpServletRequest

继承自javax.servlet.servletRequest,在该接口中新增的方法如下:

String getContextPath() 返回请求URI中表示请求上下文的部分,上下文路径是请求URI的开始部分

Cookie[] getCookies() 返回客户端在此次请求中发送的所有的Cookie对象

String getHeader(String name) 返回名字为name的请求报头的值

Enumeration getHeaderNames() 返回此次请求中包含的所有的报头名字的枚举集合

Enumeration getHeaders(String name) 返回名字为name的请求报头的所有值的枚举集合

String getMethod() 返回此次请求所使用的HTTP方法的名字

String getServletPath() 返回请求URI中调用Servlet的部分

HttpSession getSession() 返回和此次请求相关联的Session

HttpSession getSession(boolean create)  返回此次请求相关联的Session,如果没有给客户端分配Session,并且create参数为true,则创建一个新的Session,如果为false,此次请求没有一个有效的HttpSession,返回null

HttpServletResponse

该接口继承ServletResponse,新增的方法入下

addCookie(Cookie cookie)

addHeader(String name,String value);

boolean containsHeader(String name)

encodeRedirectURL(String url) 

使用SessionID 对于重定向的url编码,以便用于sendRedirect()方法中

encodeURL(String url)            使用SessionID 指定的url编码

sendRedirect(String location)      发送一个临时的重定向响应到客户端,让客户端访问新的url

(链接:http://www.jianshu.com/p/d718a5f4a850)



ServletConfig接口

当Servlet容器初始化Servlet时,Servlet容器会给Servlet的init方法传入一个ServletConfig对象。ServletConfig封装了通过@WebServlet注解或者部署描述符(关于@WebServlet注解和部署描述符的内容会在后面的文章中讲到)传给Servlet的配置信息。这样传入的每一条信息就叫一个初始参数。一个初始参数有key和value两个元素。可以使用getServletConfig来获取传递给Servlet的ServletConfig。

为了从Servlet内部获取到初始参数的值,要在Servlet容器传给Servlet的init方法的ServletConfig中调用getInitParameter方法。ServletConfig还提供了另一个很有用的方法:getServletContext。利用这个方法可以从Servlet内部获取ServletContext。

(链接:http://www.jianshu.com/p/136fb6bf9ed6)

4.ServletContext接口

ServletContext表示Servlet应用程序的上下文,且每一个应用程序只有一个上下文。在将一个应用程序同时部署到多个容器的分布式环境中,每台Java虚拟机上的Web应用都会有一个ServletContext对象。

通过在ServletConfig中调用getServletContext方法,可以获得ServletContext。有了ServletContext,就可以共享从应用程序中的所有资料处访问到的信息,并且可以动态注册Web对象。ServletContext将对象保存在一个内部Map中。保存在ServletContext中的对象被称作属性。


链接:http://www.jianshu.com/p/136fb6bf9ed6

Cookie

Cookie是由Web服务器保存在用户浏览器上的小文本文件,它可以包含有关用户的信息。无论何时用户链接到服务器,Web站点都可以访问cookie信息。Cookie作为HTTP  header的一部分,其传输由HTTP协议控制。此外,你还可以控制cookie的有效时间。

可以通过传递name和value两个参数给Cookie类的构造函数来创建一个cookie:

Cookie cookie = new Cookie(name, value);

创建完一个Cookie对象后,你可以使用setMaxAge方法设置maxAge属性,这个属性决定cookie何时过期。

要将cookie发送到浏览器,需要调用HttpServletResponse的add方法。

服务端若要读取浏览器提交的cookie,可以通过HttpServletRequest接口的getCookies方法,该方法返回一个Cookie数组,若没有cookies则返回null。你需要遍历整个数组来查询某个特定名称的cookie。

目前,还没有通过名称来获取cookie的方法来帮助简化工作。此外,也没有一个直接的方法来删除一个cookie,你只能创建一个同名的cookie,并将maxAge 属性设置为0,并添加到HttpServletResponse接口中,就像下面这样:

Cookie cookie = new Cookie("userName", "");

cookie.setMaxAge(0);

response.addCookie(cookie);

现在我们来编写一个使用cookie来帮助统计用户访问某一页面次数的Servlet:

package com.mc.hello;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class CookieDemoServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setCharacterEncoding("UTF-8");

response.setContentType("text/html");

PrintWriter out = response.getWriter();

int count = 0;

Cookie[] cookies = request.getCookies();

if(cookies != null) {

for (Cookie cookie : cookies) {

if(cookie.getName().equals("VisitCount")) {

count = Integer.parseInt(cookie.getValue());

break;

}

}

}

count++;

out.print("这是你第" + count + "次访问这个页面");

Cookie cookie = new Cookie("VisitCount", "" + count);

response.addCookie(cookie);

}

}

在web.xml中的配置:

cookiecom.mc.hello.CookieDemoServletcookie/cookie

在浏览器地址栏中输入http://localhost:8080/HelloWorld/cookie即可看到如下页面:

显示访问次数的页面

每刷新一次这个页面,访问次数都会增加一次。但是当我们关闭浏览器,然后再次打开浏览器,并输入这个页面的URL时,页面上显示的访问次数还是一次。这是因为我们没有设置cookie的过期时间,当我们关闭浏览器的时候cookie就过期了。这里我们将这个cookie的过期时间设置为3分钟:

Cookie cookie = new Cookie("VisitCount", "" + count);

cookie.setMaxAge(3 * 60);

response.addCookie(cookie);

这样一来,3分钟之内,无论我们是否关闭浏览器,cookie都不会过期。

Session 接口

Session是另一种记录客户状态的机制,与Cookie将客户状态保存在客户端浏览器中的形式不同,Session将客户状态保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。客户端浏览器再次访问时只需要从该Session中查找该客户的状态即可。

HttpSession接口是Java对Session机制的实现规范,它位于javax.servlet.http包中。

HttpSession对象在用户第一次访问网站的时候自动被创建,你可以通过调用HttpServletRequest的getSession方法获取该对象。getSession有两个重载方法:

HttpSession getSession()

HttpSession getSession(boolean create)

没有参数的getSession方法会返回当前的HttpSession,若当前没有,则创建一个返回。getSession(false)返回当前HttpSession,如当前会话不存在,则返回null。getSession(true)与没有参数的getSession方法一致,也是返回当前HttpSession,若当前没有,则创建一个。

可以通过HttpSession的setAttribute方法将值放入HttpSession,该方法签名如下:

void setAttribute(String name, Object value)

调用setAttribute方法时,若传入的name参数此前已经使用过,则会用新值覆盖旧值。

通过调用HttpSession的getAttribute方法可以取回之前放入的对象,该方法的签名如下:

Object getAttribute(String name)

注意,所有保存在HttpSession的数据不会被发送到客户端。

可以通过调用HttpSession的getId方法来读取Session的ID。Servlet容器为每个HttpSession生成唯一的标识,并为这个标识创建一个名为JSESSIONID的cookie。在后续的请求中,浏览器会将标识提交给服务端,这样服务器就可以识别该请求是由哪个用户发起的。

下面是几种使Session失效的方法:

在项目的部署描述文件中进行设置:

1

该Session会在最后一次访问一分钟后失效

直接在应用服务器中设置。如果是tomcat,可以在tomcat目录下conf/web.xml中找到元素,tomcat默认设置是30分钟,只要修改这个值即可。

对HttpSession调用setMaxInactiveInterval方法来设定其超时时间:

void setMaxInactiveInterval(int seconds)

对HttpSession调用invalidate方法强制使会话过期。

下面我们编写程序来创建一个Session:

package com.mc.hello;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

@WebServlet(urlPatterns = { "/mysession" })

public class SessionDemoServlet extends HttpServlet {

private static final long serialVersionUID = 36L;

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setCharacterEncoding("UTF-8");

response.setContentType("text/html");

PrintWriter out = response.getWriter();

HttpSession session = request.getSession();

session.setAttribute("name", "maconn");

Cookie[] cookies = request.getCookies();

if(cookies != null) {

for (Cookie cookie : cookies) {

out.print(cookie.getName() + " = " + session.getId());

}

}

else

out.print("no cookie");

}

}

第一次打开页面,由于之前此时还不存在Session,也就不存在JSESSIONID对应的cookie,此时网页上会显示"no cookie"。再次刷新页面,就会看到Session对应的JSESSIONID。

链接:http://www.jianshu.com/p/95849fa7be53

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

推荐阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,169评论 11 349
  • Servlet 学习笔记 一、动态网页技术发展 静态网页技术HTML: 无法进行用户交互 动态网页技术CGI: 效...
    Jane_Static阅读 422评论 0 0
  • http://blog.csdn.net/luman1991/article/details/52678559 基...
    Nic_ofh阅读 1,809评论 0 3
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • Servlet接口: Servlet主要方法: init()--ServletConfig servlet实例化后...
    cxm11阅读 720评论 0 3