前言:
项目的实际应用中,我们往往为了方便去继承GenericServlet类,而不是去实现Servlet接口,是什么原因呢?下面进行简单的实践操作。
一. 准备工作
1.首先看GenericServlet的API:
GenericServlet
javax.servlet
Class GenericServlet
-
All Implemented Interfaces:
- Serializable, Servlet, ServletConfig
-
Direct Known Subclasses:
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 call super.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中的一些方法。
附:
本次项目代码:点击打开链接