前面2篇关注的都是Servlet接口,在实际编码中一般不直接实现这个接口,而是继承HttpServlet类。因为j2e的包里面写好了GenericServlet和HttpServlet类来让我们简化编码了,具体的使用了模板模式。





以下代码贴出一个比较简单的自己的Servlet,以后的内容直接不在赘述Servlet接口,直接针对HttpServlet这个类来说。

package linkin;

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 LinkinServlet extends HttpServlet
{ /**
*
*/
private static final long serialVersionUID = 1L; @Override
public void init() throws ServletException
{
System.out.println("init...");
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter(); out.write("梦似烟花心似水,同学少年不言情。。。");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
this.doGet(req, resp);
} }
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet>
<servlet-name>LinkinServlet</servlet-name>
<servlet-class>linkin.LinkinServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>LinkinServlet</servlet-name>
<url-pattern>/LinkinServlet</url-pattern>
</servlet-mapping> </web-app>

关联前面写的针对Servlet接口的2篇,这里有几点说明:

1,在前面我们自己写Servlet的时候,处理请求的时候实现Service()就好。这里并没有去重写Service()方法,而是重写doGet和doPost2个方法,在HttpServlet抽象类中,已经实现了Service方法了,在有请求进来Servlet的时候首先从请求中获取到请求提交的方式,比如说get方式或者post方式,在调用相关的doXXX方法。所以我们直接重写doGet和doPost方法就好。通常来说在doGet和doPost中实现一个就够了,然后在另外一个方法中this打点调一下实现的那个就OK。

以下贴出HttpServlet的Service源码。

//这里使用try,catch来处理强转问题。
public void service(ServletRequest req, ServletResponse res) 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");
}
service(request, response);
} protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
String method = req.getMethod(); if (method.equals("GET"))
{
doGet(req, resp);
}
else if (method.equals("POST"))
{
doPost(req, resp);
}
....method...
else
{
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(501, errMsg);
}
}

那么问题来了:假如,我说假如在自己的类中重写了service()方法,然后又重写了doGet()和doPost()方法,那么到底调用那个呢?

其实这个问题并不是j2e领域的知识,这是java面向对象的问题,答案很明显,如果出现上面那种情况,doGet()和doPost()2个方法肯定就不起作用了,而是直接使用service()方法来处理请求了。因为在HttpServlet类中已经将service实现了,这个方法的主要功能就是区分不同的请求类型的,然后根据不同的请求类型来调用相应的doXXX方法,世界上Servlet程序本身就是java模板设计模式的应用。



2,在前面一篇博客,我们通过ServletConfig接口和ServletContent接口来获得Servlet的初始化信息,当时直接在init()方法中就可以拿到config那个对象。那么现在我自己写的类不是事先Servlet接口而是继承HttpServlet的话,应该如何办呢?首先我们不改init(ServletConfig config)方法来看看发生了什么。

方法如下:

@Override
public void init(ServletConfig config) throws ServletException
{
System.out.println(config.getInitParameter("name"));
}

OK,没有问题,但是我们知道我们在继承HttpServlet后一般都不是来重写这个方法了,因为GenericServlet中已经实现了一个getServletConfig()方法了,OK,那我现在想要在doGet中取下初始化信息,看看有没有问题:

代码如下:

@Override
public void init(ServletConfig config) throws ServletException
{
System.out.println(config.getInitParameter("name"));
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
this.getServletConfig().getInitParameter("name");
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter(); out.write("梦似烟花心似水,同学少年不言情。。。");
}

访问页面报错500,后台报空指针异常,怎么回事呢?因为在GenericServlet中init(ServletConfig config)这里初始化ServletConfig对象,并且Config是该类的私有成员变量。我们要是自己也重写这个方法,自然会覆盖GenericServlet类中的这个方法,config对象得不到初始化,后面调getInitParameter方法自然报空指针。

那么如何解决呢?

1,以后不用重写init(ServletConfig config)这个方法,要是真的需要自己初始化,直接重写init()方法就好了

2,如果非要重写init(ServletConfig config)这个方法的话,那么请在方法里面的第一行加上一句话:super.init(config);这样子就初始化了GenericServlet类中的config。

