首页 > 网站 > WEB开发 > 正文

servlet学习笔记(一)

2024-04-27 15:07:10
字体:
来源:转载
供稿:网友

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(过时)


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表