Java之Servlet

一、servlet的相关概念

1、Servlet

(1)Servlet,服务器端的小程序,它是相对于Applet而言的,Applet是客户端小程序。

(2)Servlet,是接受来自网络的请求(form表单,以及其他的请求),并对不同请求作出不同的响应

(3)Servlet,是基于Http协议的,是运行在web服务器中的程序。这里要提出一个容器的概念。

(4)servlet是运行在web容器中,在后面会详细地讲解,这个web容器可以控制Servlet对象的生命周期,

 控制请求由Servlet对象处理。

 

2、web服务器,

这里的服务器不是硬件概念,而是软件,常用的web服务器有 Tomcat,Jboss等,

我们所用到的Tomcat是一个开源的服务器,Tomcat是一个用java语言编写的web服务器,

所以需要有相应的java运行环境,也就是JVM,还要配置tomcat的具体路径。

二、Tomcat

1、Tomcat的配置

(1)JAVA_HOME=/XXX/XXX/(JDK路径,bin的上一层目录)

(2)CATALINA_HOME=/XXXX/XXX(tomcat的绝对路径 windows中 X:\xxx\xxx)

2、Tomcat的启动与停止

(1)启动:

1)在启动Tomcat时,是运行Tomcat的bin目录下的startup.sh(windows中使用startup.bat)

2)或者在终端Tomcat的bin目录下敲命令:catalina.sh run,servlet的执行过程也会在终端显示。

(2)判断Tomcat是否启动成功

可以在浏览器的地址栏中使用http://localhost:8080/或http://127.0.0.1:8080/

可以访问到tomcat的主页就是启动成功了。

注释:

http://127.0.0.1:8080/tomcat-docs

http://127.0.0.1:8080/tomcat-docs/index.html

127.0.0.1 - serverip             

8080 - server port  

/tomcat-docs - application virtual path

/  - application virtual path

/index.html - resource virtual path

(3)停止:

要想停止tomcat服务器要使用shutdown.sh(windows中使用shutdown.bat),

如果直接关闭启动窗口,就会造成8080端口占用错误,这时可以在使用shutdown.sh关闭一下服务器。

 

3、tomcat的默认监听端口是8080端口,当接受到每一个连接请求,就会为其分配一个线程。

  

4、Tomcat的目录结构:

(1)tomcat可以识别的资源只有在webapps文件夹下,webapps也就是web应用文件夹,

         webapps下的文件夹这些文件夹中存放的就是web应用,web应用是有格式规范的,

       每个web应用的文件夹下都要有

(2)每个web应用文件都要有WEB-INF文件夹。

(3)WEB-INF文件夹下有classes,和lib文件夹,以及一个web.xml文件。

   

 

(4)访问应用时,在端口号后加上web应用文件夹的名字

http://127.0.0.1:8080/***/***.html。

注意:使用完有限的资源要进行释放。

tomcat中配置了root缺省应用,也就是在不指定的情况下会默认访问这个应用。

三、servlet程序

1、编写Servlet程序的步骤

(1)写一个类,继承于javax.servlet.http.HttpServlet

(2)覆盖方法doGet/doPost

(3)编译

(4)部署

1)将雷放到应用的WEB-INF/classes下

2)修改WEB-INF/web.xml,为Servlet配置一个虚拟路径

2、Servlet的API在E:\apache-tomcat-5.5.20\webapps\tomcat-docs目录下

   Servlet的jar包在E:\apache-tomcat-5.5.20\common\lib目录下

3、实现Servlet接口

所有的Servlet必须实现Servlet接口,并提供方法的实现:

(1) init(生命周期的回调方法)

初始化方法,会自动被服务器调用。

(2)service(生命周期的回调方法)

服务方法,是Servlet的核心方法,会自动被服务器调用。

(3)destroy(生命周期的回调方法)

销毁方法,会自动被服务器调用。

(4)getServletConfig()

返回一个描述性的字符串,类似于Object的toString()

(5)getServletInfo()

返回一个ServletConfig对象,这个对象通常是 init方法中传入的对象。

 注意:

 其中init,service,destroy会被系统调用

        getServletConfig(),getServletInfo()为辅助方法

4、继承GenericServlet

