一. GenericServlet

   1. 前面写的 Servlet和JSP学习笔记(一) 中的实例都是通过实现Servlet接口编写的,这样存在的问题就是:你必须实现Servlet中的所有方法,而不管该方法是否包含有用的

代码。所以,在此基础上Servlet API 为我们提供了GenericServlet 抽象类。

     2. javax.servlet.GenericServlet接口 的源码如下:

package javax.servlet;

import java.io.IOException;
import java.util.Enumeration; public abstract class GenericServlet implements Servlet, ServletConfig,
java.io.Serializable { private static final long serialVersionUID = 1L; private transient ServletConfig config; public GenericServlet() {
// NOOP
}
  
    
@Override
public void destroy() {
// NOOP by default
} @Override
public String getInitParameter(String name) {
return getServletConfig().getInitParameter(name);
} @Override
public Enumeration<String> getInitParameterNames() {
return getServletConfig().getInitParameterNames();
}   /*
      为我们提供了方法获取ServletConfig实例
    */
@Override
public ServletConfig getServletConfig() {
return config;
} @Override
public ServletContext getServletContext() {
return getServletConfig().getServletContext();
} @Override
public String getServletInfo() {
return "";
} /*
  在此方法中将ServletConfig对象赋值给一个类成员变量,通过getServletConfig()获取该类级成员变量   */
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
} public void init() throws ServletException {
// NOOP by default
} public void log(String msg) {
getServletContext().log(getServletName() + ": " + msg);
} public void log(String message, Throwable t) {
getServletContext().log(getServletName() + ": " + message, t);
} @Override
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;  public String getServletName() {
return config.getServletName();
}
}

    该抽象类主要做了一下的三件事:

    ①在init方法中将ServletConfig对象赋值给一个类成员变量,通过getServletConfig()获取该类级成员变量。

    ②为Servlet接口中的方法供默认实现。

    ③ 提供方法包装ServletConfig中的方法。

  2. GenericServlet示例。

    备注:根据源码个人需求,在继承GenericServlet抽象类时,我们只需要实现service抽象方法就可以了,其他的方法GenericServlet已经帮我们做了处理。

    ① 编写Servlet 类

package com.hjj.servlet.two;

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 TestGenericServlet extends GenericServlet { @Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
String name = this.getServletConfig().getInitParameter("two");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter pw = response.getWriter();
pw.print("<html><head><head><title>测试GenericServlet</title><body> hello "+name+"</body></html>"); } }

    

    ②因为在之前的实例中我用的是注解的方式进行servlet的配置,所以在这里我使用web.xml进行配置。

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>testGenericServlet</servlet-name>
<servlet-class>com.hjj.servlet.two.TestGenericServlet</servlet-class>
<init-param>
<param-name>two</param-name>
<param-value>GenericServlet</param-value>
</init-param>
</servlet> <servlet-mapping>
<servlet-name>testGenericServlet</servlet-name>
<url-pattern>/testGenericServlet</url-pattern>
</servlet-mapping> </web-app>

  

二. Servlet中的第二个包 javax.servlet.http.* 的主要类型 

    备注:这个包中提供的HttpServlet为我们编写Servlet提供另外一种写法

public abstract class javax.servlet.http.HttpServlet
public interface javax.servlet.http.HttpServletRequest

public interface javax.servlet.http.HttpServletResponse

三.  public class javax.servlet.http.HttpServlet

  1. HttpServlet具体信息为:public abstract class HttpServlet extends  GenericServlet implements java.io.Serializable

  2.该类的部分源码如下:

    

package javax.servlet.http;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle; import javax.servlet.DispatcherType;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public abstract class HttpServlet extends GenericServlet { private static final long serialVersionUID = 1L; private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String METHOD_POST = "POST";
private static final String METHOD_PUT = "PUT";
private static final String METHOD_TRACE = "TRACE"; private static final String HEADER_IFMODSINCE = "If-Modified-Since";
private static final String HEADER_LASTMOD = "Last-Modified"; private static final String LSTRING_FILE =
"javax.servlet.http.LocalStrings";
private static ResourceBundle lStrings =
ResourceBundle.getBundle(LSTRING_FILE); public HttpServlet() {
// NOOP
} protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
} protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}   
//重载的service方法
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
} } else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp); } else if (method.equals(METHOD_POST)) {
doPost(req, resp); } else if (method.equals(METHOD_PUT)) {
doPut(req, resp); } else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp); } else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
// String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}

 //重写父类GenericServlet的service 
