提早声明:我的说的不必定对,若有错误之处,请批评指出. html
servlet能够很好地替代公共网关接口(Common Gateway Interface,CGI)脚本。一般CGI脚本是用Perl或者C语言编写的,它们老是和特定的服务器平台紧密相关。而servlet是用Java编写的,因此它们一开始就是平台无关的。这样,Java编写一次就能够在任何平台运行(write once,run anywhere)的承诺就一样能够在服务器上实现了。servlet还有一些CGI脚本所不具有的独特优势: java
但值得注意的是Servlet并不局限于Web领域(或者说是HTTP协议相关).你可能要本身去扩展javax.servlet.GenericServlet .上面第三点就是这个意思.
好比说:扩展javax.servlet.GenericServlet实现一个Servlet,搞搞电子邮件的smtp(Simple Mail Transfer Protocol 即简单邮件传输协议)服务器,你就是基于SMTP协议扩展了GenericServlet ,也许你会叫它SMTPServlet.咱们用的HttpServlet不就这个命名规范嘛.
综上所述,Servlet能够在各类协议下良好的运行应用程序. web
JSP的本质就是Servlet,或者说(是吧,开始说的是java,汗)JavaWeb开发的本质也就是Servlet+JDBC.任何性质的框架技术最底层的依然是基于他们2个.所以若是本身想写一套如SSH那样的框架技术,Java最底层的东西是必须掌握的. 数据库
Servlet被称为"服务器端小程序."是运行在服务器端的程序,用于处理以及响应客户端的请求. 编程
HTTP 目前支持 7 种请求方法: GET 、 POST 、 PUT 、 DELETE 和 TARCE,HEAD 、 OPTIONS .前四个都是客户端请求数据这类相关的方法. 小程序
我在这里只是列出HTTP的请求方法,具体的HTTP协议请参考这篇文章:http://my.oschina.net/zhaoqian/blog/90315 浏览器
Servlet是个特殊的类,这个类必须继承HttpServlet.Servlet提供了相对于HTTP数据请求的四个方法的请求(其余三个也提供了,但我懒得写了,不多用到). 缓存
事实上,HTTP这个大好青年被浪费了,大部分咱们就是使用GET/POST请求,至于PUT/DELETE都不知道被遗弃到哪里去了.但最近几年兴起的一种REST模型的WEB服务,让HTTP协议发出了第二春.具体详见:http://my.oschina.net/zhaoqian/blog/90321 安全
而诸如Struts2,SpringMVC这类的框架,也就是使用GET/POST,但工做时间久后,愈加的感受到,不少新技术,不必去追,所须要的是,搞清楚追底层的,以不变的底层去应对万变的新技术. 服务器
Servlet的示例代码:
package org.credo.test; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * <P>Project: Credo's Base</P> * <P>Description:Servlet3.0的第一个测试. </P> * <P>Copyright (c) 2012 LionCredo.All Rights Reserved.</P> * @author <a href="zhaoqianjava@qq.com">LionCredo</a> */ @WebServlet(name="firstServlet",urlPatterns="/firstServlet") public class ServletTest1 extends HttpServlet{ private static final long serialVersionUID = -2149324298582445679L; @Override public void init(ServletConfig config) throws ServletException { //初始化Servlet的时候,能够在这里完成某些初始化的方法. super.init(config); } @Override protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { //大部分时候,对于全部请求都是同样的话,能够重写HttpServlet的Service方法来替代doGet/doPost这些方法. super.service(arg0, arg1); } @Override public void destroy() { // 在销毁Servlet以前,须要完成某些资源的回收,好比关闭数据库连接等,能够写在这里. super.destroy(); } }
public abstract class javax.servlet.http
•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
===========================================
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 方法便可。
剥离了一大堆注释的源码:
package javax.servlet; import java.io.IOException; import java.util.Enumeration; public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable { private static final long serialVersionUID = 1L; //java语言的关键字,变量修饰符,若是用transient声明一个实例变量,当对象存储时,它的值不须要维持。 //Java的serialization提供了一种持久化对象实例的机制。 //当持久化对象时,可能有一个特殊的对象数据成员,咱们不想用serialization机制来保存它。 //为了在一个特定对象的一个域上关闭serialization,能够在这个域前加上关键字transient。 //当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。 private transient ServletConfig config; public GenericServlet() { //构造方法 } @Override public void destroy() { //销毁 } @Override public String getInitParameter(String name) { return getServletConfig().getInitParameter(name); } @Override public Enumeration<String> getInitParameterNames() { return getServletConfig().getInitParameterNames(); } @Override public ServletConfig getServletConfig() { return config; } */ @Override public ServletContext getServletContext() { return getServletConfig().getServletContext(); } @Override public String getServletInfo() { return ""; } @Override public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { // NOOP by default } public void log(String msg) { getServletContext().log(getServletName() + ": " + msg); } public void log(String message, Throwable t) { getServletContext().log(getServletName() + ": " + message, t); } @Override public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; @Override public String getServletName() { return config.getServletName(); } }
能够看到,HttpServlet,是基于Http协议扩展了GenericServlet的抽象类.
而 GenericServlet是实现了Servlet,ServletConfig,以及必须的Serializable序列化.下面主要看实现的2个接口,Servlet,ServletConfig都定义了那些接口.===========================================================
能够看源码,API,均可以发现servlet是一个接口.定义了五个方法.
package javax.servlet; import java.io.IOException; public interface Servlet { public void init(ServletConfig config) throws ServletException; public ServletConfig getServletConfig(); public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; public String getServletInfo(); public void destroy(); }
看上图Servlet接口中有 getServletConfig.从这个接口的定义能够结合起来.
package javax.servlet; import java.util.Enumeration; public interface ServletConfig { public String getServletName(); public ServletContext getServletContext(); public String getInitParameter(String name); public Enumeration<String> getInitParameterNames(); }
==========================================================================
具体的接口定义和抽象类的实现,能够看看源代码,不过话说回来,我如今的目的也就是搞清楚,而非是本身写,那样精力消耗太大.毕竟源码是轻易得到的,想看明白就好了.
=====================================================================================================
下一个将粗略说下HttpServletRequest , HttpServletResponse .这两个写下就知道是什么状况了.
HttpServletRequest , HttpServletResponse,在Servlet里是什么意思,一目了然.
Web基于HTTP的开发中,这两货是每天用的东西.二者都是接口.
客户端对于Servlet的每次访问请求,Servlet容器(如Tomcat)都会建立一个封装HTTP请求的对象和一个表明HTTP响应的对象,当调用Servlet的doGet或doPost方法时,这两个对象会做为参数被传递进去
HttpServletRequest对象表明客户端的请求,当客户端经过HTTP协议访问服务器时,所发出的HTTP请求消息被封装在此对象之中,经过这个对象提供的方法,便可得到客户端发出的请求信息。
具体的示例嘛...:日,不想写了,这些太简单了,随便去网上找的DEMO看啦.
读取请求参数的方法
经过HttpServletRequest对象的如下方法读取GET/POST方式下传递的参数
getParameter
getParameterValues
输出响应正文(实体内容)输出响应正文的方法
public class Servlet1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response){ response.setContentType("text/html"); PrintWriter out = response.getWriter(); String userName = request.getParameter("userName"); //经过PrintWriter类型对象out的println方法,输出内容至浏览器 out.println("username:"+userName+"<br/>"); //显式清理缓存和关闭 out.flush(); out.close(); }如上示例.
HttpServletResponse其它经常使用方法