• Servlet--继承HttpServlet写自己的Servlet


    前面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。



  • 相关阅读:
    Android-通过SlidingPaneLayout高仿微信6.2最新版手势滑动返回(一)
    B树
    nyoj448 寻找最大数
    IT痴汉的工作现状22-由Dalvik虚拟机引发的口水战
    POJ 3221 Diamond Puzzle.
    CMDBuild安装及webservice接口的获取
    安卓dex 文件结构简要说明
    安装RPM包或者安装源代码包
    Java程序性能优化技巧
    [Sqlite]--&gt;数据迁移备份--从低版本号3.6.2到高版本号3.8.6
  • 原文地址:https://www.cnblogs.com/LinkinPark/p/5233010.html
Copyright © 2020-2023  润新知