(1)开发Servlet的时候,不必直接实现Servlet接口,可以继承GenericServlet,因为它实现了Servlet接口,并提供了init,destroy,getServletConfig,getServletInfo方法的通用的实现。

(2)只要覆盖service方法即可

5、继承HttpServlet

(1)HttpServlet继承抽象类javax.servlet.GenericServlet,实现接口java.io.Serializable;

用以开发Http协议为基础的Servlet

只要覆盖doGet()和doPost()方法即可

1)doGet():用来处理get请求

2)doPost():用来处理post请求

(2)请求:

1)get:

·直接在地址栏输入路径的请求

·使用超链接<a href="url"></a>

·使用form表单以get方式发送请求

           <form method="get"></form>

2)post:

1)post请求不会把要发送的参数显示在地址栏上。

2)使用form表单以post方式发送请求

    <form method="post"></form>

四、配置文件 web.xml

 

五、Servlet生命周期

 

1、生命周期

(1)通过web Container装载(J2EE的组件都是被动地装载入Container)并实例化Servlet对象,

第一次请求时才会创建(默认)

(2)调用init()方法(在整个生命周期中只被调用一次)

(3) 调用service()方法(在整个生命周期中可被调用多次)

(4)调用destroy()方法(在整个生命周期中只被调用一次)

2、创建对象/实例:

(1)所有的Servlet必须包含一个无参的构造器,系统只调用缺省构造器来创建对象 

(2)缺省状态下,系统在需要时(第一个请求到来时)创建对象(servlet容器(tomcat)一般会在用户(浏览器)第一次请求的时候实例化对象)

这种情况可以改变:

在web.xml中增加<load-on-startup>标签

  <servlet>

    <servlet-name>LifeCycleServlet1</servlet-name>

    <servlet-class>day02.LifeCycleServlet1</servlet-class>

    <load-on-startup>数值</load-on-startup>

  </servlet>

改变默认的装载方式,即在应用启动时创建对象

值越小越先装载,如果值相同,则随机装载。

负数:相当于没写这个标记

零和正数:启动时装载

3、初始化

(1)init

       1) 当首次创建Servlet时就会调用init方法, 而不是每个用户请求都会调用该方法。

       2) 除非被destroy方法移除,否则不能被重载;

      3) init方法一结束,servlet即可接受客户端请求;

(2)有参和无参的init方法。

    1)public void init(ServletConfig config)throws ServletException

·如果调用带参的init()方法,应该在开始调用super.init()方法,保证父类中的init()也执行

·这个ServletConfig对象是由服务器生成,也就是有系统提供的,

通过他可以获   得启动信息。ServletConfig对象和Servlet是一一对应的。

·这个方法是在Servlet创建后调用的。如果要是用到ServletConfig对象是一定要  为对象赋值。

  2)public void init()throws ServletException

      {

              .....;//覆盖了的无参的init()方法,会在Servlet创建,调用有参的init方法时

              也会被调用。

       }

  (3)初始化参数

<servlet>   

      <servlet-name>LifeCycleServlet</servlet-name>

  <servlet-class>com.tarena.serv.LifeCycleServlet</servlet-class>

      <init-param>

            <param-name>file</param-name>

            <param-value>c:/ip.log</param-value>

      </init-param>   

      <init-param> 初始化参数

            <param-name>mail</param-name> 参数名

            <param-value>[email protected]</param-value>  参数值

       </init-param>

       <load-on-startup>1</load-on-startup>

     </servlet>

     <servlet-mapping>

        <servlet-name>LifeCycleServlet</servlet-name>

        <url-pattern>/life/test</url-pattern>

     </servlet-mapping>

4、服务于客户端

·service()

1)每当服务器接收到对Servlet的请求时,服务器就会产生一个新线程, 并调用service。    

service方法检查HTTP请求类型,请相应地调用doGet、doPost、doPut、doDelete。

2)被container调用去响应(ServletResponse)来自客户端的请求(ServletRequest); 

·doGet()

·doPost()

5、销毁

destroy()

1) 服务器决定删除已经加载的Servlet实例之前将调用Servlet的destroy方法;

2) 该方法允许Servlet:

   ·关闭数据库连接;

   ·中止后台线程;

   ·将Cookie程序清单或访问计数写到磁盘以及执行其他类似的收尾工作。

六、服务器在每个阶段为Servlet提供的服务

