这是一篇整理自网络的技术笔记,记录了我在早期 Java Web 开发学习过程中对 Servlet 和 WebService 两种技术的对比与理解。虽然在当今的微服务和 RESTful API 时代,这些技术已经逐渐被取代,但它们所代表的架构思想仍然值得回味。

背景

在初学 Java Web 开发的那段日子里,我经常被一个问题困扰:Servlet 和 WebService 到底有什么区别? 它们似乎都能处理 HTTP 请求、都能返回数据、都能被客户端调用,那为什么要有两种不同的技术?它们各自的适用场景又是什么?

记得那是 2014 年的冬天,我坐在出租屋的电脑前,屏幕上同时开着十几个浏览器标签页——有 CSDN 的技术博客,有 Stack Overflow 上的英文问答,还有 Oracle 官方文档的长篇大论。那时候的我,刚刚从学校出来不久,对 Java Web 的世界充满了好奇,也充满了困惑。每天下班回到住处,第一件事就是打开电脑,泡一杯茶,开始啃那些晦涩的技术文档。

带着这些疑问,我查阅了大量的资料,整理了这篇学习笔记,希望对同样在路上的朋友有所帮助。

Java Web开发技术对比

什么是 Servlet

Servlet 是 Java 对于 Web 开发而产生的一项技术,可以说 Servlet 技术是 Java 专有的。它是运行在服务器端的技术,客户端通常是浏览器,通过 HTTP 协议进行通信。

Servlet 的核心思想很简单:

  1. 接收来自客户端的 HTTP 请求
  2. 在服务器端进行业务逻辑处理
  3. 将处理结果封装为 HTTP 响应返回给客户端

你可以把 Servlet 理解为一个运行在 Web 容器(如 Tomcat)中的 Java 程序,它专门用来处理 Web 请求。

Servlet 技术是 Java 在 Web 领域的基础设施,后续的 JSP、Spring MVC 等框架,本质上都是建立在 Servlet 之上的封装和扩展。

Servlet请求处理流程

Servlet 的生命周期

理解 Servlet,首先要理解它的生命周期。一个 Servlet 从诞生到消亡,经历了以下几个阶段:

  • 加载和实例化:Web 容器负责加载 Servlet 类并创建实例。
  • 初始化:容器调用 init() 方法,Servlet 在此阶段完成资源初始化。
  • 服务:容器调用 service() 方法处理客户端请求,根据请求类型分发到 doGet()doPost()
  • 销毁:容器调用 destroy() 方法,Servlet 释放资源,结束生命周期。

我记得第一次写 Servlet 的时候,笨拙地在 doGet() 方法里拼接 HTML 字符串,用 out.println() 一行一行地输出。那种感觉就像是在用打字机写文章——原始、低效,但却让你对底层机制有了最直观的认识。

1
2
3
4
5
6
7
8
9
10
11
12
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<html><body>");
out.println("<h1>Hello, World!</h1>");
out.println("</body></html>");
}
}

这段代码现在看来可能有些粗糙,但它是我理解 Web 请求处理机制的起点。

什么是 WebService

WebService 则是在 DCOM、CORBA 等分布式技术发展之后兴起的一种远程调用技术。与 Servlet 不同,WebService 有一个国际通用的标准 —— SOAP。具体规范发布在 W3C 官方网站

SOAP(Simple Object Access Protocol)的核心目标是:

  • 实现系统的 松散耦合
  • 实现 跨平台 通信
  • 实现 与语言无关 的接口调用
  • 实现 与特定接口无关 的服务描述
  • 提供对 Web 应用程序的 可靠访问

这意味着什么呢?这意味着无论你用什么语言开发 —— Java、C#、甚至是基于 VCL 架构的 Delphi —— 你都可以开发 WebService 系统。而且,开发出来的 WebService 系统,可以被 任何客户端 调用,包括浏览器、Windows 应用程序、Java 应用等等。

WebService跨平台架构

WebService 的三大基石

