servlet学习笔记(一)

来源:互联网 发布:淘宝卖家关闭花呗支付 编辑:程序博客网 时间:2024/05/16 12:21

SERVLET入门(一)


参考:http://www.cnblogs.com/xdp-gacl/p/3760336.html
这个博主的知识点写的非常棒而且细致,推荐新手入门的大家直接过去充能~

一.什么是servlet


servlet是按照servlet规范编写的java类。它运行于支持java的应用服务器中,主要用于响应web(HTTP)方面的请求。

二.servlet的作用


servlet在服务器端运行,主要用于处理客户端的请求。
web服务器习惯于处理静态页面,对于动态请求,一般交由一个帮助程序进行处理,再将处理后的静态页面返回给web服务器。servlet就是这样的帮助程序。通常由浏览器向web容器发送HTTP请求,根据web容器中的web.xml文件,决定由具体的某个servlet来对其进行处理。

三.servlet生命周期


servlet生命周期指的是,从创建servlet实例后,servlet存在到销毁的整个过程。
生命周期中主要有以下几个阶段:
1.实例化。servlet容器加载servlet类,并将.class 文件读取到内存中,由servlet容器创建一个servlet实例。
2.初始化。servlet容器调用init()函数完成参数的初始化。
3.运行。当servlet容器接收到请求时,会根据请求创建ServletRequest和ServletResponse对象,并将其传递给调用的service()方法。service()方法通过request获取请求的内容,并对其进行处理,将请求的结果封装在response中。每个请求均在独立的线程中运行。
4.销毁。servlet容器调用destroy()方法,销毁servlet对象,并释放它占用的资源。

在一个生命周期中,init()方法和destroy()方法都只会被调用一次。而service方法执行的次数则取决于被客户端访问的次数。

四.使用MyEclipse建立一个基础的servlet


1.新建一个web-project,生成的目录如下:
web-project

2.在src目录下,新建一个servlet文件
新建servlet1
新建servlet2
新建servlet3

那么,自动生成的servlet文件和在web.xml文件中的配置如下:
AutoServlet文件:

