javaWEB总结(8):自定义GenericServlet

前言:

项目的实际应用中,我们往往为了方便去继承GenericServlet类,而不是去实现Servlet接口,是什么原因呢?下面进行简单的实践操作。

一. 准备工作


1.首先看GenericServlet的API:

GenericServlet

javax.servlet
Class GenericServlet

All Implemented Interfaces:
Serializable,Servlet,ServletConfig
Direct Known Subclasses:

HttpServlet

Method Summary
 void destroy()
          Called by the servlet container to indicate to a servlet that the servlet is being taken out of service.
 String getInitParameter(String name)
          Returns a String containing the value of the named initialization parameter, ornull if the parameter does not exist.
 Enumeration getInitParameterNames()
          Returns the names of the servlet's initialization parameters as an Enumeration of String objects, or an empty Enumeration if the servlet has no initialization parameters.
 ServletConfig getServletConfig()
          Returns this servlet's ServletConfig object.
 ServletContext getServletContext()
          Returns a reference to the ServletContext in which this servlet is running.
 String getServletInfo()
          Returns information about the servlet, such as author, version, and copyright.
 String getServletName()
          Returns the name of this servlet instance.
 void init()
          A convenience method which can be overridden so that there's no need to callsuper.init(config).
 void init(ServletConfig config)
          Called by the servlet container to indicate to a servlet that the servlet is being placed into service.
 void log(String msg)
          Writes the specified message to a servlet log file, prepended by the servlet's name.
 void log(String message,Throwable t)
          Writes an explanatory message and a stack trace for a given Throwable exception to the servlet log file, prepended by the servlet's name.
abstract  void service(ServletRequest req,ServletResponse res)
          Called by the servlet container to allow the servlet to respond to a request.

可以看出:GenericServlet共有两个实现类Servlet和ServletConfig,还有一个子类HttpServlet.


二. 项目实践


实验目标:在web.xml中分别定义当前web应用的参数和当前servlet的参数,并在java类当中获取,控制台中打印出来。


2.1 只实现servlet的方式:


(a)项目目录结构:



(b)web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>javaWeb_08</display-name>
    
    <!-- 当前web应用的参数 -->
    <context-param>
    	<param-name>user1</param-name>    
    	<param-value>admin</param-value>
    </context-param>
    <context-param>
    	<param-name>password1</param-name>
    	<param-value>123456</param-value>
    </context-param>
    
    <servlet>
        <!-- 当前servlet的参数 -->
        <init-param>
            <param-name>user2</param-name>
            <param-value>admin</param-value>
        </init-param>
        <init-param>
            <param-name>password2</param-name>
            <param-value>123456</param-value>
        </init-param>
        
        <servlet-name>MyGenericServlet</servlet-name>
        <servlet-class>com.dao.chu.MyGenericServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>MyGenericServlet</servlet-name>
        <url-pattern>/MyGenericServlet</url-pattern>
    </servlet-mapping>
    
</web-app>

(c) MyGenericServlet.java

package com.dao.chu;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 
* <p>Title: MyGenericServlet</p>
* <p>Description: 自定义MyGenericServlet</p>
 */
public class MyGenericServlet implements Servlet{
	
	
	//ServletConfig对象,在init方法执行后赋值
	private ServletConfig servletConfig;

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	//ServletConfig对象的get方法
	@Override
	public ServletConfig getServletConfig() {
		return servletConfig;
	}

	@Override
	public String getServletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		
		System.out.println("init...");
		this.servletConfig=servletConfig;
		
	}

	@Override
	public void service(ServletRequest servletRequest, ServletResponse servletResponse)
			throws ServletException, IOException {
		
		//得到servletContext对象
		ServletContext servletContext = servletConfig.getServletContext();
		
		//当前web应用的参数
		String user1 = servletContext.getInitParameter("user1");
		String password1 = servletContext.getInitParameter("password1");
		
		String user2 = servletConfig.getInitParameter("user2");
		String password2 = servletConfig.getInitParameter("password2");
		
		
		System.out.println("user1 is: "+user1);
		System.out.println("passwrod1 is: "+password1);
		System.out.println("user2 is: "+user2);
		System.out.println("passwrod2 is: "+password2);
	}

	

}

