Servlet的优点:
servlet可以很好地替代公共网关接口(Common Gateway Interface,CGI)脚本。通常CGI脚本是用Perl或者C语言编写的,它们总是和特定的服务器平台紧密相关。而servlet是用Java编写的,所以它们一开始就是平台无关的。这样,Java编写一次就可以在任何平台运行(write once,run anywhere)的承诺就同样可以在服务器上实现了。servlet还有一些CGI脚本所不具备的独特优点:
- 1、servlet是持久的。servlet只需Web服务器加载一次,而且可以在不同请求之间保持服务(例如一次数据库连接)。与之相反,CGI脚本是短暂的、瞬态的。每一次对CGI脚本的请求,都会使Web服务器加载并执行该脚本。一旦这个CGI脚本运行结束,它就会被从内存中清除,然后将结果返回到客户端。CGI脚本的每一次使用,都会造成程序初始化过程(例如连接数据库)的重复执行。
- 2、servlet是与平台无关的。如前所述,servlet是用Java编写的,它自然也继承了Java的平台无关性。
- 3、servlet是可扩展的。由于servlet是用Java编写的,它就具备了Java所能带来的所有优点。Java是健壮的、面向对象的编程语言,它很容易扩展以适应你的需求。servlet自然也具备了这些特征。
- 4、servlet是安全的。从外界调用一个servlet的惟一方法就是通过Web服务器。这提供了高水平的安全性保障,尤其是在你的Web服务器有防火墙保护的时候。
- 5、setvlet可以在多种多样的客户机上使用。由于servlet是用Java编写的,所以你可以很方便地在HTML中使用它们,就像你使用applet一样。
但值得注意的是Servlet并不局限于Web领域(或者说是HTTP协议相关).你可能要自己去扩展javax.servlet.GenericServlet .上面第三点就是这个意思.
比如说:扩展javax.servlet.GenericServlet实现一个Servlet,搞搞电子邮件的smtp(Simple Mail Transfer Protocol 即简单邮件传输协议)服务器,你就是基于SMTP协议扩展了GenericServlet ,也许你会叫它SMTPServlet.我们用的HttpServlet不就这个命名规范嘛.
综上所述,Servlet可以在各种协议下良好的运行应用程序.
也许现在很多人不再写Servlet,但Servlet是心脏,Servlet放在刚出世的时候,还是非常NB的.到现在,各种成熟好用的东西很多了.但不能忘本.....再深点说
为什么要这么设计,体现了什么?我还真是说不上来了,我觉得上面的几点也已经表明为什么了.就是Java对协议的一个设计.....
JSP的本质就是Servlet,或者说(是吧,开始说的是java,汗)JavaWeb开发的本质也就是Servlet+JDBC.任何性质的框架技术最底层的依然是基于他们2个.因此如果自己想写一套如SSH那样的框架技术,Java最底层的东西是必须掌握的.
Servlet被称为"服务器端小程序."是运行在服务器端的程序,用于处理以及响应客户端的请求.
HTTP 目前支持 7 种请求方法: GET 、 POST 、 PUT 、 DELETE 和 TARCE,HEAD 、 OPTIONS .前四个都是客户端请求数据这类相关的方法.
- GET 请求获取由Request-URI所标识的资源。
- POST 在Request-URI所标识的资源后附加新的数据。
- PUT 请求服务器存储一个资源,并用Request-URI作为其标识。
- DELETE 请求服务器删除由Request-URI所标识的资源。
- TRACE 请求服务器回送收到的请求信息,主要用语测试或诊断。
- HEAD 请求获取由Request-URI所标识的资源的响应消息报头。
- OPTIONS 请求查询服务器的性能,或查询与资源相关的选项和需求。
我在这里只是列出HTTP的请求方法,具体的HTTP协议请参考这篇文章:http://my.oschina.net/zhaoqian/blog/90315
Servlet是个特殊的类,这个类必须继承HttpServlet.Servlet提供了相对于HTTP数据请求的四个方法的请求(其他三个也提供了,但我懒得写了,很少用到).
- doGet:用于响应上面绿色字体的GET请求.
- doPost:用于响应客户端的POST请求.
- doPut:用于响应客户端的PUT请求.
- doDelete:用于响应客户端的Delete请求.
事实上,HTTP这个大好青年被浪费了,大部分我们就是使用GET/POST请求,至于PUT/DELETE都不知道被遗弃到哪里去了.但最近几年兴起的一种REST模型的WEB服务,让HTTP协议发出了第二春.具体详见:http://my.oschina.net/zhaoqian/blog/90321
而诸如Struts2,SpringMVC这类的框架,也就是使用GET/POST,但工作时间久后,越发的感觉到,很多新技术,没必要去追,所需要的是,搞清楚追底层的,以不变的底层去应对万变的新技术.
Servlet的示例代码:
01 | package org.credo.test; |
03 | import java.io.IOException; |
05 | import javax.servlet.ServletConfig; |
06 | import javax.servlet.ServletException; |
07 | import javax.servlet.annotation.WebServlet; |
08 | import javax.servlet.http.HttpServlet; |
09 | import javax.servlet.http.HttpServletRequest; |
10 | import javax.servlet.http.HttpServletResponse; |
13 | * <P>Project: Credo's Base</P> |
14 | * <P>Description:Servlet3.0的第一个测试. </P> |
15 | * <P>Copyright (c) 2012 LionCredo.All Rights Reserved.</P> |
16 | * @author <a href="zhaoqianjava@qq.com">LionCredo</a> |
18 | @WebServlet (name= "firstServlet" ,urlPatterns= "/firstServlet" ) |
19 | public class ServletTest1 extends HttpServlet{ |
21 | private static final long serialVersionUID = -2149324298582445679L; |
24 | public void init(ServletConfig config) throws ServletException { |
30 | protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { |
32 | super .service(arg0, arg1); |
36 | public void destroy() { |
HttpServlet
public abstract class javax.servlet.http
Extends: GenericServlet
Implements: java.io.Serializable
提供将要被子类化以创建适用于 Web 站点的 HTTP servlet 的抽象类。HttpServlet 的子类至少必须重写一个方法,该方法通常是以下这些方法之一:
•doGet,如果 servlet 支持 HTTP GET 请求
•doPost,用于 HTTP POST 请求
•doPut,用于 HTTP PUT 请求
•doDelete,用于 HTTP DELETE 请求
•init 和 destroy,用于管理 servlet 的生命周期内保存的资源
•getServletInfo,servlet 使用它提供有关其自身的信息
几乎没有理由重写 service 方法。service 通过将标准 HTTP 请求分发给每个 HTTP 请求类型的处理程序方法(上面列出的 doXXX 方法)来处理它们。
同样,几乎没有理由重写 doOptions 和 doTrace 方法。
servlet 通常运行在多线程服务器上,因此应该意识到 servlet 必须处理并发请求并小心地同步对共享资源的访问。共享资源包括内存数据(比如实例或类变量)和外部对象(比如文件、数据库连接和网络连接)。有关在 Java 程序中处理多个线程的更多信息,请参见 Java Tutorial on Multithreaded Programming。
上面是查阅官方的API所得的说明,实际上javaweb开发中,很少有web开发完全严格的使用Http协议.所以说大好青年浪费不是没道理的,但商业的实现手段就是商业的实现手段,技术永远是其次的.当然,REST这个嘛,第二春....再详细的方法就看HttpServlet的源码或者API.
另外,为什么不重写servlet的service方法有更详细的文章:http://my.oschina.net/dtkking/blog/89443
===========================================
一个Servlet继承抽象类HttpServlet,而HttpServlet继承GenericServlet,
abstract GenericServlet
Implements: Servlet, ServletConfig, java.io.Serializable
Extended by: HttpServlet
定义一般的、与协议无关的 servlet。要编写用于 Web 上的 HTTP servlet,请改为扩展 javax.servlet.http.HttpServlet。
GenericServlet 实现 Servlet 和 ServletConfig 接口。servlet 可以直接扩展 GenericServlet,尽管扩展特定于协议的子类(比如 HttpServlet)更为常见。
GenericServlet 使编写 servlet 变得更容易。它提供生命周期方法 init 和 destroy 的简单版本,以及 ServletConfig 接口中的方法的简单版本。GenericServlet 还实现 log 方法,在 ServletContext 接口中对此进行了声明。
要编写一般的 servlet,只需重写抽象 service 方法即可。
剥离了一大堆注释的源码:
01 | package javax.servlet; |
03 | import java.io.IOException; |
04 | import java.util.Enumeration; |
06 | public abstract class GenericServlet implements Servlet, ServletConfig, |
07 | java.io.Serializable { |
09 | private static final long serialVersionUID = 1L; |
16 | private transient ServletConfig config; |
18 | public GenericServlet() { |
23 | public void destroy() { |
28 | public String getInitParameter(String name) { |
29 | return getServletConfig().getInitParameter(name); |
33 | public Enumeration<String> getInitParameterNames() { |
34 | return getServletConfig().getInitParameterNames(); |
38 | public ServletConfig getServletConfig() { |
44 | public ServletContext getServletContext() { |
45 | return getServletConfig().getServletContext(); |
49 | public String getServletInfo() { |
54 | public void init(ServletConfig config) throws ServletException { |
59 | public void init() throws ServletException { |
63 | public void log(String msg) { |
64 | getServletContext().log(getServletName() + ": " + msg); |
67 | public void log(String message, Throwable t) { |
68 | getServletContext().log(getServletName() + ": " + message, t); |
72 | public abstract void service(ServletRequest req, ServletResponse res) |
73 | throws ServletException, IOException; |
76 | public String getServletName() { |
77 | return config.getServletName(); |
可以看到,HttpServlet,是基于Http协议扩展了GenericServlet的抽象类.
而
GenericServlet是实现了Servlet,ServletConfig,以及必须的
Serializable序列化.下面主要看实现的2个接口,Servlet,ServletConfig都定义了那些接口.
===========================================================
public interface javax.servlet
Implemented by: FacesServlet, GenericServlet, JspPage
定义所有 servlet 都必须实现的方法。
servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
要实现此接口,可以编写一个扩展 javax.servlet.GenericServlet 的一般 servlet,或者编写一个扩展 javax.servlet.http.HttpServlet 的 HTTP servlet。
此接口定义了初始化 servlet 的方法、为请求提供服务的方法和从服务器移除 servlet 的方法。这些方法称为生命周期方法,它们是按以下顺序调用的:
1.构造 servlet,然后使用 init 方法将其初始化。
2.处理来自客户端的对 service 方法的所有调用。
3.从服务中取出 servlet,然后使用 destroy 方法销毁它,最后进行垃圾回收并终止它。
除了生命周期方法之外,此接口还提供了 getServletConfig 方法和 getServletInfo 方法,servlet 可使用前一种方法获得任何启动信息,而后一种方法允许 servlet 返回有关其自身的基本信息,比如作者、版本和版权。
可以看源码,API,都可以发现servlet是一个接口.定义了五个方法.
01 | package javax.servlet; |
03 | import java.io.IOException; |
05 | public interface Servlet { |
07 | public void init(ServletConfig config) throws ServletException; |
09 | public ServletConfig getServletConfig(); |
11 | public void service(ServletRequest req, ServletResponse res) |
12 | throws ServletException, IOException; |
14 | public String getServletInfo(); |
16 | public void destroy(); |
public interface javax.servlet ServletConfig
Implemented by: GenericServlet
servlet 容器使用的 servlet 配置对象,该对象在初始化期间将信息传递给 servlet。
看上图Servlet接口中有 getServletConfig.从这个接口的定义可以结合起来.
01 | package javax.servlet; |
03 | import java.util.Enumeration; |
05 | public interface ServletConfig { |
07 | public String getServletName(); |
09 | public ServletContext getServletContext(); |
11 | public String getInitParameter(String name); |
13 | public Enumeration<String> getInitParameterNames(); |
==========================================================================
可以看到,正常下我们使用的的 Servlet extend httpServlet,
然后实质上的httpServlet extends GenericServlet ,
而GenericServlet实现implements
1.接口Servlet, 2.接口ServletConfig,以及 3.java.io.Serializable.
具体的接口定义和抽象类的实现,可以看看源代码,不过话说回来,我现在的目的也就是搞清楚,而非是自己写,那样精力消耗太大.毕竟源码是轻易获得的,想看明白就行了.
=====================================================================================================
HttpServletRequest , HttpServletResponse
下一个将粗略说下HttpServletRequest , HttpServletResponse .这两个写下就知道是什么情况了.
HttpServletRequest , HttpServletResponse,在Servlet里是什么意思,一目了然.
Web基于HTTP的开发中,这两货是天天用的东西.两者都是接口.
HttpServletRequest, HttpServletResponse对象简介:
客户端对于Servlet的每次访问请求,Servlet容器(如Tomcat)都会创建一个封装HTTP请求的对象和一个代表HTTP响应的对象,当调用Servlet的doGet或doPost方法时,这两个对象会作为参数被传递进去
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,所发出的HTTP请求消息被封装在此对象之中,通过这个对象提供的方法,即可获得客户端发出的请求信息。
HttpServletRequest对象最基本的应用是获取浏览器传递给Web服务器的请求参数信息
请求参数:
▪GET方式下,URL地址后的附加信息
▪POST方式下,HTTP请求消息中的实体内容部分
具体的示例嘛...:日,不想写了,这些太简单了,随便去网上找的DEMO看啦.
读取请求参数的方法
通过HttpServletRequest对象的以下方法读取GET/POST方式下传递的参数
getParameter
getParameterValues
HttpServletResponse对象代表服务器端对客户端的响应,用于封装HTTP响应消息
输出响应正文(实体内容)输出响应正文的方法
▪getWriter
–返回一个(文本)字符输出流对象
–专用于输出内容为文本字符的网页文档
▪getOutPutStream
–返回一个字节输出流对象
–如果要输出二进制格式的响应正文,应该使用该方法
01 | public class Servlet1 extends HttpServlet { |
02 | public void doGet(HttpServletRequest request, HttpServletResponse response){ |
03 | response.setContentType( "text/html" ); |
04 | PrintWriter out = response.getWriter(); |
05 | String userName = request.getParameter( "userName" ); |
07 | out.println( "username:" +userName+ "<br/>" ); |
如上示例.
HttpServletResponse其它常用方法
}字符集编码问题
}重定向
具体百度下吧,不想写了,我遁了.......