精通Servlet研究,HttpServlet的实现追究
2012-12-09 17:32
288 查看
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请求服务器回送收到的请求信息,主要用语测试或诊断。
[b]HEAD请求获取由Request-URI所标识的资源的响应消息报头。[/b]
[b]OPTIONS请求查询服务器的性能,或查询与资源相关的选项和需求。[/b]
我在这里只是列出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的示例代码:
Extends:GenericServlet
Implements:java.io.Serializable
提供将要被子类化以创建适用于Web站点的HTTPservlet的抽象类。HttpServlet的子类至少必须重写一个方法,该方法通常是以下这些方法之一:
•doGet,如果servlet支持HTTPGET请求
•doPost,用于HTTPPOST请求
•doPut,用于HTTPPUT请求
•doDelete,用于HTTPDELETE请求
•init和destroy,用于管理servlet的生命周期内保存的资源
•getServletInfo,servlet使用它提供有关其自身的信息
几乎没有理由重写service方法。service通过将标准HTTP请求分发给每个HTTP请求类型的处理程序方法(上面列出的doXXX方法)来处理它们。
同样,几乎没有理由重写doOptions和doTrace方法。
servlet通常运行在多线程服务器上,因此应该意识到servlet必须处理并发请求并小心地同步对共享资源的访问。共享资源包括内存数据(比如实例或类变量)和外部对象(比如文件、数据库连接和网络连接)。有关在Java程序中处理多个线程的更多信息,请参见JavaTutorialonMultithreadedProgramming。
上面是查阅官方的API所得的说明,大概可以看看,虽说不官方推荐重写Service方法,但实际上javaweb开发中,很少有web开发完全严格的使用Http协议.所以说大好青年浪费不是没道理的,但商业的实现手段就是商业的实现手段,技术永远是其次的.当然,REST这个嘛,第二春....再详细的方法就看HttpServlet的源码或者API.
===========================================
Extendedby:HttpServlet
定义一般的、与协议无关的servlet。要编写用于Web上的HTTPservlet,请改为扩展javax.servlet.http.HttpServlet。
GenericServlet实现Servlet和ServletConfig接口。servlet可以直接扩展GenericServlet,尽管扩展特定于协议的子类(比如HttpServlet)更为常见。
GenericServlet使编写servlet变得更容易。它提供生命周期方法init和destroy的简单版本,以及ServletConfig接口中的方法的简单版本。GenericServlet还实现log方法,在ServletContext接口中对此进行了声明。
要编写一般的servlet,只需重写抽象service方法即可。
剥离了一大堆注释的源码:
可以看到,HttpServlet,是基于Http协议扩展了GenericServlet的抽象类.
而GenericServlet是实现了Servlet,ServletConfig,以及必须的Serializable序列化.下面主要看实现的2个接口,Servlet,ServletConfig都定义了那些接口.
===========================================================
定义所有servlet都必须实现的方法。
servlet是运行在Web服务器中的小型Java程序。servlet通常通过HTTP(超文本传输协议)接收和响应来自Web客户端的请求。
要实现此接口,可以编写一个扩展javax.servlet.GenericServlet的一般servlet,或者编写一个扩展javax.servlet.http.HttpServlet的HTTPservlet。
此接口定义了初始化servlet的方法、为请求提供服务的方法和从服务器移除servlet的方法。这些方法称为生命周期方法,它们是按以下顺序调用的:
1.构造servlet,然后使用init方法将其初始化。
2.处理来自客户端的对service方法的所有调用。
3.从服务中取出servlet,然后使用destroy方法销毁它,最后进行垃圾回收并终止它。
除了生命周期方法之外,此接口还提供了getServletConfig方法和getServletInfo方法,servlet可使用前一种方法获得任何启动信息,而后一种方法允许servlet返回有关其自身的基本信息,比如作者、版本和版权。
可以看源码,API,都可以发现servlet是一个接口.定义了五个方法.
servlet容器使用的servlet配置对象,该对象在初始化期间将信息传递给servlet。
看上图Servlet接口中有getServletConfig.从这个接口的定义可以结合起来.
==========================================================================
1.接口Servlet,2.接口ServletConfig,以及3.java.io.Serializable.
具体的接口定义和抽象类的实现,可以看看源代码,不过话说回来,我现在的目的也就是搞清楚,而非是自己写,那样精力消耗太大.毕竟源码是轻易获得的,想看明白就行了.
=====================================================================================================
HttpServletRequest,HttpServletResponse,在Servlet里是什么意思,一目了然.
Web基于HTTP的开发中,这两货是天天用的东西.两者都是接口.
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,所发出的HTTP请求消息被封装在此对象之中,通过这个对象提供的方法,即可获得客户端发出的请求信息。
▪GET方式下,URL地址后的附加信息
▪POST方式下,HTTP请求消息中的实体内容部分
具体的示例嘛...:日,不想写了,这些太简单了,随便去网上找的DEMO看啦.
读取请求参数的方法
通过HttpServletRequest对象的以下方法读取GET/POST方式下传递的参数
getParameter
getParameterValues
▪getWriter
返回一个(文本)字符输出流对象
专用于输出内容为文本字符的网页文档
▪getOutPutStream
返回一个字节输出流对象
如果要输出二进制格式的响应正文,应该使用该方法
如上示例.
HttpServletResponse其它常用方法
}字符集编码问题
}重定向
Servlet被称为"服务器端小程序."是运行在服务器端的程序,用于处理以及响应客户端的请求.
HTTP目前支持7种请求方法:GET、POST、PUT、DELETE和TARCE,HEAD、OPTIONS.前四个都是客户端请求数据这类相关的方法.
GET请求获取由Request-URI所标识的资源。
POST在Request-URI所标识的资源后附加新的数据。
PUT请求服务器存储一个资源,并用Request-URI作为其标识。
DELETE请求服务器删除由Request-URI所标识的资源。
TRACE请求服务器回送收到的请求信息,主要用语测试或诊断。
[b]HEAD请求获取由Request-URI所标识的资源的响应消息报头。[/b]
[b]OPTIONS请求查询服务器的性能,或查询与资源相关的选项和需求。[/b]
我在这里只是列出HTTP的请求方法,具体的HTTP协议请参考这篇文章:
Servlet是个特殊的类,这个类必须继承HttpServlet.Servlet提供了相对于HTTP数据请求的四个方法的请求(其他三个也提供了,但我懒得写了,很少用到).
doGet:用于响应上面绿色字体的GET请求.
doPost:用于响应客户端的POST请求.
doPut:用于响应客户端的PUT请求.
doDelete:用于响应客户端的Delete请求.
事实上,HTTP这个大好青年被浪费了,大部分我们就是使用GET/POST请求,至于PUT/DELETE都不知道被遗弃到哪里去了.但最近几年兴起的一种REST模型的WEB服务,让HTTP协议发出了第二春.具体详见:
而诸如Struts2,SpringMVC这类的框架,也就是使用GET/POST,但工作时间久后,越发的感觉到,很多新技术,没必要去追,所需要的是,搞清楚追底层的,以不变的底层去应对万变的新技术.
Servlet的示例代码:
01 | package org.credo.test; |
02 |
03 | import java.io.IOException; |
04 |
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; |
11 |
12 | /** |
13 | *<P>Project:Credo'sBase</P> |
14 | *<P>Description:Servlet3.0的第一个测试.</P> |
15 | *<P>Copyright(c)2012LionCredo.AllRightsReserved.</P> |
16 | *@author<ahref="zhaoqianjava@qq.com">LionCredo</a> |
17 | */ |
18 | @WebServlet (name= "firstServlet" ,urlPatterns= "/firstServlet" ) |
19 | public class ServletTest1 extends HttpServlet{ |
20 |
21 | private static final long serialVersionUID=-2149324298582445679L; |
22 |
23 | @Override |
24 | public void init(ServletConfigconfig) throws ServletException{ |
25 | //初始化Servlet的时候,可以在这里完成某些初始化的方法. |
26 | super .init(config); |
27 | } |
28 |
29 | @Override |
30 | protected void service(HttpServletRequestarg0,HttpServletResponsearg1) throws ServletException,IOException{ |
31 | //大部分时候,对于所有请求都是一样的话,可以重写HttpServlet的Service方法来替代doGet/doPost这些方法. |
32 | super .service(arg0,arg1); |
33 | } |
34 |
35 | @Override |
36 | public void destroy(){ |
37 | //在销毁Servlet之前,需要完成某些资源的回收,比如关闭数据库链接等,可以写在这里. |
38 | super .destroy(); |
39 | } |
40 | } |
HttpServlet
publicabstractclassjavax.servlet.httpExtends:GenericServlet
Implements:java.io.Serializable
提供将要被子类化以创建适用于Web站点的HTTPservlet的抽象类。HttpServlet的子类至少必须重写一个方法,该方法通常是以下这些方法之一:
•doGet,如果servlet支持HTTPGET请求
•doPost,用于HTTPPOST请求
•doPut,用于HTTPPUT请求
•doDelete,用于HTTPDELETE请求
•init和destroy,用于管理servlet的生命周期内保存的资源
•getServletInfo,servlet使用它提供有关其自身的信息
几乎没有理由重写service方法。service通过将标准HTTP请求分发给每个HTTP请求类型的处理程序方法(上面列出的doXXX方法)来处理它们。
同样,几乎没有理由重写doOptions和doTrace方法。
servlet通常运行在多线程服务器上,因此应该意识到servlet必须处理并发请求并小心地同步对共享资源的访问。共享资源包括内存数据(比如实例或类变量)和外部对象(比如文件、数据库连接和网络连接)。有关在Java程序中处理多个线程的更多信息,请参见JavaTutorialonMultithreadedProgramming。
上面是查阅官方的API所得的说明,大概可以看看,虽说不官方推荐重写Service方法,但实际上javaweb开发中,很少有web开发完全严格的使用Http协议.所以说大好青年浪费不是没道理的,但商业的实现手段就是商业的实现手段,技术永远是其次的.当然,REST这个嘛,第二春....再详细的方法就看HttpServlet的源码或者API.
===========================================
一个Servlet继承抽象类HttpServlet,而HttpServlet继承GenericServlet,
abstractGenericServlet
Implements:Servlet,ServletConfig,java.io.SerializableExtendedby:HttpServlet
定义一般的、与协议无关的servlet。要编写用于Web上的HTTPservlet,请改为扩展javax.servlet.http.HttpServlet。
GenericServlet实现Servlet和ServletConfig接口。servlet可以直接扩展GenericServlet,尽管扩展特定于协议的子类(比如HttpServlet)更为常见。
GenericServlet使编写servlet变得更容易。它提供生命周期方法init和destroy的简单版本,以及ServletConfig接口中的方法的简单版本。GenericServlet还实现log方法,在ServletContext接口中对此进行了声明。
要编写一般的servlet,只需重写抽象service方法即可。
剥离了一大堆注释的源码:
01 | package javax.servlet; |
02 |
03 | import java.io.IOException; |
04 | import java.util.Enumeration; |
05 |
06 | public abstract class GenericServlet implements Servlet,ServletConfig, |
07 | java.io.Serializable{ |
08 |
09 | private static final long serialVersionUID=1L; |
10 |
11 | //java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。 |
12 | //Java的serialization提供了一种持久化对象实例的机制。 |
13 | //当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。 |
14 | //为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。 |
15 | //当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。 |
16 | private transient ServletConfigconfig; |
17 |
18 | public GenericServlet(){ |
19 | //构造方法 |
20 | } |
21 |
22 | @Override |
23 | public void destroy(){ |
24 | //销毁 |
25 | } |
26 |
27 | @Override |
28 | public StringgetInitParameter(Stringname){ |
29 | return getServletConfig().getInitParameter(name); |
30 | } |
31 |
32 | @Override |
33 | public Enumeration<String>getInitParameterNames(){ |
34 | return getServletConfig().getInitParameterNames(); |
35 | } |
36 |
37 | @Override |
38 | public ServletConfiggetServletConfig(){ |
39 | return config; |
40 | } |
41 |
42 | */ |
43 | @Override |
44 | public ServletContextgetServletContext(){ |
45 | return getServletConfig().getServletContext(); |
46 | } |
47 |
48 | @Override |
49 | public StringgetServletInfo(){ |
50 | return "" ; |
51 | } |
52 |
53 | @Override |
54 | public void init(ServletConfigconfig) throws ServletException{ |
55 | this .config=config; |
56 | this .init(); |
57 | } |
58 |
59 | public void init() throws ServletException{ |
60 | //NOOPbydefault |
61 | } |
62 |
63 | public void log(Stringmsg){ |
64 | getServletContext().log(getServletName()+ ":" +msg); |
65 | } |
66 |
67 | public void log(Stringmessage,Throwablet){ |
68 | getServletContext().log(getServletName()+ ":" +message,t); |
69 | } |
70 |
71 | @Override |
72 | public abstract void service(ServletRequestreq,ServletResponseres) |
73 | throws ServletException,IOException; |
74 |
75 | @Override |
76 | public StringgetServletName(){ |
77 | return config.getServletName(); |
78 | } |
79 | } |
而GenericServlet是实现了Servlet,ServletConfig,以及必须的Serializable序列化.下面主要看实现的2个接口,Servlet,ServletConfig都定义了那些接口.
===========================================================
publicinterfacejavax.servlet
Implementedby:FacesServlet,GenericServlet,JspPage定义所有servlet都必须实现的方法。
servlet是运行在Web服务器中的小型Java程序。servlet通常通过HTTP(超文本传输协议)接收和响应来自Web客户端的请求。
要实现此接口,可以编写一个扩展javax.servlet.GenericServlet的一般servlet,或者编写一个扩展javax.servlet.http.HttpServlet的HTTPservlet。
此接口定义了初始化servlet的方法、为请求提供服务的方法和从服务器移除servlet的方法。这些方法称为生命周期方法,它们是按以下顺序调用的:
1.构造servlet,然后使用init方法将其初始化。
2.处理来自客户端的对service方法的所有调用。
3.从服务中取出servlet,然后使用destroy方法销毁它,最后进行垃圾回收并终止它。
除了生命周期方法之外,此接口还提供了getServletConfig方法和getServletInfo方法,servlet可使用前一种方法获得任何启动信息,而后一种方法允许servlet返回有关其自身的基本信息,比如作者、版本和版权。
可以看源码,API,都可以发现servlet是一个接口.定义了五个方法.
01 | package javax.servlet; |
02 |
03 | import java.io.IOException; |
04 |
05 | public interface Servlet{ |
06 |
07 | public void init(ServletConfigconfig) throws ServletException; |
08 |
09 | public ServletConfiggetServletConfig(); |
10 |
11 | public void service(ServletRequestreq,ServletResponseres) |
12 | throws ServletException,IOException; |
13 |
14 | public StringgetServletInfo(); |
15 |
16 | public void destroy(); |
17 | } |
publicinterfacejavax.servletServletConfig
Implementedby:GenericServletservlet容器使用的servlet配置对象,该对象在初始化期间将信息传递给servlet。
看上图Servlet接口中有getServletConfig.从这个接口的定义可以结合起来.
01 | package javax.servlet; |
02 |
03 | import java.util.Enumeration; |
04 |
05 | public interface ServletConfig{ |
06 |
07 | public StringgetServletName(); |
08 |
09 | public ServletContextgetServletContext(); |
10 |
11 | public StringgetInitParameter(Stringname); |
12 |
13 | public Enumeration<String>getInitParameterNames(); |
14 | } |
可以看到,正常下我们使用的的ServletextendhttpServlet,
然后实质上的httpServletextendsGenericServlet,
而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(HttpServletRequestrequest,HttpServletResponseresponse){ |
03 | response.setContentType( "text/html" ); |
04 | PrintWriterout=response.getWriter(); |
05 | StringuserName=request.getParameter( "userName" ); |
06 | //通过PrintWriter类型对象out的println方法,输出内容至浏览器 |
07 | out.println( "username:" +userName+ "<br/>" ); |
08 | //显式清理缓存和关闭 |
09 | out.flush(); |
10 | out.close(); |
11 | } |
HttpServletResponse其它常用方法
}字符集编码问题
}重定向
相关文章推荐
- Servlet研究,HttpServlet的实现
- 用 C++ 实现类似于 JAVA HttpServlet 的编程接口
- HttpServletRequestWrapper 实现xss注入
- 用C++实现类似于JAVA HttpServlet 的编程接口
- Http方式下载-Servlet实现
- 精研Servlet,HttpServlet的实现追究
- Response对象、HttpServletResponse简介、处理字节编码问题、实现动态文件下载
- HTTP请求响应头信息|用Servlet如何实现验证码
- 【Java Servlet 开发系列之二】创建WebApp详细步骤,通过Servlet实现http简单交互
- 使用common-fileUpload和 Spring中MultipartHttpServletRequest实现文件上传
- 继承HttpServletRequestWrapper以实现在Filter中修改HttpServletRequest的参数
- 【转】HttpServletRequestWrapper 实现xss注入
- HttpServletRequest和HttpServletResponse实现登录(附乱码处理代码)(2017.9.28第一次修改版)
- 用java的servlet实现http访问mongodb中的文件
- 继承HttpServletRequestWrapper以实现在Filter中修改HttpServletRequest的参数
- Spring中MultipartHttpServletRequest实现文件上传
- 精研Servlet,HttpServlet的实现追究
- Servlet继承HttpServlet重写service方法的实现!
- 不同框架实现的WebService的服务端获取HttpServletRequest的方法
- servlet实现http通信基础