基于java技术的web组件,由容器管理,生成动态内容,不依赖于平台的
servlet通过servlet容器发布的请求/响应规范与web客户端交互
servlet容器:
是web服务器或应用(application)的一部分,对发送的请求/响应提供网络服务。对MIME-based请求解码,对MIME-based的响应规范化。所有的servlet容器必须支持请求/响应的HTTP协议,但是其他基于请求/响应的协议,如HTTPS(HTTP over SSL)可能得到支持。
加载和实例化可以在容器启动时发生,也可以延迟到容器确定需要servlet来服务请求为止。
servlet是通过一个定义良好的生命周期来管理的,该生命周期定义了如何加载和实例化servlet、如何初始化servlet、如何处理来自客户端的请求以及如何停止服务。这个生命周期在API中由javax.servlet.servlet接口的init、service和destroy方法表示,所有servlet都必须通过GenericServlet或HttpServlet抽象类直接或间接实现。
2.1请求处理方法
Web服务器、Servlet容器和Servlet:(10条消息) Web服务器、Servlet容器和Servlet_荒野孤鹰-CSDN博客_servlet容器和web容器
基本的Servlet接口有一个方法service()用于解决客户端请求,对于servlet容器路由到servlet实例的每个请求,都会调用此方法。
public interface Servlet
定义所有servlet必须实现的方法。
servlet是在Web服务器中运行的小型Java程序。servlet通常通过HTTP协议接收和响应来自Web客户端的请求。
要实现此接口,可以编写扩展javax.servlet.GenericServlet的generic servlet或扩展javax.servlet.HTTP.HttpServlet的HTTP servlet。
这个接口定义了初始化servlet、服务请求和从服务器中删除servlet的方法。这些方法称为生命周期方法,按以下顺序调用:
- 构建servlet,然后用init方法初始化。
void init(ServletConfig config) throws ServletException
由servlet容器调用,以向servlet指示servlet正在投入服务。servlet容器在实例化servlet之后只调用init方法一次。init方法必须成功完成,servlet才能接收任何请求。
如果init方法满足以下,servlet容器无法将servlet投入服务:
抛出ServletException
在Web服务器定义的时间段内不返回。
- 处理来自客户机对service方法的任何调用。
void service(ServletRequest req,ServletResponse res)throws ServletException,
IOException
由servlet容器调用以允许servlet响应请求。只有在servlet的init()方法成功完成后才调用此方法。应该始终为抛出或发送错误的servlet设置响应的状态代码。
servlet通常在多线程servlet容器中运行,这些容器可以同时处理多个请求。开发人员必须知道如何同步访问任何共享资源,如文件、网络连接以及servlet的类和实例变量。
- servlet停止服务,然后用destroy方法销毁,然后垃圾收集并完成。
void destroy()
由servlet容器调用,以向servlet指示servlet正在停止服务。只有当servlet的service方法中的所有线程都已退出或超过超时后,才会调用此方法。在servlet容器调用此方法之后,它将不再在此servlet上调用服务方法。
这个方法给servlet一个机会来清理所持有的任何资源(例如,内存、文件句柄、线程),并确保任何持久状态都与servlet在内存中的当前状态同步。
对Web应用程序并发请求的处理通常要求Web开发人员设计servlet,该servlet可以处理在特定时间内执行的多个线程。
通常,Web容器通过在不同线程上并发执行service方法来处理对同一servlet的并发请求。
2.1.1HTTP特定的请求处理方法
HttpServlet抽象子类在基本Servlet接口之外添加了其他方法,这些方法由HttpServlet类中的service方法自动调用,以帮助处理基于HTTP的请求。这些方法是:
HttpServlet的子类必须重写其中至少一个方法
- doGet用于解决HTTP GET请求
- doPost for handling HTTP POST requests:当要处理POST操作时,你必须在HttpServlet的子类中重载这一方法。
- doPut for handling HTTP PUT requests:允许Servlet开发人员支持HTTP/1.1使用这些功能的客户
- doDelete for handling HTTP DELETE requests:允许Servlet开发人员支持HTTP/1.1使用这些功能的客户
- doHead for handling HTTP HEAD requests:是doGet方法的专门形式,只返回由doGet方法生成的头部
- doOptions for handling HTTP OPTIONS requests:响应servlet支持哪些HTTP方法。
- doTrace for handling HTTP TRACE requests:生成一个响应,包含所有跟踪请求中发送的头的实例
2.1.3条件GET
HttpServlet接口定义getLastModified方法以支持条件GET操作。条件GET操作仅当资源在指定时间后被修改时才请求发送该资源。在适当的情况下,该方法的实现有助于网络资源的有效利用。
protected long getLastModified(HttpServletRequest req)
返回HttpServletRequest对象上次修改的时间,以毫秒为单位,从1970年1月1日午夜开始。如果时间未知,此方法将返回负数(默认值)。
支持http get请求并能快速确定其最后修改时间的servlet应该覆盖此方法。这使得浏览器和代理缓存更有效地工作,减少了服务器和网络资源的负载。
3.the request
request对象封装了来自client请求的所有信息。在HTTP协议中,这些信息以HTTP格式从client传输到server请求的头和消息体。
3.1HTTP协议参数
servlet的请求参数是客户端作为其请求的一部分发送到servlet容器的字符串。当请求是HttpServletRequest对象,并且满足第24页“参数可用时”中规定的条件时,容器将从URI查询字符串和POST-ed数据填充参数。
public interface ServletRequest
定义一个向servlet提供客户端请求信息的对象。servlet容器创建一个ServletRequest对象,并将其作为参数传递给servlet的service方法。
ServletRequest对象提供包括参数名称和值、属性和输入流的数据。扩展ServletRequest的接口可以提供额外的特定于协议的数据(例如,HTTP数据由HttpServletRequest提供)。
参数存储为一组键-值对。任何给定的参数名都可以存在多个参数值。ServletRequest接口的以下方法可用于访问参数:
■ getParameter
String getParameter(String name)
以字符串形式返回请求参数的值,如果参数不存在,则返回null。Request 参数是随请求发送的额外信息。对于httpservlet,参数包含在查询字符串或发布的表单数据中。
只有在确定参数只有一个值时才应使用此方法。如果参数可能有多个值,请使用getParameterValues(java.lang.String)。
如果对多值参数使用此方法,则返回的值等于getParameterValues返回的数组中的第一个值。如果参数数据是在请求正文中发送的,例如在HTTP POST请求中发生的,那么通过getInputStream()或getReader()直接读取正文可能会干扰此方法的执行。
■ getParameterNames
Enumeration<String> getParameterNames()
返回包含此请求中包含参数名称的字符串对象的枚举。如果请求没有参数,则该方法返回空枚举。
■ getParameterValues
String[] getParameterValues(String name)
返回包含给定请求参数所具有的所有值的字符串对象数组,如果参数不存在,则返回null。
如果参数只有一个值,则数组的长度为1。
■ getParameterMap
Map<String,String[]> getParameterMap()
返回此请求的参数的java.util.Map。names as keys and parameter values as map values.
请求参数是随请求发送的额外信息。对于httpservlet,参数包含在查询字符串或发布的表单数据中。
来自查询字符串和post body的数据被聚合到请求参数集中。Query string data在post body数据之前显示。例如,如果请求是用a=hello的query string和a=goodbye&world的post body的组合,生成的参数集将被排序为a=(hello,goodbye,world)。
作为GET请求(由HTTP1.1定义)一部分,Path parameters不可exposed by these APIs.。必须从
getRequestURI方法或getPathInfo方法转换为String值。
3.1.3 什么时候Parameters可获取
在将post form data(发布的表单数据)填充到参数集之前,必须满足以下条件:
1.请求为HTTP或HTTPS请求。
2.HTTP方法为POST。
3.内容类型为application/x-www-form-urlencoded。
4.servlet已经对getParameter家族方法中的任何一个,进行了初始调用在请求对象上
如果不满足条件并且参数集中不包含post form data,则post data必须通过请求对象的输入流连接servlet。如果满足条件,则post form data将不再可直接从请求对象的输入流读取。
3.2文件上传
Servlet容器允许文件被上传,当数据作为multipart/form-data发送时。
如果满足以下任一条件,servlet容器将提供multipart/form-data处理:
- 处理请求的servlet使用@MultipartConfig进行注释,如第8.1.5节第8-74页的“@MultipartConfig”所定义。
- servlet处理请求时,Deployment descriptors包含一个multipart-config元素
数据如何在请求类型为multipart/form-data时可获得,取决于servlst容器是否提供multipart/form-data处理:
若提供,则数据通过HttpServletRequest中的以下方法获得:
- public Collection getParts()
获取此请求的所有part组件,前提是它的类型为multipart/form data。如果此请求的类型为multipart/form data,但不包含任何part组件,则返回的集合将为空。对返回集合的任何更改都不得影响此HttpServletRequest。
- public Part getPart(String name)
每个部分通过part.getInputStream方法提供对headers、content type related with it和内容的访问。得到给定名字的part。
对于form-data作为Content-Disposition但没有文件名的part,该part的字符串值也将通过HttpServletRequest上的getParameterValues方法使用part名称获得。
若不提供,数据将通过HttpServletReuqest.getInputStream获取
3.3属性
属性是请求关联的objects,属性可以由容器设置以表示信息,否则不能通过API被表达,或者可以由servlet设置以与另一个servlet交流信息(通过RequestDispatcher)。属性使用ServletRequest接口的以下方法访问:
- getAttribute
- getAttributeNames
- setAttribute
只有一个属性值被关联到一个属性名上。
以java.或javax.开头的属性名,是为本specification定义而保留的。类似,以sun., com.sun., oracle and com.oracle开头的属性是Oracle公司定义所保留的。建议放置在属性集中的所有属性都为
按照 Java 编程语言规范建议的反向域名约定命名包命名。
3.4Headers
一个servlet可以通过HttpServletRequest的以下方法访问HTTP请求的头部:
- getHeader
String getHeader(String name)
返回给定name的一个header,若有多个,只返回第一个
- getHeaders:返回多个,返回枚举或String对象
- getHeaderNames
- getIntHeader:得到int类型的header,如果无法将header值转换为int,则会引发NumberFormatException。
- getDateHeader
3.5Request Path Elements
使得servlet服务一个request的request path由多个重要的部分组成。以下元素从请求URI路径获得,并通过请求对象公开:
- Context Path:
- Servlet Path:
- PathInfo: