在Java Web中Servlet、请求和响应是最基本的三个对象,在Web容器的管理下,这三者能够完成基本的HTTP请求处理。
Servlet的作用是为客户提供服务。servlet的角色是接受一个客户的请求,再返回一个响应。请求可能非常简单,例如:给我提供一个欢迎页面;也可能非常复杂,例如:为当前的购物车结账,这个请求会带一些客户端传来的参数,servlet需要知道自己如何使用请求中的参数,还需要知道该返回什么样的响应。
Java Web服务器处理用户请求的基本过程:用户在客户端点击一个链接,浏览器会向Web应用服务器发送一个URL请求,该URL会指向一个servlet;Web容器看出这个请求指向某个servlet A,就会创建两个对象(HttpServletRequest和HttpServletResponse),并分配或创建一个线程,调用servlet A对应的service方法(上述请求和响应对象作为参数);service根据HTTP请求区分出客户端发来的是GET还是POST请求,并调用对应的doGet()或doPost()方法;在doGet()或doPost()方法中进行业务逻辑的处理,处理完成后的结果通过响应对象返回写回给客户端。
在容器启动时,XXXServlet在JVM的管理下被实例化为一个对象,这时候它还不是servlet,需要在容器的管理下调用init()方法进行初始化,获得ServletConfig和ServletContext对象的引用后,才称为一个真正的Servlet。
Servlet的一生.png
关键点:每个请求都在一个单独的线程中运行!
servlet的继承体系.png
HttpServletRequest的API与HTTP有关,例如:Cookie、首部(Header)和会话(Session)等;
HttpServletRequest的继承体系.png
ServletResponse(响应)也是类似,用于帮助servlet给客户端返回处理结果,而HttpServletResponse增加了HTTP相关的内容(例如:错误、cookie和首部)等API。
HttpServletResponse的继承体系.png
HttpServletRequest和HttpServletResponse这些都是servlet规范里指定的接口,而web容器开发商(例如tomcat)会负责实现这些接口,例如:HttpServletResponseWrapper和ApplicationHttpResponse等,作为开发者,我们只需要知道,在处理doGet()和doPost方法时,容器会给这个方法传HttpServletRequest和HttpServletResponse两个参数。
大多数情况下,使用响应只是为了向客户发回数据。会对响应调用两个方法:setContentType()和getWriter()。在此之后,可以将HTML或其他内容写入到流。不过,你也可以使用响应设置首部、发送错误或增加Cookie。
/**
* Encodes the specified URL for use in the <code>sendRedirect</code> method
* or, if encoding is not needed, returns the URL unchanged. The
* implementation of this method includes the logic to determine whether the
* session ID needs to be encoded in the URL. Because the rules for making
* this determination can differ from those used to decide whether to encode
* a normal link, this method is separated from the <code>encodeURL</code>
* method.
* <p>
* All URLs sent to the <code>HttpServletResponse.sendRedirect</code> method
* should be run through this method. Otherwise, URL rewriting cannot be
* used with browsers which do not support cookies.
*
* @param url
* the url to be encoded.
* @return the encoded URL if encoding is needed; the unchanged URL
* otherwise.
* @see #sendRedirect
* @see #encodeUrl
*/
public String encodeRedirectURL(String url);
/**
* Sends an error response to the client using the specified status code and
* clears the output buffer. The server defaults to creating the response to
* look like an HTML-formatted server error page containing the specified
* message, setting the content type to "text/html", leaving cookies and
* other headers unmodified. If an error-page declaration has been made for
* the web application corresponding to the status code passed in, it will
* be served back in preference to the suggested msg parameter.
* <p>
* If the response has already been committed, this method throws an
* IllegalStateException. After using this method, the response should be
* considered to be committed and should not be written to.
*
* @param sc
* the error status code
* @param msg
* the descriptive message
* @exception IOException
* If an input or output exception occurs
* @exception IllegalStateException
* If the response was committed
*/
public void sendError(int sc, String msg) throws IOException;
/**
* Sends a temporary redirect response to the client using the specified
* redirect location URL. This method can accept relative URLs; the servlet
* container must convert the relative URL to an absolute URL before sending
* the response to the client. If the location is relative without a leading
* '/' the container interprets it as relative to the current request URI.
* If the location is relative with a leading '/' the container interprets
* it as relative to the servlet container root.
* <p>
* If the response has already been committed, this method throws an
* IllegalStateException. After using this method, the response should be
* considered to be committed and should not be written to.
*
* @param location
* the redirect location URL
* @exception IOException
* If an input or output exception occurs
* @exception IllegalStateException
* If the response was committed or if a partial URL is given
* and cannot be converted into a valid URL
*/
public void sendRedirect(String location) throws IOException;