要真正理解 WebService,需要理解支撑它的三大技术标准:

  • SOAP(Simple Object Access Protocol):简单对象访问协议,定义了消息的格式和传输方式。它是基于 XML 的协议,确保不同系统之间能够以统一的方式交换数据。
  • WSDL(Web Services Description Language):Web 服务描述语言,以 XML 格式描述服务的接口、方法、参数和返回值。就像一个服务的”说明书”,客户端通过读取 WSDL 就知道如何调用这个服务。
  • UDDI(Universal Description, Discovery and Integration):统一描述、发现和集成协议,用于服务的注册和发现。虽然在实际应用中 UDDI 并没有广泛流行,但它代表了一种服务治理的理想。

WebService 的核心优势

可以这么说:开发一个 WebService 系统,把它部署到互联网上,生成一个 WebService 描述文件 .wsdl(这个过程非常容易),然后全世界的任何人,使用几乎任何开发工具,引用了这个 WSDL 文件,就像引用了一个动态库的头文件一样,可以方便地调用你的 WebService 接口,就像调用本地方法一样自然。

这就是 WebService 最大的魅力所在 —— 它抹平了不同语言、不同平台之间的差异

我至今还记得第一次成功调用一个跨语言 WebService 时的兴奋。当时我用 Java 编写了一个简单的计算器服务,然后用 C# 写了一个客户端去调用它。当 C# 客户端正确返回计算结果的那一刻,我深刻地体会到了”跨平台”这几个字的分量。

1
2
3
4
5
6
7
8
9
10
11
12
@WebService
public class CalculatorService {
@WebMethod
public int add(int a, int b) {
return a + b;
}

@WebMethod
public int multiply(int a, int b) {
return a * b;
}
}

只需要几个注解,一个标准的 WebService 就诞生了。WSDL 文件自动生成,任何语言的客户端都可以通过它来 discover 和 invoke 这些方法。

Servlet 与 WebService 的详细对比

下面我将从多个维度来对比这两种技术:

1. 调用方式

  • WebService:通常是基于 HTTP 的远程方法调用(RMI),号称可以返回远程对象。一般来说,客户端可以像调用本地方法一样调用 WebService 的方法。
  • Servlet:通过 HTTP 请求访问,通常的访问方式为 http://ip/servlet/servletname,需要手动处理请求参数和响应数据。

2. 数据格式

  • WebService:使用的 SOAP 是一种 通用标准格式,不管什么样的客户端都可以解析。
  • Servlet:如果返回 XML,那个 XML 的描述框架是你自己定的。你能确保别人都能看明白你的 XML 格式含义吗?

3. 开发复杂度

  • WebService:并不复杂,开发起来甚至比 Servlet 还简单。有了成熟的框架(如 Apache CXF、Axis2 等),几个注解就能搞定。
  • Servlet:需要手动处理 HTTP 请求和响应,对于复杂数据结构的传递比较麻烦。

4. 复杂数据传递

如果客户端需要传递一个复杂的多维数组给服务端,Servlet 怎么办?你需要手动序列化、手动解析,非常繁琐。而 WebService 则天然支持复杂对象的传递。

5. 核心优势总结

对比维度 Servlet WebService
技术归属 Java 专有 国际标准(SOAP/WSDL)
跨平台性 否(Java 体系内) 是(跨语言、跨平台)
数据格式标准 自定义 标准 SOAP 协议
复杂对象传递 困难 天然支持
异构系统集成 不友好 友好

实际项目中的应用

在我们的一个实际项目中,一个 Java Web 项目需要调用另一个 Java Web 项目的方法。这时候我们可以选择两种方案:

方案一:使用 Servlet + HttpClient

1
2
3
4
5
6
7
8
9
10
11
// 使用 HttpClient 访问 Servlet
String url = "http://ip/servlet/servletname";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
// 设置请求参数
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("action", "getUserInfo"));
params.add(new BasicNameValuePair("userId", "12345"));
post.setEntity(new UrlEncodedFormEntity(params));
// 执行请求并处理响应
HttpResponse response = client.execute(post);