1、实例创建阶段

      · 定位servlet类(从classes找)

       ·调用缺省构造器创建实例

       ·创建时间:如果没有<load-on-startup>标签,则在第一个请求到来的时创建,

                如果有<load-on-startup>标签,则在服务器启动时创建

2、初始化阶段

       ·创建ServletConfig对象

·调用init()方法

       ·获得通过<init-param>标签配置的初始化参数,通过ServletConfig.get

3、service阶段

       ·请求(request):客户端发往服务器的信息

       ·响应(response):服务器发往客户端的响应信息

       ·如果多个用户同时访问服务器,服务器必须载单独的线程下服务于每一个用户,即为

servlet提供线程的服务,并且在每一个线程里为用户都提供request和response。(产生

一个线程池(ThreadPool)来存放线程,不是对每一次请求都创建一个线程)

4、销毁阶段(于init相反)

 

七、Servlet的url-pattern

1、url-pattern可以使用以下三种方式

(1)确切路径匹配,也就是给出确定的路径 xxx/xxxx

(2)模糊路径匹配,也就是指给出一部分路径,xxxx/*,他会匹配确定路径,也就是xxxx/a 或者

是xxxx/b都是可以匹配的

(3)扩展名匹配,也就是会匹配扩展名,只要是扩展名相同就匹配,xxx.xxx *.xx

注意:扩展名匹配和确切路径匹配不能放在一起使用,也就是不能写成 xxxx/xxxx/xxx.xx,但是可以用*.xxx。

2、ServletRequest对象的三个返回路径的方法

(1)getContextPath()获得应用的路径,用动态获取应用路径

(2)getServletPath()获得Servlet路径,如果使用确切路径那么就会是这个Servlet配置的url-pattern。

(3)getPathInfo()使用模糊路径匹配时会返回匹配模糊部分。

注意:在html的form表单的action中,如果使用了扩展名匹配,一定要写明/xxxxx/xxx.xx,不要写成/xxxx/*.xx,在form的action中要尽量使用绝对路径,也就是要用 应用名/xxx.xx或者应用名/xxx。

八、获得参数

1、getParameter(String name)方法,可以获得form表单中指定名字的参数,多参数同名时,只取一个

2、getParameterNames(),可以获得一个迭代器Enumeration,通过这个

getParameterValues(String name)

getQueryString()

九、重定向和转发的区别:

1、原理:

(1)重定向:是一个响应对应一个请求

(2)转发:是同一个请求有多个响应

2、用途:

(1)重定向:一般用于一件事情完成后,再做另一件事

(2)转发:只是同一件事

3、相对路径与绝对路径
(1)相对路径:前面不能有“/”

(2)绝对路径:前面有“/”

   eg.

1)普通链接:

1.html

<abc>

              2.html

<bcd>

              3.html

<WEB-INF>

1.html要链接2.html:abc/2.html

2.html要链接3.html:../bcd/3.html

2)servlet链接:

1.html

<abc>

       two(servlet)

              2.html

<bcd>

              3.html

<WEB-INF>

1.html要链接2.html:abc/2.html

2.html要链接3.html:../bcd/3.html

十、Web服务器装载,执行并管理Servlet的过程

 

(1)客户向服务器发送对页面的请求。

(2)如果Servlet还没有装入,服务器就装入它。

(3)服务器把请求信息送给Servlet,给每一个请求创建一个执行的新线程

  (Java语言的线程允许同时执行多个任务。

(4)Serlvet处理这个请求,生成一个响应并传递给服务器。

(5)服务器把响应送回给客户。

十一、Session

1、会话(Session):

       指一个客户端和一个服务器之间进行的一组相关的交互,更为重要的时用户可以载这一组交互中

使用一个只属于自己的空间,即会话空间。

2、设置Sessions

(1) 创建Sessions:

HttpSession session = request.getSession(true);

// true表示如不存在则创建一个新的session

(2) 用指定名称将一个对象绑定到session:

       public void setAttribute(String name, Object value);

(3) 删除与指定名称相关的所有值:

       public void removeAttribute(String name);

(4) 返回会话中所有属性名

       public Enumeration getAttributeNames();

(5)返回指定名称对象

       public Object getAttribute(String name);

4、HttpServletRequest中的会话管理方法

(1)getRequestedSessionId()

返回随客户端请求到来的会话ID。可能与当前的会话ID相同,也可能不同。

(2)getSession(boolean isNew)

如果会话已经存在,则返回一个HttpSession,如果不存在并且isNew为true,则会新建一个HttpSession。

(3)isRequestedSessionIdFromCookie()

当前的Session ID如果是从Cookie获得,为true。

(4)isRequestedSessionIdFromURL()

当前Session ID如果是由URL获得,为true。

(5)isRequestedSessionIdValid():

如果客户端的会话ID代表的是有效会话,则返回true。否则(比如,会话过期或根本不存在),

返回false。

5、Session的生命周期

Session会在需要时创建,但是他的生命周期比Request对象要长,Session对象的生命周期

也是有限制的,如果长时间的没有访问,就会销毁掉Session对象。

(1)创建会话

HttpRequest.getSession(boolean true/false); //true 不存在就创建,false 不存在返null.

HttpRequest.getSession(); //相当于getSession(true);

(2)使用会话:保持信息:setAttribute(),getAttribute(),removeAttribute()

(3)销毁会话:session.invalidate();

<session-config>

<session-timeout>30</session-timeout> //超时时间,单位为分钟

</session-config>

Session是用户级的对象,可以通过setAttribute(String name,Object o)和getAttribute(String name)来存取数据信息。

6、实现会话跟踪的三种方式

(1) cookie

(2) URL重写

(3) 隐藏的表单段

7、使用会话的注意事项

(1)放在会话中的属性最好都实现可序列化接口(Serializable)

(2)保证当服务器重启时,可以重新获得原来的Session中的值。

(3)ServletRequest对象适用于传输大量的数据,因为其生命周期比较短,可以有效的节省内存资源。

大数据量的传输或保存不适合使用Sessin空间。

十二、Cookie

1、是一种客户端的技术,它是服务器将一部分信息保存在客户端的一个文本文件,

以后在访问同一个Web站点或域时浏览器就会毫无更改地返回该文本信息。实现跨请求服务。

每条Cookie限制为4KB。

2、一个Cookie由以下内容组成:

(1) 名称;

(2) 单个值;

(3) 一些操作属性:路径或所在域、有效期以及版本号。

3、设置Cookie

(1) 创建Cookie:

       Cookie c = new Cookie("CookieName", "CookieValue");

(2) 设置有效期:

       c.setMaxAge(int lifetime); 黙认为负值,只作用于当前会话,不能存储在磁盘上;如为0值表示删除Cookie;有效值为秒为单位。

(3) 在响应头中放置Cookie:

       response.addCookie(c);

(4) 从客户端读取Cookie:

       Cookie[] cookies = request.getCookies();

       Cookie cookie;

       for(int i=0; i<cookies.length; i++)

       {

          cookie = cookies[i];

          out.println("<tr><td>" + cookie.getName() + "</td><td>" + cookie.getValue());

       }

4、如何理解会话是基于Cookie(跟踪)的?

       当服务器产生一个新的会话对象后,在挡当前的相应的头文件自动的增加一个cookie

信息,该cookie的名字为JSESESSIONID值为会话的ID,浏览器会将cookie保存到内存空间中,

然后在以后的请求中将该cookie发送到服务器中。

   request.getSession(){

    String id = getSessionIdFromCookie(“JSESESSIONID”);

    if(id == null){

           id = getSessionIdFromURL()

    }

    if(id == null){

           session = new SessionImpl();

           response.addCookie(new Cookie(“JSESESSIONID”),session);

}else{

       session =findSessionObjectInMemery(id);

}

}

作为程序员,应该考虑如果浏览器不支持Cookie,我们的程序需要在每个URL的末尾都加:jsesionid=****,为了实现这个功能,系统提供了两个方法:

    response.encodeURL(url);

       response.encodeRedirectURL(url)

 

5、 Cookies和Sessions的比较

(1)Cookies可由用户决定是否需要, Sessions不能; 

(2) Cookies是一种装载sessionID的可能;

(3)Cookies存储在客户端, Sessions存储于服务器端;

(4) Cookies可以构造,可以由Request取出,由Response返回

       response.addCookie(c);

 

猜你喜欢

转载自ldaolong.iteye.com/blog/2145779