web技术的发展
早期的web应用主要是静态页面的浏览,这些静态页面使用HTML语言编写,放在服务器上,用户使用浏览器通过HTTP协议请求服务器上的web页面,服务器上的web服务器软件接受到用户发送的请求后,读取请求URI所标识的资源,加上消息包头发送给客户端的浏览器,浏览器解析响应中的HTML数据,向用户呈现多姿多彩的HTML页面。
但是随着网络的发展,很多线下业务开始向网上发展,基于Internet的web应用也变得越来越复杂用户所访问的资源已不仅仅局限于服务器硬盘上存放的静态网页,更多的应用需要根据用户的请求动态生成网页信息,复杂的还需要从数据库中提取信息,经过一定的运算,生成一个页面返回给客户如何才能实现?
利用已经实现HTTP协议的服务器端软件,这些软件预先给我们留出了扩展的接口,我们只需要按照一定的规则取提供相应的扩展功能,当这类web服务器接受到客户端请求后,判断请求是否是访问我们提供的扩展功能,如果是,将请求交由我们编写的程序去处理,处理完成后,程序将处理结果交回web服务器软件,web服务器软件拿到结果后,再将结果作为相应信息返回给客户端。
早起使用的web服务器扩展机制是CGI,它允许用户调用web服务器上的CGI程序,CGI全称 CommonGateway Interface 公共网关接口,大多数的CGI程序使用Perl来编写,也有通过C,Python或PHP编写,用户通过单击某个连接或者直接在浏览器的地址栏输入URL来访问CGI程序,web服务器接受到请求后,发现这个请求是给CGI程序的,于是就启动并运行这个CGI程序,对用于请求进行处理。CGI程序解析请求中的CGI数据,处理数据,并且产生一个响应,这个响应被返回给web服务器,web服务器包装这个响应,以HTTP响应的形式发送给Web浏览器。但是CGI编写困难,对用户请求的响应时间较长以进程方式运行导致性能受限制。
-
1997年,SUN公司推出了Servlet技术,作为java阵营的CGI解决方案,作为对微软ASP(1996年推出)的推出,SUN公司于1998年推出了JSP技术,允许在HTML页面中嵌入java脚本代码,从而实现动态网页的功能。此外,PHP(1994年发明)技术也是类似于APS,JSP服务器端页面编写技术
-
Servlet
java Servlet(java服务器小程序)是一个基于java技术的web组件,运行在服务器端,由Servlet容器所管理,用于生成动态的内容,Servlet是平台独立的java类,编写一个Servlet实际上就是按照Servlet规范编写一个Java类,Servlet被编译为平台独立的字节码,可以被动态地加载到支持java技术的web服务器中运行。Servlet容器
Servlet容器也叫Servlet引擎,是Web服务器或者应用服务器的一部分,用户在发送请求和响应之上提供网络服务,解码基于MIME的请求,格式化基于MIME的请求,Servlet不能独立运行,必须被部署到Servlet容器中,由容器实例化和调用Servlet的方法,Servlet容器在Servlet的生命周期内包含和管理Servlet
-
对比CGI
- Servlet是单实例多线程的运行方式,每个请求在一个独立的线程中运行,提供服务的Servlet实例只有一个
- Servlet 具有可升级性,能响应更多的请求,因为servlet容器使用一个线程而不是操作系统进程,线程占用的资源要小
3.Servlet使用标准的API,被更多的web服务器所支持。
4.Servlet使用java语言编写,拥有更多的java程序语言的优点
5.Servlet可以访问java平台丰富的类库,使得各种应用的开发更为容易
6.Servlet容器给Servlet提供额外的功能。
Tomcat
Tomcat是一个免费的开源代码的Servlet容器,是Apache软件基金会的一个顶级项目,由Apache,SUN和其他一些公司及个人共同开发而成,由于SUN的参与与支持,最新的Servlet和JSP规范总是能在Tomcat中得到体现。Tomcat支持Servlet2.5Tomcat的安装
安装jdk,并且配置环境变量 path,CLASSPATH,JAVA_HOME
解压tomcat即可
Tomcat的目录结构
bin 存放启动和关闭Tomcat的脚本文件
conf 存放Tomcat服务器的各种配置文件,server.xml web.xml等
lib 存放Tomcat服务器和所有web应用程序需要访问的JAR文件
logs 存放Tomcat的日志文件
temp 存放Tomcat运行时产生的临时文件
webapps 当发布web应用程序时,通常把Web应用程序的目录及文件放到这个目录下
work Tomcat将JSP生成的Servlet源文件和字节码文件存放到这个目录下
-
Servlet详解
Servlet API
Servlet接口
init(ServletConfig config)
在Servlet实例化之后,Servlet容器会调用init()方法,来初始化该对象,主要是为了让servlet对象在处理客户请求前完成一些初始化工作。例如建立数据库的连接,获取配置信息等。对于每个Servlet实例,init()方法只能被调用一次。Servlet容器通过config参数向Servlet传递配置信息。可以通过config获取web应用程序的初始化参数,还可以获取ServletContext对象service(ServletRequest req,ServletResponse res)
容器调用service()方法处理客户端的请求,在调用service()方法被容器调用之前,必须确保Init()方法正确完成,容器会构造一个ServletRequest对象和ServletResponse对象作为参数传递给service()方法。destroy();
当容器检测到一个Servlet对象应该从服务中被移除的时候,容器会调用该对象的destory方法,以便让Servlet对象可以释放它所使用的资源,保存数据到数据库中。ServletConfig getServletConfig()
返回容器调用init()方法时传递给Servlet对象的ServletConfig对象String getServletInfo()
返回一个String类型的字符串,包含了关于Servlet的信息,例如版权,作者等。
ServletRequest
ServletRequest 对象,用来封装请求数据
- Object getAttribute(String name)
返回以name为名字的属性的值,如果不存在,返回null - Enumeration getAttributeNames();
返回请求中所有可用的属性的名字。返回一个枚举集合 - void removeAttribute(String name);
移除请求中名字为name的属性 - void setAttribute(String key,Object val);
在请求中保存一个键值对。 - getCharacterEncoding()
返回请求正文使用的字符编码的名字 - int getContentLength()
以字节为单位,返回请求正文的长度。 - String getContentType()
返回正文的MIME类型 - ServletInputStream getInputStream()
- BufferedReader getReader()
- String getLocalAddr()
返回接收到请求的网络接口的IP地址。 - String getRemoteAddr()
返回发送请求的客户端或最后一个代理服务器的IP地址 - String getRemoteHost()
返回发送请求的客户端或者最后一个代理服务器的完整限定名 - String getLocalName()
返回接收到请求的IP接口的主机名 - int getLocalPort()
返回接收到请求的网络接口的IP端口号 - int getRemotePort()
返回发送请求的客户端或最后一个代理服务器的IP源端口。 - String getParameter(String name)
返回请求中name参数的值,如果name参数有多个值,该方法返回值列表中的第一个值。如果请求中没有找到该参数,返回null - Enumeration getParameterNames()
返回请求中包含的所有的参数的名字。 - String[] getParameterValues(String name);
返回请求中name参数所有的值 - String getProtocal()
返回请求使用的协议的名字和版本 例如: HTTP/1.1 - RequestDispatcher getRequestDispatcher(String path)
返回RequestDispather对象,作为path所定位的资源的封装。 - String getServerName()
返回请求发送到服务器的主机名 - int getServerPort()
返回请求发送到服务器的端口号 - setCharacterEncoding(String env)
覆盖在请求正文中所使用的字符编码的名字。
ServletResponse对象,用来封装响应数据
- flushBuffer() 强制把任何在缓存中的内容发送到客户端
- int getBufferSize() 返回实际用于响应的缓存的大小,如果没有使用缓存,这个方法返回0
- String getCharacterEncoding()
返回响应中发送的正文所使用的字符编码(MIME字符集) - String getContentType()
返回响应中发送的正文所使用的MIME类型 - ServletOutputStream getOutputStream()
- PrintWriter getWriter()
- boolean isCommitted() 返回一个布尔值,指示是否已经提交了响应。
- void reset() 清除在缓存中的任何数据,包括状态代码和消息报头。
- void resetBuffer() 清除在缓存中的响应内容,保留状态代码和消息包头。
- void setBufferSize(int size)
设置响应正文的缓存大小。 - void setCharacterEncoding(String charset)
设置发送到客户端的响应的字符编码 - void setContentLength(int len)
设置内容正文的长度 - void setContentType(String type)
设置要发送到客户端的响应的内容类型。例如:"text/html;charset=UTF-8"
ServletConfig
Servlet容器使用ServletConfig对象在Servlet初始化期间向它传递配置信息,一个ServletConfig对象。
String getInitParameter(String name);
返回名字为name的初始化参数的值,初始化参数在web.xml配置文件中进行配置。Enumeration getInitParameterNames()
返回Servlet所有初始化参数的名字的枚举集合。ServletContext getServletContext()
返回Servlet上下文对象的引用。String getServletName()
返回Servlet实例的名字,这个名字是web应用程序的部署描述符中指定。编写一个Servlet实际上就是编写一个实现了javax.servlet.Servlet接口的类。
GenericServlet
-
如果要编写一个通用的Servlet,只需要从GenericServlet继承,并且实现抽象方法service();
String getInitParameter(String name) Enumeration getInitParameterNames(); ServletContext getServletContext() init(ServletConfig config)
HttpServlet
-
在绝大多数的网络应用中,都是客户端通过HTTP协议去访问服务器端的资源我们编写的Servlet也主要是应用于HTTP协议的请求和响应,为了快速开发应用于HTTP协议的Servlet类,sun公司在javax.servlet.http包中给我们提供了一个抽象类HttpServlet,它继承自GenericServlet类,用于创建适合WEB站点的HTTP Servlet
public void service(ServletRequest req,ServletResponse res); protected void service(HttpServletRequest req,HttpServletResponse resp) 针对HTTP1.1定义的7种请求方法GET,POST,HEAD,PUT,DELETE,TRACE,OPTION, HttpServlet提供了7个处理方法 doGet(HttpServletRequest req,HttpServletResponse resp) doPost(HttpServletRequest req,HttpServletResponse resp) ......
-
当容器接受到一个针对HttpServlet对象的请求时,调用该对象中的方法顺序如下:
- 调用公共的service()方法
- 在公共的service()方法中,首先将参数类型转换为HttpServletRequest和HttpServletResponse,然后调用保护的service()方法,将转换后的对象作为参数传递进去
- 在保护的service方法中,首先调用HttpServletRequest对象的getMethod方法,获取HTTP请求方法的名称,然后根据请求方法的类型,调用相应的doXxx()方法
HttpServletRequest
继承自javax.servlet.servletRequest,在该接口中新增的方法如下:
- String getContextPath()
返回请求URI中表示请求上下文的部分,上下文路径是请求URI的开始部分 - Cookie[] getCookies()
返回客户端在此次请求中发送的所有的Cookie对象 - String getHeader(String name)
返回名字为name的请求报头的值 - Enumeration getHeaderNames()
返回此次请求中包含的所有的报头名字的枚举集合 - Enumeration getHeaders(String name)
返回名字为name的请求报头的所有值的枚举集合 - String getMethod()
返回此次请求所使用的HTTP方法的名字 - String getServletPath()
返回请求URI中调用Servlet的部分 - HttpSession getSession()
返回和此次请求相关联的Session - HttpSession getSession(boolean create)
返回此次请求相关联的Session,如果没有给客户端分配Session,并且create参数为true,则创建一个新的Session,如果为false,此次请求没有一个有效的HttpSession,返回null
HttpServletResponse
该接口继承ServletResponse,新增的方法入下
- addCookie(Cookie cookie)
- addHeader(String name,String value);
- boolean containsHeader(String name)
- encodeRedirectURL(String url)
- 使用SessionID 对于重定向的url编码,以便用于sendRedirect()方法中
- encodeURL(String url) 使用SessionID 指定的url编码
- sendRedirect(String location) 发送一个临时的重定向响应到客户端,让客户端访问新的url
Servlet生命周期
Servlet运行在Servlet容器中,其声明周期由容器来管理,其声明周期通过javax.servlet.Servlet接口中的init(),service(),destory()方法表示Servlet的生命周期包含了4个阶段
- 加载和实例化
Servlet容器负责加载和实例化Servlet,当Servlet容器启动时,或者是在容器检测到这个Servlet来响应第一个请求时,创建Servlet实例。 - 初始化
在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象。对于每个Servlet实例,init()方法只被调用一次, - 请求处理
Servlet容器调用Servlet的service()方法对请求进行处理。service执 行之前init()方法必须成功执行。 - 服务终止
当容器检测到一个Servlet实例应该从服务中被移除的时候,容器就会调用实例的destory()方法。释放资源。
跳转
RequestDispatcher接口
该对象由Servlet容器创建,用于封装一个由路径标识的服务器资源。利用该对象可以将请求转发给其他的Servlet或jsp页面。
forword(ServletRequest req,ServletResponse resp)
该方法用于将请求从一个Servlet传递给服务器上的另外的Servlet,jsp或者html文件,在forword方法调用之后,之前在响应缓存中没有提交的内容将会被自动清除。该方法将请求转发给其他Servlet,将又被调用的Servlet负责对请求做出响应,原先Servlet执行终止。include(ServletRequest req,ServletResponse resp)
该方法用于将请求转发给其他Servlet,被调用的Servlet对该请求做出的响应将并入原来的响应对象中,原先的Servlet还可以继续输出响应信息。forword(),include()属于内部请求,浏览器地址不发生改变,客户端仅向服务器端发送一次请求
sendRedirect()
该方法由HttpServletResponse对象提供,
表示重定向到另外一个请求中。属于外部请求。重定向相当于重新向服务器发送请求,浏览器地址发送改变