(d) 运行结果

e)小结:我们首先需要获取servletConfig对象,而servletConfig对象在init方法中,方法却写在service方法中,所以我们定义了私有的servletConfig对象,并在init方法中把参数传给我们定义的servletConfig对象,写好servletConfig的get方法。



2.2 将MyGenericServlet作为父类,其他类来继承这个类


(a)项目结构:

(b) web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>javaWeb_08</display-name>
    
    <!-- 当前web应用的参数 -->
    <context-param>
    	<param-name>user1</param-name>    
    	<param-value>admin</param-value>
    </context-param>
    <context-param>
    	<param-name>password1</param-name>
    	<param-value>123456</param-value>
    </context-param>
    
    <servlet>
        <!-- 当前servlet的参数 -->
        <init-param>
            <param-name>user2</param-name>
            <param-value>admin</param-value>
        </init-param>
        <init-param>
            <param-name>password2</param-name>
            <param-value>123456</param-value>
        </init-param>
        
        <servlet-name>myGenericServletExtends</servlet-name>
        <servlet-class>com.dao.chu.MyGenericServletExtends</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>myGenericServletExtends</servlet-name>
        <url-pattern>/myGenericServletExtends</url-pattern>
    </servlet-mapping>
    
</web-app>

(c) MyGenericServlet

package com.dao.chu;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 
* <p>Title: MyGenericServlet</p>
* <p>Description: 自定义MyGenericServlet</p>
 */
public abstract class MyGenericServlet implements Servlet{
	
	
	//ServletConfig对象,在init方法执行后赋值
	private ServletConfig servletConfig;

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	//ServletConfig对象的get方法
	@Override
	public ServletConfig getServletConfig() {
		return servletConfig;
	}

	@Override
	public String getServletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		
		System.out.println("init...");
		this.servletConfig=servletConfig;
		
	}

	/**
	 * 抽象方法,必需被子类实现
	 */
	@Override
	public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse);

}

(d) MyGenericServletExtends

package com.dao.chu;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 
* <p>Title: MyGenericServletExtends</p>
* <p>Description: MyGenericServlet的子类</p>
 */
public class MyGenericServletExtends extends MyGenericServlet{

	@Override
	public void service(ServletRequest srvletRequest,
			ServletResponse servletResponse) {
		
		String user1 = getServletConfig().getServletContext().getInitParameter("user1");
		String password1 = getServletConfig().getServletContext().getInitParameter("password1");
		
		
		String user2 = getServletConfig().getInitParameter("user2");
		String password2 = getServletConfig().getInitParameter("password2");
		
		
		System.out.println("user1:"+user1);
		System.out.println("user2:"+user2);
		System.out.println("password1:"+password1);
		System.out.println("password2:"+password2);
		
	}

}

(e) 运行结果:

f)小结:我们大多的业务操作都在service里面,虽然servlet当中的方法很多,也不需要所有都去实现,我们定义的MyGenericServlet只需让他的子类必需实现service方法就可以,所以MyGenericServlet定义为抽象类,service方法定义为抽象方法。


2.3 和API中一致,加入实现ServletConfig

(a) 目录结构:

b)web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>javaWeb_08</display-name>
    
    <!-- 当前web应用的参数 -->
    <context-param>
    	<param-name>user1</param-name>    
    	<param-value>admin</param-value>
    </context-param>
    <context-param>
    	<param-name>password1</param-name>
    	<param-value>123456</param-value>
    </context-param>
    
    <servlet>
        <!-- 当前servlet的参数 -->
        <init-param>
            <param-name>user2</param-name>
            <param-value>admin</param-value>
        </init-param>
        <init-param>
            <param-name>password2</param-name>
            <param-value>123456</param-value>
        </init-param>
        
        <servlet-name>myGenericServletExtends</servlet-name>
        <servlet-class>com.dao.chu.MyGenericServletExtends</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>myGenericServletExtends</servlet-name>
        <url-pattern>/myGenericServletExtends</url-pattern>
    </servlet-mapping>
    
