一. 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. Vmware Briged方式使虚拟机上网

    1.禁用掉在网络连接VMware Network Adapter VMnet1和VMware Network Adapter VMnet8 (在bridged这种方式下不需要这两个连接,如下图) 2. ...

  2. gethostbyname() -- 用域名或主机名获取IP地址

    #include <netdb.h>    #include <sys/socket.h> struct hostent *gethostbyname(const char * ...

  3. opencv开源库

    opencv是开源库 在Windows下编译扩展OpenCV 3.1.0 + opencv_contrib 为什么要CMake,这里我陈述自己的想法,作为一个刚使用opencv库的小白来说,有以下大概 ...

  4. HTTP的请求头标签If-Modified-Since

    一直以来没有留意过HTTP请求头的IMS(If-Modified-Since)标签. 最近在分析Squid的access.log日志文件时,发现了一个现象. 就是即使是对同一个文件进行HTTP请求,第 ...

  5. AsyncTask总结(经典,附带源码)

    一.整体工程图 二.MainActivity.java package com.jltxgcy.asynctaskdemo; import android.app.Activity; import a ...

  6. jquery Deferred使用经验

    这周做了个小活动(http://aoqi.100bt.com/zt-2016duanzi/index.html),刚开始时候没看好需求,逻辑都写一块了 最后各种坑要填补,从中也获取了些经验和教训,下面 ...

  7. 利用WebClient上传参数及文件流到远程ashx服务

    原文 利用WebClient上传参数及文件流到远程ashx服务 1 思路: WebClient.UploadFile()方法可以上传文件:UploadData()方法可以上传数据参数:如何合二为一既上 ...

  8. DOM方法入门 - 第二课

    1.console.log()是吧元素显示在控制台2.appendChild() 就是将元素追加到末尾3.innerHTML获取的是元素里面的所有内容包括里面的子元素4.innerText获取的是元素 ...

  9. nest expression &amp; Pyparsing

    http://pyparsing.wikispaces.com/ http://bbs.csdn.net/topics/330052586 C++ boost "<([^<> ...

  10. 浮点数在计算机内存中的表示(IEEE 754规定1位是符号位,8位是指数,剩下的23位为有效数字)

    本文转载自:阮一峰的博客,http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html 张玉彬的博客 h ...