@Override
public void service
throws ServletException, IOException { HttpServletRequest request;
HttpServletResponse response; try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException("non-HTTP request or response");
}     
 //实际上调用上的还是上面的重载的方法:protected void service(HttpServletRequest req, HttpServletResponse resp)
     service(request, response);
  }

    //此处省略部分源码
}

  3. 该类继承了GenericServlet。重写的service方法,传递的参数依然是ServletRequest实例和ServletResponse实例。但是我们可以看到源码,它把ServletRequest和

ServletResponse两个实例分别转化为HttpServletRequest和HttpServletResponse实例。同时实现了重载了一个方法: service(HttpServletRequest req,

HttpServletResponse resp)。并且在参数类型为ServletRequest和ServletResponse的重写方法service 中调用了参数类型为HttpServletRequest 和

HttpServletResponse 的重载方法 service。service重载方法做的事情为:判断请求的类型是GET、POST、HEAD、OPTIONS、PUT、DELETE或者TRACE,然后分别调用相应

的doGet,doPost,doHead,doOptions,doPut,doDelete,doTrace方法。我们常用的请求有GET和POST,因此,我贴上去的源码只有doGet和doPut方法。基于源码的实现,我

们通过继承HttpServlet去编写一个Servlet应用程序时,只需要实现重写doGet()和doPost()方法即可。

四. 关于service重载方法传递的两个参数:HttpServletRequest和HttpServletResponse

  1. HttpServletRequest

    ① 具体信息 :public interface extends  ServletRequest

    ②HttpServletRequest表示HTTP环境中的Servlet请求。

    ③比ServletRequest接口增加的主要方法有: 

public java.lang.String getContextPath() //返回请求Servlet应用程序的URI部分。
public Cookie[] getCookies() //返回一个Cookies数组
public java.lang.String getHeader(java.lang.String name) //返回指定的HTTP 标头的值
public java.lang.String getMethod() // 返回发出这条请求的HTTP方法的名称
public java.lang.String getQueryString()//返回请求Servlet应用的URL中的查询字符串
public HttpSession getSession(boolean create) //返回与这个请求有关的session对象。如果没找到,且create为true,则创建新的session
public HttpSession getSession() //返回与这个请求有关的session对象,如果没有则创建新的session并且返回

  2. HttpServletResponse

    ①具体信息:public interface HttpServletResponse extends ServletResponse

    ②HttpServletResponse表示HTTP环境下的Servlet响应。

    ③声明的部分方法: 

public void addCookie(Cookie cookie)           //给当前的响应对象添加cookie

public void sendRedirect(java.lang.String location) throws java.io.IOException // 将浏览器重定向到指定位置
public void addHeader(java.lang.String name, java.lang.String value ) // 给当前的响应添加标头

 五. 采用继承HttpServlet编写Servlet小示例。

    1. 通过继承HttpServlet实现编写一个Servlet应用程序。
      
package com.hjj.servlet.two;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name="testHttpServlet",urlPatterns="/testHttpServlet")
public class TestHttpServlet extends HttpServlet{ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是 doGet 方法,我被调用了");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8"); PrintWriter pw = response.getWriter();
pw.println("<html><head></head><title>测试HttpServlet</title><body><center>");
pw.println("<center><h1>提交数据</h1></center>" );
pw.println("<form method='post' action='testHttpServlet'>");
pw.println("<p>姓名<input name='name' type='text '/></p>");
pw.println("<p><input value='提交' type='submit'/></p>");
pw.println("</form></center></body></html>");
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是 doPost 方法,我被调用了");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8"); String name = request.getParameter("name"); PrintWriter pw = response.getWriter();
pw.println("<html><head></head><title>测试提交数据</title><body>");
pw.println("<center><h1>");
pw.println("get提交的表单的值为:"+name);
pw.println("</h1></center></body></html>");
}
}

    2. 在浏览器中输入url:http://localhost:8080/one/testHttpServlet

      页面显示:

      

      控制台打印:

            我是 doGet 方法,我被调用了

   3. 在上一个页面的表单中输入值

      u

    提交后页面显示:

      

    控制台打印:

          我是 doPost 方法,我被调用了

  

        

