servlet学习笔记(一)

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值