Servlet 是一些遵从Java Servlet API的Java类,这些Java类可以响应请求。尽管Servlet可以响应任意类型的请求,但是它们使用最广泛的是响应web方面的请求。 Servlet必须部署在Java servlet容器才能使用。虽然很多开发者都使用Java Server Pages(JSP)和Java Server Faces(JSF)等Servlet框架,但是这些技术都要在幕后通过Servlet容器把页面编译为Java Servlet。也就是说,了解Java Servlet技术的基础知识对任何Java web开发者来说是很有用的。

  在这个教程里,我们将会通过下面的专题来全面了解Java Servlet技术。

  目录

  • 编写你的第一个Servlet
  • Servlet生命周期方法
  • 使用@WebServlet注解开发Servlet
  • 打包和部署Servlet到Tomcat服务器
  • 编写动态的Servlet响应内容
  • 处理Servlet请求和响应
  • 监听Servlet容器事件
  • 传递Servlet初始化参数
  • 为特定的URL请求添加Servlet过滤器
  • 使用Servlet下载二进制文件
  • 使用RequestDispatcher.forward()转发请求到另一个Servlet
  • 使用HttpServletResponse.sendRedirect()重定向请求到另一个Servlet
  • 使用Servlets读写Cookie

  让我们一起来一步步地学习Servlet。

  编写你的第一个Servlet

  我们的第一个Servlet是一个只拥有少量代码的简单Servlet,目的是让你只需关注它的行为。

package com.howtodoinjava.servlets;

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 MyFirstServlet extends HttpServlet {

	private static final long serialVersionUID = -1915463532411657451L;

	@Override
	protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException 
	{
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		try {
			// Write some content
			out.println("<html>");
			out.println("<head>");
			out.println("<title>MyFirstServlet</title>");
			out.println("</head>");
			out.println("<body>");
			out.println("<h2>Servlet MyFirstServlet at " + request.getContextPath() + "</h2>");
			out.println("</body>");
			out.println("</html>");
		} finally {
			out.close();
		}
	}

	@Override
	protected void doPost(HttpServletRequest request,IOException {
		//Do some other work
	}

	@Override
	public String getServletInfo() {
		return "MyFirstServlet";
	}
}

  为了在web容器里注册上面的Servlet,你要为你的应用建一个web.xml入口文件。

<?xml version="1.0"?>
<web-app     xmlns="http://xmlns.jcp.org/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd"

            version="3.0">

    <welcome-file-list>
        <welcome-file>/MyFirstServlet</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>MyFirstServlet</servlet-name>
        <servlet-class>com.howtodoinjava.servlets.MyFirstServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyFirstServlet</servlet-name>
        <url-pattern>/MyFirstServlet</url-pattern>
    </servlet-mapping>

</web-app>

  上面的Servlet做了一些重要的事情,你可能想了解的。

  MyFirstServlet类继承了HttpServlet。这个继承是必须的,因为所有的Servlet必须是要么继承了 javax.servlet.GenericServlet 的普通Servlet,要么是继承了 javax.servlet.http.HttpServlet 的HTTP Servlet。

  重新 doGet() 和 doPost() 方法。这两个方法都已在 HttpServlet 类里定义了。当一个GET或POST请求到来时,它就会被映射到相应的方法里。例如,如果你向这个servlet发送一个HTTP GET请求,doGet()方法就会被调用。

  这里也有一些其他有用的方法。你可以重写它们来在运行时控制应用。例如getServletInfo()。

  HttpServletRequest 和 HttpServletResponse 是所有doXXX()方法的默认参数。我们会在后面的章节里详细学习这些对象。

  以上所有关于简单Servlet的内容就是你需要知道的内容。

  Servlet生命周期方法

  在你的应用加载并使用一个Servlet时,从初始化到销毁这个Servlet期间会发生一系列的事件。这些事件叫做Servlet的生命周期事件(或方法)。让我们一起来进一步了解它们。

  Servlet生命周期的三个核心方法分别是 init(),service() 和 destroy()。每个Servlet都会实现这些方法,并且在特定的运行时间调用它们。

  1) 在Servlet生命周期的初始化阶段,web容器通过调用init()方法来初始化Servlet实例,并且可以传递一个实现 javax.servlet.ServletConfig 接口的对象给它。这个配置对象(configuration object)使Servlet能够读取在web应用的web.xml文件里定义的名值(name-value)初始参数。这个方法在Servlet实例的生命周期里只调用一次。

  init方法定义与这类似:

public void  init() throws ServletException {
	//custom initialization code
}

  2) 初始化后,Servlet实例就可以处理客户端请求了。web容器调用Servlet的service()方法来处理每一个请求。service() 方法定义了能够处理的请求类型并且调用适当方法来处理这些请求。编写Servlet的开发者必须为这些方法提供实现。如果发出一个Servlet没实现的请求,那么父类的方法就会被调用并且通常会给请求方(requester)返回一个错误信息。

  通常,我们不需要重写(override)这个方法。

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 = req.getDateHeader(HEADER_IFMODSINCE);
	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);
}
}

  3) 最后,web容器调用destroy()方法来终结Servlet。如果你想在Servlet的生命周期内关闭或者销毁一些文件系统或者网络资源,你可以调用这个方法来实现。destroy() 方法和init()方法一样,在Servlet的生命周期里只能调用一次。

public void destroy() {
//
}

  在大多数情况下,你通常不需要在你的Servlet里重写这些方法。

扩展阅读:web服务器是如何运作的?

  使用@WebServlet注解来开发Servlet

  如果你不喜欢使用xml配置而喜欢注解的话,没关系,Servlets API同样提供了一些注解接口给你。你可以像下面的例子一样使用 @WebServlet 注解并且不需要在web.xml里为Servlet注册任何信息。容器会自动注册你的Servlet到运行环境,并且像往常一样处理它。

package com.howtodoinjava.servlets;

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 = "MyFirstServlet",urlPatterns = {"/MyFirstServlet"})
public class MyFirstServlet extends HttpServlet {

    private static final long serialVersionUID = -1915463532411657451L;

    @Override
    protected void doGet(HttpServletRequest request,IOException
    {
        //Do some work
    }

    @Override
    protected void doPost(HttpServletRequest request,IOException {
        //Do some other work
    }
}

  打包和部署Servlet到Tomcat服务器

  如果你在使用IDE(例如Eclipse),那么打包和部署你的应用只需要一个简单的步骤。右击项目> Run As > Run As Server。如果还没配置服务器先配置好服务器,然后就可以准备开干了。

  如果你没在使用IDE,那么你需要做一些额外的工作。比如,使用命令提示符编译应用,使用ANT去生成war文件等等。但我相信,现在的开发者都在使用IDE来开发。所以我就不在这方面浪费时间了。

dawei

【声明】:唐山站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。