这种方式简单直接,适合两个系统都是 Java 技术栈的场景。但它的问题也很明显——一旦对方系统换成 .NET 或 Python,你就得重新协商数据格式、重新编写解析逻辑。

方案二:使用 WebService

如果未来有可能有其他语言(如 .NET、Python)的系统需要接入,那么使用 WebService 会是更好的选择。WSDL 文件就是最好的契约,任何语言都可以通过它生成客户端代码,无需手动拼接 URL 和解析响应。

分布式技术演进

深入理解:两者不在同一个层次

其实,Servlet 和 WebService 根本不是一个层次上的东西,它们不可比

  • Servlet 定义的是一套接口规范,目的是实现 Java 在 Web 上的动态访问(不止局限于 HTTP 协议,至少还有 FTP 协议)。
  • WebService 定义的是一套标准体系(SOAP / UDDI / WSDL……比 API 更抽象),与语言无关、协议无关、平台无关,目的是实现基于 Service 的组件化架构(相对于 EJB、DCOM 等)。

从 WebService 的设计目的不难看出,它的复杂度是相当大的。EJB 需要考虑的问题,WebService 都需要进行实现,包括 安全性、事务性 等等……远不止上面列出的 SOAP / UDDI / WSDL 这些表面协议。

打个比方来说,Servlet 像是”砖块”——它是构建 Web 应用的基本材料;而 WebService 更像是”建筑蓝图”——它定义了不同建筑之间如何连接和交互。

时代变迁与反思

写下这篇笔记的时候是 2014 年。那时候,Java Web 开发还处在 Servlet/JSP 与 WebService 并存的时代。我每天在公司的项目里,既写 Servlet 处理前端请求,又写 WebService 对接外部系统。两种技术交替使用,让我对它们各自的优缺点有了切身的体会。

如今回头来看,技术世界已经发生了翻天覆地的变化:

  • Servlet 已经退居幕后,成为了 Spring MVC、Spring Boot 等框架的底层基础设施,开发者很少再直接编写 Servlet 代码。Spring 的 DispatcherServlet 本质上还是一个 Servlet,但我们再也无需关心它的生命周期了。
  • WebService(SOAP) 也已经被更轻量的 RESTful API 所取代。JSON 替代了 XML 作为主流的数据交换格式,HTTP 动词(GET/POST/PUT/DELETE)替代了 SOAP 信封。曾经冗长的 XML 消息体,现在变成了简洁的 JSON 对象。
  • 微服务架构 的兴起,让服务间的通信变得更加灵活和高效。gRPC、GraphQL 等新技术层出不穷。Spring Cloud、Dubbo 等框架让服务治理变得前所未有的简单。

但无论如何变迁,理解这些基础技术的本质和它们要解决的问题,对于我们理解当今的技术架构仍然有着重要的意义。每一种技术的出现,都是为了解决特定时代下的特定问题。理解了它们的来龙去脉,我们才能更好地把握技术的演进方向。

技术演进时间线

小结

  1. WebService 通常是基于 HTTP 的远程方法调用(RMI),号称可以返回远程对象,一般来说客户端可以像调用本地方法一样调用 WebService 的方法。
  2. WebService 使用的 SOAP 是一种通用的格式,不管什么样的客户端都可以解析。
  3. 如果你用 Servlet 返回 XML,那个 XML 的描述框架就是你定的。你能确保别人都能看明白你的 XML 格式含义?
  4. WebService 并不复杂,开发起来甚至比 Servlet 还简单。
  5. 如果客户端需要传递一个复杂的多维数组给服务端,Servlet 处理起来会比较麻烦。
  6. WebService 的优点在于可以传递对象(其实是结构化的数据),从而对异构系统来说更有优势。

最核心的一点:WebService 的方法返回消息是有标准的(大家通用,谁都能看懂),而用 Servlet 所返回的 XML,是没有标准的。


转载出处:http://xuyuanshuaaa.iteye.com/blog/1134677