Servlet--继承HttpServlet写自己的Servlet的更多相关文章

  1. 最简单的Servlet继承HttpServlet查询数据库登录验证

    <%-- Created by IntelliJ IDEA. User: yunqing Date: 2017-12-06 Time: 9:11 To change this template ...

  2. servlet(1) - 手写第一个servlet程序 - 小易Java笔记

    声明:如tomcat的安装目录为D:\Java\tomcat6,下面要根据tomcat的安装目录而定 1. 建立程序的文件结构 ==>找到tomcat的安装目录,在webapps目录下新建一个名 ...

  3. Servlet简介与Servlet和HttpServlet运行的流程

    1.Servlet      [1] Servlet简介         > Server + let         > 意为:运行在服务器端的小程序.         > Ser ...

  4. Servlet基础知识(一)——Servlet的本质

    什么是Servlet: Servlet是运行在web服务器端(web容器,如tomcat)的程序,它与Applet相对,Applet是运行在客户端的程序. Servlet的主要作用是处理客户端的请求, ...

  5. BaseServlet 继承 httpServlet

    BaseServlet   核心 package cn.core; import java.io.IOException; import java.lang.reflect.Method; impor ...

  6. java一个类 继承HttpServlet 和实现Servlet区别

    java一个类 继承HttpServlet 和实现Servlet区别 servlet 是一个接口,如果实现这个接口,那么就必须实现接口里面定义的所有方法 而HttpServlet实现了servlet接 ...

  7. Servlet课程0424(三) 通过继承HttpServlet来开发Servlet

    //这是第三种开发servlet的方法,通过继承httpservlet package com.tsinghua; import javax.servlet.http.*; import java.i ...

  8. servlet三种实现方式之三通过继承HttpServlet开发servlet

    servlet有三种实现方式: 1.实现servlet接口 2.继承GenericServlet 3.通过继承HttpServlet开发servlet 第三种: import java.io.*; i ...

  9. Servlet-通过继承HttpServlet类实现Servlet程序

    通过继承HttpServlet类实现Servlet程序(开发一般用) 一般在实际项目开发中,都是使用继承 HttpServlet类的方式实现Servlet程序 1,编写一个类去继承 HttpServl ...

随机推荐

  1. 6年后的第一篇博客:进入java的精彩世界

    10的.NET从业经验,也算资深人士了. 2018开始,正式进入JAVA的世界. 为什么说正式?因为已经附带有几年ANDROID经验了,确切的说,是正式进入JAVA服务器端. 没有任何人要求,纯粹是个 ...

  2. Chris Richardson微服务翻译:微服务部署

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服务部署( ...

  3. .NET(c#) 移动开发平台 - Smobiler(1)

    如果说基于.net的移动开发平台,目前比较流行的可能是xamarin了,不过除了这个,还有一个比xamarin更好用的国内的.net移动开发平台,smobiler,不用学习另外一套开发模式或者搭建复杂 ...

  4. Zabbix实战-简易教程--拓扑图(Maps)

    一.拓扑图(Maps) 二话不说,有图有真相,先看看效果,再详细讲解配置过程: 图1:全国网络质量图 图2 核心机房网络质量图 二.详细配置 1.添加  map 选择 系统管理-->基础配置-- ...

  5. Erlang内存吃紧之解决思路

    首先使用erlang:memory()确定是哪个部分内存吃紧,根据输出的内容,比对内存占用大小,有针对性地进行分析.在erlang系统里内存的单位为word,通过erlang:system_info( ...

  6. MySQL中MyISAM 和 InnoDB 的基本区别

    有以下5点 1.innodb支持事务,myisam不支持 2.innodb支持mvcc,myisam不支持 3.innodb支持外键,myisam不支持 4.innodb不支持 FULLTEXT类型的 ...

  7. 认识Java中的字符串

    Java 中 String 类的常用方法 Ⅰ String 类提供了许多用来处理字符串的方法,例如,获取字符串长度.对字符串进行截取.将字符串转换为大写或小写.字符串分割等,下面我们就来领略它的强大之 ...

  8. re 模块 正则表达式

    re模块(正则表达式)   一.什么是正则表达式 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则.(在Python中)它 ...

  9. 详解zkw算法解决最小费用流问题

    网络流的一些基本概念 很多同学建立过网络流模型做题目, 也学过了各种算法, 但是对于基本的概念反而说不清楚. 虽然不同的模型在具体叫法上可能不相同, 但是不同叫法对应的思想是一致的. 下面的讨论力求规 ...

  10. bzoj 2946

    Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单词 l        计算最长公共子串的长度 l        输 ...