技术干货

Servlet

2017-12-06  本文已影响0人  Sue1024

最近要去参加一个程序设计比赛,听说比赛期间只能使用Eclipse和Tomcat,组委会不提供Spring之类的框架,故温习了一下Servlet。

What's a Servet?

A servlet is a small Java program that runs within a Web server.

Servlet就是一个运行在一个Web Server(如Tomcat)中的Java程序,可以收到客户端通过HTTP发来的请求(request),并提供返回值(response)。

Servlet Interface

init

public void init(ServletConfig config) throws ServletException
当一个ServletContainer(如Tomcat)初始化了一个servlet,它会调用这个servlet的init方法, 来告诉这个servlet它正在被放进这个container对外提供的服务中。只有在调用了init方法之后,这个servlet才可以收到客户端发来的请求。
当执行init方法时,若发生以下任何情况, container装载servlet的过程就会失败:

  1. 抛出ServletException
  2. 超时(时限由WebServer决定)
service

public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException
在一个servlet的init方法被成功执行后,它就可以收到客户端发来的请求,当有请求发来,container会调用service方法, 针对这次请求服务段的响应会在这里进行,请注意servlet应为它的每次响应设置相应代码(500,404, 200...)。
另外一点需要注意的是, 在container中,servlets通常是并发运行的, 开发者们需要单例化一些资源的访问代码,比如文件、数据库、网络连接等等,以防死锁的发生。

destroy

当一个servlet并发执行的所有service方法全部结束后,container可以调用destroy方法来告诉一个servlet它正在被移出container提供的服务中。
调用这个方法后,一个servlet可以清理因为它被占用的所有资源。

getServletConfig

public ServletConfig getServletConfig()
返回container调用init时传入的ServeltConfig对象,这个对象包含这个servlet的初始化和启动参数

getServletInfo

public java.lang.String getServletInfo
返回诸如作者、版本、版权等信息

GenericServlet

GenericServlet implements Servlet, 它实现了Service接口定义的所有方法,因此我们介绍一下它自定义的方法

getServletName

ServletConfig.getServletName()
返回servlet实例的名字

log
  1. log(java.lang.String msg)
    往servlet日志文件中插入日志信息, 由servlet的名字打头
  2. log(java.lang.String msg, java.lang.Throwable t)
    往servlet日志文件中插入日志信息, 包含给定的字符串,以及给定异常的报错信息, 由servlet的名字打头
getInitParameter

从ServletConfig对象中获得指定的参数值

getInitParameterNames

获得ServletConfig对象中包含的参数名称的枚举

getServletContext

从ServletConfig对象中获得servlet运行的上下文对象(ServletContext)

init

提供无参的方式调用GenericServlet.init(ServletConfig config)

HttpServlet

service

protected void service (HttpServletRequest req, HttpServletResponse, res) throws ServletException, java.io.IOException
将共有service方法传来的请求分发给不同的方法(doXXX),通过以下代码可以看出,service方法首先获得客户端方来请求的方法,然后将其分发给doXXX方法

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
     String method = req.getMethod(); 
     if (method.equals("GET")) {
       long lastModified = getLastModified(req);
       if (lastModified == -1L)
       { 
         doGet(req, resp);
       } else {
         long ifModifiedSince;
         try {
           ifModifiedSince = req.getDateHeader("If-Modified-Since");
         } catch (IllegalArgumentException iae) {
           ifModifiedSince = -1L;
         }
         if (ifModifiedSince < lastModified / 1000L * 1000L)
         {
           maybeSetLastModified(resp, lastModified);
           doGet(req, resp);
         } else {
           resp.setStatus(304);
         }
       }
     }
     else if (method.equals("HEAD")) {
       long lastModified = getLastModified(req);
       maybeSetLastModified(resp, lastModified);
       doHead(req, resp);
     }
     else if (method.equals("POST")) {
       doPost(req, resp);
     }
     else if (method.equals("PUT")) {
       doPut(req, resp);
     }
     else if (method.equals("DELETE")) {
       doDelete(req, resp);
     }
     else if (method.equals("OPTIONS")) {
       doOptions(req, resp);
     }
     else if (method.equals("TRACE")) {
       doTrace(req, resp); 
     }
     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);
     }
   }
doGet

protected void doGet(HttpServletRequest req, HttpServletResponse, res) throws ServletException, java.io.IOException
处理GET请求
重写这个方法可以自动地支持HTTP HEAD请求。HEAD请求相当于没有body的GET请求。
重写这个方法时, 首先读取请求数据,写响应头数据(必须写,会先于response body 发送), 然后写入响应输出流,最好包含content type和encoding,当使用PrintWriter对象响应请求时,就得在获得PrintWriter对象前设置content type。
如果可能,可以设置Content-Length头来使container开辟一个持久的连接来响应某一个客户端的请求,来优化性能。
GET方法应该是安全的,尤其是并发安全。

doHead

当用户只想获得响应头数据时,会像服务器发送HEAD请求。

doPost

HTTP POST 方法可以使客户端发送不限长度的数据给服务器。如何重写参照doGet

doPut

PUT操作可以帮助客户端服务器上传文件
重写这个方法时

doDelete

DELETE操作可以帮助客户端移出服务器上的文件或者网页

doOptions

OPTIONS请求可以使客户端知道servlet支持那些HTTP方法。

HTTP Request

HTTP Request Description
GET Asks to get the resource at the requested URL.
POST Asks the server to accept the body info attached. It is like GET request with extra info sent with the request.
HEAD Asks for only the header part of whatever a GET would return. Just like GET but with no body.
TRACE Asks for the loopback of the request message, for testing or troubleshooting.
PUT Says to put the enclosed info (the body) at the requested URL.
DELETE Says to delete the resource at the requested URL.
OPTIONS Asks for a list of the HTTP methods to which the thing at the request URL can respond
上一篇下一篇

猜你喜欢

热点阅读