</web-app>

(c) MyGenericServlet

package com.dao.chu;

import java.util.Enumeration;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 
* <p>Title: MyGenericServlet</p>
* <p>Description: 自定义MyGenericServlet</p>
 */
public abstract class MyGenericServlet implements Servlet,ServletConfig{
	
	
	//ServletConfig对象,在init方法执行后赋值
	private ServletConfig servletConfig;

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	//ServletConfig对象的get方法
	@Override
	public ServletConfig getServletConfig() {
		return servletConfig;
	}

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		
		System.out.println("init...");
		this.servletConfig=servletConfig;
		
	}

	/**
	 * 抽象方法,必需被子类实现
	 */
	@Override
	public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse);
	
	
	
	//实现ServletConfig的方法
	@Override
	public String getServletName() {
		return getServletConfig().getServletName();
	}

	@Override
	public ServletContext getServletContext() {
		return getServletConfig().getServletContext();
	}

	@Override
	public String getInitParameter(String paramString) {
		return getServletConfig().getInitParameter(paramString);
	}

	@Override
	public Enumeration<String> getInitParameterNames() {
		return getServletConfig().getInitParameterNames();
	}

}

(d) MyGenericServletExtends

package com.dao.chu;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 
* <p>Title: MyGenericServletExtends</p>
* <p>Description: MyGenericServlet的子类</p>
 */
public class MyGenericServletExtends extends MyGenericServlet{

	@Override
	public void service(ServletRequest srvletRequest,
			ServletResponse servletResponse) {
		
		String user1 = getServletContext().getInitParameter("user1");
		String password1 = getServletContext().getInitParameter("password1");
		
		
		String user2 = getInitParameter("user2");
		String password2 = getInitParameter("password2");
		
		
		System.out.println("user1:"+user1);
		System.out.println("user2:"+user2);
		System.out.println("password1:"+password1);
		System.out.println("password2:"+password2);
		
	}

}

(e) 控制台输出:


(f)小结:我们已经得到了servletConfig对象,又实现了servletConfig的接口,所以可以直接调用里面的方法,代码也变得更加简洁。


三 为了防止子类覆盖MyGenericServlet中init(ServletConfig servletConfig)的方法出现的错误,自定义MyGenericServlet修改如下:

package com.dao.chu;

import java.util.Enumeration;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 
 * <p>
 * Title: MyGenericServlet
 * </p>
 * <p>
 * Description: 自定义MyGenericServlet
 * </p>
 */
public abstract class MyGenericServlet implements Servlet, ServletConfig {

	// ServletConfig对象,在init方法执行后赋值
	private ServletConfig servletConfig;
	
	/**
	 * 实现Servlet的方法
	 */

	@Override
	public void destroy() {

	}

	@Override
	public String getServletInfo() {
		return "";
	}
	
	// ServletConfig对象的get方法
	@Override
	public ServletConfig getServletConfig() {
		return servletConfig;
	}

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {

		this.servletConfig = servletConfig;
		init();

	}

	// 空的init函数,用来给子类继承,防止覆盖init(ServletConfig servletConfig)方法引起的错误
	public void init() {

	}

	//抽象方法,必需被子类实现
	@Override
	public abstract void service(ServletRequest servletRequest,
			ServletResponse servletResponse);

	/**
	 * 实现ServletConfig的方法
	 */
	
	@Override
	public String getServletName() {
		return getServletConfig().getServletName();
	}

	@Override
	public ServletContext getServletContext() {
		return getServletConfig().getServletContext();
	}

	@Override
	public String getInitParameter(String paramString) {
		return getServletConfig().getInitParameter(paramString);
	}

	@Override
	public Enumeration<String> getInitParameterNames() {
		return getServletConfig().getInitParameterNames();
	}

}

基本还原API中的一些方法。


附:

本次项目代码:点击打开链接

     


posted on 2016-11-19 22:58  不以物喜,不已己悲  阅读(141)  评论(0)    收藏  举报

导航