servlet介绍(2)-----虚拟类GenericServlet

本文详细介绍了Servlet的基本概念,包括GenericServlet和HttpServlet两个核心类。解释了它们如何实现Servlet接口及其实现细节,如初始化过程、日志记录方法等。并通过示例展示了如何使用这些类来创建简单的Web应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2GenericServlet

GenericServlet实现了Serializable, Servlet, ServletConfig这三个接口,还有一个不带参数的init方法和两个参数不同的log方法。

实现了Serializable接口,表示其实可以被序列化的,也就是说可以在特定的情况下被写到磁盘或者通过网络传输。

Servelt接口中的方法已经在上面介绍过了。

那我们来看看ServletConfig这个接口

String getInitParameter(String name)

Enumeration getInitParameterNames()

这两个方法是用来获取初始化参数的,初始参数在web.xml中的<servlet></servlet>块中田间添加。

ServletContext getServletContext()这个方法返回一个实现了ServletContext的类的对象,ServletContext对象就是Servlet运行时候的上下文(简单说就是这个对象提供了与Servlet容器交互的几个方法)

String getServletName()返回此Servlet的名字。

 

接下来看新添加的3个方法

void init() throws ServletException

这个方法是在void init(ServletConfig config)中被调用的,所以我们以后如果想在servlet初始化的时候做一些事情的话,可以直接覆盖这个方法就可以了。而且覆盖这个方法时,我们不需要先调用super.init();这个也很好解释为什么我们一般不应该在void init(ServletConfig config)中做一些初始化动作,为了证实这点我们可以看一下GenericServlet的源码,GenericServlet中没关系的代码已经去掉

 

public   abstract   class  GenericServlet  implements  Servlet, ServletConfig,

              Serializable

{

 

       
private transient ServletConfig config;

 

       
public ServletConfig getServletConfig()

       
{

              
return config;

       }


 

       
public void init(ServletConfig config) throws ServletException

       
{

              
this.config = config;

              init();

       }


 

       
public void init() throws ServletException

       
{

       }


}


 

可以很清楚的看到void init(ServletConfig config)唯一做的两件事情:

a)       用一个成员变量private transient ServletConfig config;来保存了参数中config的值(这样我们以后需要ServletConfig对象的时候就可以使用ServletConfig getServletConfig()来取回)

b)       调用了init()方法实际上init()方法就是一个空方法。

假如我们直接去覆盖void init(ServletConfig config)的话,我们直接写我们需要初始化的东西。那么会产生的后果就是:当我们需要ServletConfig对象的时候方法的时候,我们去调用ServletConfig getServletConfig()返回的就是null。而且GenericServlet提供的其他方法中很多方法都是通过调用private transient ServletConfig config;而实现的,所以假如直接覆盖void init(ServletConfig config)可能Servlet容器的log中会出现大量的java.lang.NullPointerException。所以我们初始化的动作记得是覆盖public void init()去做而不是覆盖void init(ServletConfig config)

  

       GenericServlet的另外两个log方法

              void log(String msg)

       void log(String message, Throwable t)

顾名思义是用来记录日志的,这里就不多说了,tomcat中记录的日志存在tomcatlogs子文件夹中。

 

让我们用一个例子来结束GenericServlet的讲解

package  squall.servlet.basic;

 

import  java.io.IOException;

import  java.io.PrintWriter;

 

import  javax.servlet.GenericServlet;

import  javax.servlet.ServletException;

import  javax.servlet.ServletRequest;

import  javax.servlet.ServletResponse;

 

public   class  GenericServletTest  extends  GenericServlet

{

 

       
public void service(ServletRequest request, ServletResponse response)

                     
throws ServletException, IOException

       
{

              response.setContentType(
"text/html");

              PrintWriter out 
= response.getWriter();

              String docType 
= "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ";

              out.println(docType 
+

                            
"<HTML> " +

                            
"<HEAD><TITLE>Hello from GenericServlet!</TITLE></HEAD> " +

                            
"<BODY BGCOLOR="#FDF5E6"> " +

                            
"<H1>Hello World from  GenericServlet!</H1> " +

                            
"</BODY> " +

                            
"</HTML>");

       }


 

}


 

编译完以后部署到tomcat后,mapping/GenericServlet。访问http://127.0.0.1:8080/train/GenericServlet就可以看到

Hello World from GenericServlet!

   

    3HttpServlet

       HttpServlet类的出现使得我们写一个Web端的Servlet程序更加简单,HttpServlet中的do开头的方法分别对应于http的各种请求,比如doGet方法用来响应浏览器的GET请求。绝大多数情况下,我们只需要考虑GeTPost这两种请求,所以绝大多数情况下我们只需要实现doGetdoPost方法。(直接在浏览器中输入一个url,然后回车默认为get请求)

     写一个例子来看下使用继承HttpServlet来完成一个Servlet是怎样的。

    

package  squall.servlet.basic;

 

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  HelloServlet  extends  HttpServlet

{

       
private int times = 0;

 

       
protected void doGet(HttpServletRequest request,

                     HttpServletResponse response) 
throws ServletException, IOException

       
{

              
++times;

              response.setContentType(
"text/html");

              PrintWriter out 
= response.getWriter();

              String docType 
= "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ";

              out.println(docType 
+ "<HTML> "

                            
+ "<HEAD><TITLE>Hello</TITLE></HEAD> "

                            
+ "<BODY BGCOLOR="#FDF5E6"> " + "<H1>Hello World! " + times

                            
+ " times  from GET</H1> " + "</BODY> " + "</HTML>");

       }


 

       
protected void doPost(HttpServletRequest request,

                     HttpServletResponse response) 
throws ServletException, IOException

       
{

              response.setContentType(
"text/html");

              PrintWriter out 
= response.getWriter();

              String docType 
= "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ";

              out.println(docType 
+ "<HTML> "

                            
+ "<HEAD><TITLE>Hello</TITLE></HEAD> "

                            
+ "<BODY BGCOLOR="#FDF5E6"> " + "<H1>Hello World! " + times

                            
+ " times from POST</H1> " + "</BODY> " + "</HTML>");

       }


 

}


 

    编译完成以后部署到tomcatmappingHelloServlet

    然后访问http://127.0.0.1:8080/train/HelloServlet

会看到

Hello World! 1 times from GET

       可以看到直接输入url对应于get请求。刷新后可以看到times前面的数字在增加。其原因doGet方法每次会将servlet对象的成员变量times1。当然这里只是举了一个例子。一般我们的项目很少是真的需要为一个servlet对象添加一个成员变量来实现某种需求(一般是设计上的问题引起的)

    Servlet的成员变量被这个运行在Servlet对象上所有的线程所共享,假如想一个Servlet对象上只运行一个线程的话。需要让让servlet实现SingleThreadModel,但注意这个接口没有任何方法,并且是不推荐的。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值