package com.test1;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class AutoServlet extends HttpServlet {    /**     * Constructor of the object.     */    public AutoServlet() {        super();    }    /**     * Destruction of the servlet. <br>     */    public void destroy() {        super.destroy(); // Just puts "destroy" string in log        // Put your code here    }    /**     * The doGet method of the servlet. <br>     *     * This method is called when a form has its tag value method equals to get.     *      * @param request the request send by the client to the server     * @param response the response send by the server to the client     * @throws ServletException if an error occurred     * @throws IOException if an error occurred     */    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html");        PrintWriter out = response.getWriter();        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");        out.println("<HTML>");        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");        out.println("  <BODY>");        out.print("    This is ");        out.print(this.getClass());        out.println(", using the GET method");        out.println("  </BODY>");        out.println("</HTML>");        out.flush();        out.close();    }    /**     * The doPost method of the servlet. <br>     *     * This method is called when a form has its tag value method equals to post.     *      * @param request the request send by the client to the server     * @param response the response send by the server to the client     * @throws ServletException if an error occurred     * @throws IOException if an error occurred     */    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html");        PrintWriter out = response.getWriter();        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");        out.println("<HTML>");        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");        out.println("  <BODY>");        out.print("    This is ");        out.print(this.getClass());        out.println(", using the POST method");        out.println("  </BODY>");        out.println("</HTML>");        out.flush();        out.close();    }    /**     * Initialization of the servlet. <br>     *     * @throws ServletException if an error occurs     */    public void init() throws ServletException {        // Put your code here    }}

对于每一个具体的程序块的用途,MyEclipse自动生成时都附上了详细的注释。

web.xml文件:

<?xml version="1.0" encoding="UTF-8"?><web-app version="3.0"     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">  <display-name></display-name>  <servlet>    <description>This is the description of my J2EE component</description>    <display-name>This is the display name of my J2EE component</display-name>    <servlet-name>AutoServlet</servlet-name>    <servlet-class>com.test1.AutoServlet</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>AutoServlet</servlet-name>    <url-pattern>/servlet/AutoServlet</url-pattern>  </servlet-mapping>      <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list></web-app>

主要看<servlet></servlet><servlet-mapping></servlet-mapping> 这两对标签中的内容。在这里,配置了对特定servlet文件的映射关系。

注意:
(1)两个servlet-name必选相同;
(2)默认的url-pattern为:/servlet/servlet-name


接下来,将这个web-project部署到tomcat上,启动tomcat后,就可以在网页上访问这个servlet了。
网页访问servlet

访问的地址为:
http://localhost:8080/servlet-test/servlet/AutoServlet
也就是:"http://localhost:8080/" + web项目名称+web.xml中配置的url-pattern


五.其他细节

1.servlet的url映射配置

由于客户端是根据url来访问web中的资源,因此,要想访问一个servlet,就要把它映射到一个url地址上,这个工作,在web.xml中,由<servlet></servlet><servlet-mapping></servlet-mapping> 这两对标签来完成。
<servlet></servlet> 标签用于注册servlet,其中,servlet-name是servlet的名称,servlet-class中写servlet所在的完整类名。
<servlet-mapping></servlet-mapping> 标签用于映射一个已注册的servlet和它的对外访问路径。一个注册的servlet可以有多个访问路径。
如:

  <servlet>    <description>This is the description of my J2EE component</description>    <display-name>This is the display name of my J2EE component</display-name>    <servlet-name>AutoServlet</servlet-name>    <servlet-class>com.test1.AutoServlet</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>AutoServlet</servlet-name>    <url-pattern>/servlet/AutoServlet</url-pattern>  </servlet-mapping>      <servlet-mapping>      <servlet-name>AutoServlet</servlet-name>      <url-pattern>/1.html</url-pattern>  </servlet-mapping>  <servlet-mapping>      <servlet-name>AutoServlet</servlet-name>      <url-pattern>/2.jsp</url-pattern>  </servlet-mapping>  <servlet-mapping>      <servlet-name>AutoServlet</servlet-name>      <url-pattern>/3.php</url-pattern>  </servlet-mapping>  <servlet-mapping>      <servlet-name>AutoServlet</servlet-name>      <url-pattern>/4.ASPX</url-pattern>  </servlet-mapping>

那么,使用地址:
http://localhost:8080/servlet-test/servlet/AutoServlet
http://localhost:8080/servlet-test/1.html
http://localhost:8080/servlet-test/2.jsp
http://localhost:8080/servlet-test/3.php
http://localhost:8080/servlet-test/4.ASPX
都可以访问同一servlet。


此外,还可以使用*通配符来匹配映射的url地址。
使用通配符时,只有两种固定格式:
1.使用*.扩展名
2.使用正斜杠(/)开头,并以/*结尾。
如: 对于上述例子中的servlet,在web.xml中配置

  <servlet-mapping>    <servlet-name>AutoServlet</servlet-name>    <url-pattern>/servlet/AutoServlet</url-pattern>  </servlet-mapping>      <servlet-mapping>      <servlet-name>AutoServlet</servlet-name>      <url-pattern>/find/*</url-pattern>  </servlet-mapping>  <servlet-mapping>      <servlet-name>AutoServlet</servlet-name>      <url-pattern>*.do</url-pattern>  </servlet-mapping>

那么,就可以使用:
http://localhost:8080/servlet-test/find/aabbcc
或:
http://localhost:8080/servlet-test/aabbcc.do
来访问上述servlet
(aabbcc可以由任意字符串代替)

对于多个注册的servlet都使用了通配符的情况,在映射过程中,遵循那个更相似,就匹配到哪一个的原则

2.<load-on-startup>标签

根据上面的知识点,可以知道,在处理客户端的servlet请求时,首先需要有一个servlet实例。对于多次请求,仅创建一个实例,调用一次init()方法。每次请求过程中,servlet引擎将创建新的HttpServletRequest请求对象和HttpServletResponse响应对象,并将其作为参数传递给service(),service()再根据请求的内容,调用响应的doXXX方法,对请求进行处理。
在web.xml中配置<load-on-startup>,那么,在web应用启动时,就会装载并实例化servlet,并调用实例对象的init()方法。

  <servlet>    <description>This is the description of my J2EE component</description>    <display-name>This is the display name of my J2EE component</display-name>    <servlet-name>AutoServlet</servlet-name>    <servlet-class>com.test1.AutoServlet</servlet-class>    <load-on-startup>1</load-on-startup>  </servlet>

标签中的数字,用于标记容器是否在启动时就加载这个servlet,以及加载的优先级。
当数字为负数或是无指定值时,容器只在该servlet被选择是才对它进行加载。
当数字为非负数是,表示容器在启动时就加载这个servlet。数字越小,启动这个servlet的优先级越高(如:0的优先级大于1)

3.缺省的servlet

当一个servlet的访问路径(url-pattern)配置为一个正斜杠(/)时,这个servlet就称为web容器的缺省servlet。
即,凡是找不到对应的<servlet-mapping></servlet-mapping>的url请求,都将访问该缺省servlet。

4.servlet线程安全

当多个客户端并发访问一个servlet时,web服务器就会为每一个访问创建一个线程,每个线程分别调用servlet实例的service()方法。如果多个service()方法同时访问同一个资源,就会导致线程安全问题。
线程安全问题只存在多个线程并发操作同一个资源的情况下,所以在编写Servlet的时候,如果并发访问某一个资源(变量,集合等),就会存在线程安全问题。
就之前学过的java基础部分的知识点而言,可以使用线程锁synchronized来解决线程问题.即,将可能产生线程安全问题的程序块写在

synchronized(this) {    ....}

中。当有线程访问该资源时,它就拿到了这把锁。那么,如果有并发的线程同时访问该资源,就必须等待上一个线程访问完毕,将锁释放出来。
但是,在实际的应用中,使用servlet时,不可以使用该方式。针对线程安全问题,在servlet2.4之前,采用的方法是,让servlet继承Sun公司提供的标记接口:SingleThreadModel,这样,这个servlet无论何时,都将单线程运行。
需要注意的是,这种方法的实质是产生多个Servlet实例对象,每个并发的线程分别对应一个实例对象。因此,这种方法并没有真正解决多并发的线程安全性问题,在servlet2.4以后,已被标记为deprecated(过时)

0 0
原创粉丝点击