service

Servlet和JSP读书笔记(二)的更多相关文章

  1. Servlet和JSP读书笔记(一)

    Java Servlet 技术,简称Servlet,是Java中用于开发web应用程序的基本技术. Servlet实际上也就是一个Java程序.一个Servlet应用程序通常包含很多Servlet.而 ...

  2. Servlet和JSP读书笔记(三)之Cookie

    一. 浏览器和服务器之间通信的简单介绍引出Cookie和Session(只是简单的简介,不包含协议方面的知识) 1.当我们在浏览器中输入一个地址后,回车后就可以看到浏览器给我们展示的漂亮页面.在这个过 ...

  3. how tomcat works 读书笔记(二)----------一个简单的servlet容器

    app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...

  4. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

  5. spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Pr ...

  6. ES6读书笔记(二)

    前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,现在为第二篇,本篇内容包括: 一.数组扩展 二.对象扩展 三.函数扩展 四.Set和Map数据结构 五.Reflect 本文 ...

  7. spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Pr ...

  8. 【记】《.net之美》之读书笔记(二) C#中的泛型

    前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...

  9. Mastering Web Application Development with AngularJS 读书笔记(二)

    第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...

随机推荐

  1. Jquery moblie中的分栏布局

    大家好,很高兴又与大家见面了,今天我要给大家展示的是自己对jquery  moblie中网格布局的理解.可能不是尽善尽美,希望大家多多体谅! 在jquery moblie中有两种布局,一种是表格布局( ...

  2. 基于visual Studio2013解决C语言竞赛题之0705矩阵转置

     题目 解决代码及点评 /* 5. 写一函数,将一个3×3的矩阵转置. */ #include <stdio.h> #include <stdlib.h> void mai ...

  3. 教程:查找内存泄漏 (JavaScript)

    本主题带领您完成使用 JavaScript 内存分析器确定并修复简单内存问题的过程.在本教程中,我们创建一个生成大量数据的应用程序.我们预期在导航到新页时该应用程序会释放数据.  说明 JavaScr ...

  4. hibernate笔记(一)

    一.主配置文件hibernate.cfg.xml 位置:放在src目录下. 主要包含信息: 一.数据库信息    数据库方言(类的全名) 及 数据库链接信息 1.      数据库方言 2.      ...

  5. mysql 安装过程中的错误:my-template.ini could not be processed and written to XXX\my.ini.Error code-1

    安装mysql的过程中,在最后配置mysql时,提示错误:Configuration file tmeplate E:\编程\MySQL\my-template.ini could not be pr ...

  6. 经验交流List

    6月10日:登录功能的实现 第1组,郑超,90 第5组,张琳,90 ----------------------------- 6月11日上午:登录优化 第7组,张朋,90 6月11日下午:查询操作实 ...

  7. 生成awr报告

    主要参考文献: http://343766868.blog.163.com/blog/static/48314056201110124513396/ 概况 Oracle内部以一定的频率把系统关键的统计 ...

  8. C#、WinForm、ASP.NET - SQLHelper.cs

    SQLHelper.cs using System; using System.Data; using System.Configuration; using System.Data.SqlClien ...

  9. http权威指南 telnet

    对于winXP 1.先启动一个telnet程序连接到TCP服务器中. telnet www.joes-hardware.com 80 2.在连接上的TCP服务器的telnet程序窗口中同时按下 &qu ...

  10. BaseActivity--上门啦

    package com.fwpt.activity; import com.fwpt.entity.RyUserInfo; import com.fwpt.entity.SmlaUserinfo; i ...