Java网络02 Servlet开胃酒

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

 

Tomcat初次尝试中,我们搭建了用于测试Servlet和JSP的基本环境。我们现在要转向网络应用的具体开发。

 

厨师

Web服务器的基本工作方式是请求-处理-回复。请求和回复是在网络上,以HTTP协议为基础的通信(参考HTTP协议)。请求是客户点菜,回复像是服务员上菜,而处理则是在后厨中,厨师根据请求的菜单,准备菜品的过程。

厨师通常是服务器上的一个应用程序。这个应用程序可以提取请求中的信息,并根据这些信息准备回复。这样的应用程序可以是许多中语言写成的,比如C, C++, Perl, Ruby, Python, Ruby, PHP等等。由于不同语言的设计理念和编译器特征的不同,这些语言写成的应用程序也有不同的特点(各种各样的厨师)。比如C和C++语言会有比较高的运行效率,PHP的Web应用广泛,Ruby和Python开发方便等等。

(在语言之争中,Web服务器的“后厨”是一块兵家必争之地)

Servlet是Java语言提供的的“厨师”。在Java中,“一切皆对象”。Servlet是一类特殊的Java对象。Java语言利用Servlet对象,来实现对HTTP请求的处理。

 

样例

下面是一个简单的Servlet例子,源文件为TestPage.java:

package foo;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class TestPage extends HttpServlet {

    public void doGet(HttpServletRequest request,
                     HttpServletResponse response)
                throws IOException, ServletException
    {
        PrintWriter out = response.getWriter();
        out.println("<html><body>" +
           "<p>Hello World!</p>" + "</body></html>");
    }
}

这个Servlet的功能是回复字符串"<html><body><p>Hello World!</p></body></html>"。这一段字符串实际上是一个HTML文本。它将作为HTTP回复的主体部分,发回给客户端。

这里定义了一个TestPage类,该类继承HttpServlet抽象类(参考HttpServlet)。我们覆盖了doGet()方法。doGet()方法处理GET方法的HTTP请求。如果HTTP请求的方法为POST,则应该覆盖doPost()方法。每个Servlet都应该覆盖doGet()和doPost()之一。doGet()和doPost()方法接收两个参数request和response,分别为HttpServletRequest类型和HttpServletResponse类型。这两个参数分别代表该次HTTP通信的请求和回复。

HttpServletRequest和HttpServletResponse为两个接口。在方法的内部,我们可以操作request和response对象。比如,通过response的getWriter方法,来获得Writer,从而写入HTML文本。这些写入的文本将作为HTTP回复的主体传递回客户端。再比如,我们可以使用request的getMethod()方法来获知HTTP请求的方法。可以参考下面的官方文档:

HttpServletRequest的更多方法

HttpServletResponse的更多方法

 

此外,PrintWriter类来自java.io包。参考Java IO

 

doGet()是真正的工作室。我们通过定义该方法(或者doPost())方法,来让厨师做特定的事情。Servlet编写的关键在于写出一个符合需求的doGet()方法或者doPost()方法。

 

doGet()与doPost()

正如第一行package语句所说明的(参考Java包),TestPage类被放入到foo包中。我们还import了其他的Java包。Servlet是基于Java的,所以它可以借助Java语言所提供的丰富的工具。

 

编译

使用下面命令编译TestPage.java

$javac -classpath /path-to-tomcat/lib/servlet-api.jar:classes:. TestPage.java

上面的path-to-tomcat是Tomcat的安装路径。我们需要包括servlet-api.jar,原因是,javax.servlet包属于J2EE,它并不属于JSE。

 

将编译生成的TestPage.class文件放入到下面的文件夹中。(如果文件夹不存在,需要自行创建):

/path-to-tomcat/webapps/test/WEB-INF/classes/foo

(在TesPage.java中,利用package语句,说明该类在foo包中。这里的路径符合之前的package定义。)

 

修改或者新建/path-to-tomcat/webapps/test/WEB-INFO/web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0"
  metadata-complete="true">

  <servlet>
    <servlet-name>Test</servlet-name>
    <servlet-class>foo.TestPage</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Test</servlet-name>
    <url-pattern>/MyServlet</url-pattern>
  </servlet-mapping> 

</web-app>

这样的一个xml文件被称作部署描述(DD, Deployment Descriptor)。DD告诉Container如何运行Servlet和JSP。

上面的<servlet>标签是将该Servlet(foo.TestPage.class)命名为Test。

在<servlet-mapping>标签中,我们将Test这个Servlet对应于URL: /MyServlet。这说明,当有请求访问该URL时,则将请求传递给Test这个Servlet处理。

上面修改的主要目的,是说明Servlet与URL的对应关系。

 

随后,可以访问localhost:8080/test/MyServlet,来查看访问页面。

 

过程

看一下Servlet完成一次请求处理的过程:

从客户端(Guest)向服务器发送HTTP请求,该HTTP请求传递给Servlet Container。该Container负责:

  • 分析HTTP请求的信息,并新建request对象,将HTTP请求中的信息放入request对象
  • 新建response对象
  • 根据web.xml,查找URL对应的Servlet对象。如果Servlet对象不存在,则新建相应Servlet对象。
  • 创建新的线程,用于处理本次请求。线程拥有指向request和response对象的引用。

 

线程将调用Servlet的doGet()或者doPost()方法。线程运行结束后,response对象将传回给Container。Container根据response对象中的信息,生成一个符合HTTP协议的回复,传回给客户端。

注意,即使是新建的Servlet对象,它也不会随着线程的结束而结束。Servlet将继续存在。下次相同的URL访问将不必新建Servlet。

 

总结

上面制作了一个简单的Servlet,主要用于说明制作Servlet的过程。Servlet的许多强大功能还有待以后展开。

每个Servlet就像是后厨的一个厨师。我们可以用不同的URL对应来选择不同的厨师。一个复杂的网站往往需要许多个不同功能的Servlet。

 

欢迎继续阅读“Java快速教程”系列文章

 

时间: 2024-09-20 00:20:01

Java网络02 Servlet开胃酒的相关文章

Java网络03 Servlet沙拉

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.   Servlet开胃酒中介绍了Servlet的基本流程和设置方式.这里,我们将看一些Servlet实例.这些实例都是HTTP通信(参考HTTP协议)中的常见问题.我们通过操作request和response,来实现HTTP协议的功能.   生成页面 Servlet的目的是动态生成页面.比如下面的例子: package foo; import javax.servlet.*; impo

Java网络学习(二) Servlet开胃酒

在Tomcat初次尝试中,我们搭建了用于测试Servlet和JSP的基本环境.我们现在要转向网络应用的具体开发. 厨师 Web服务器的基本工作方式是请求-处理-回复.请求和回复是在网络上,以HTTP协议为基础的通信(参考HTTP协议).请求是客户点菜,回复像是服务员上菜,而处理则是在后厨中,厨师根据请求的菜单,准备菜品的过程. 厨师通常是服务器上的一个应用程序.这个应用程序可以提取请求中的信息,并根据这些信息准备回复.这样的应用程序可以是许多中语言写成的,比如C, C++, Perl, Ruby

Java网络学习(三) Servlet沙拉

Servlet开胃酒中介绍了Servlet的基本流程和设置方式.这里,我们将看一些Servlet实例.这些实例都是HTTP通信(参考HTTP协议:http://www.cnblogs.com/vamei/archive/2013/05/11/3069788.html)中的常见问题.我们通过操作request和response,来实现HTTP协议的功能. 生成页面 Servlet的目的是动态生成页面.比如下面的例子: package foo; import javax.servlet.*; imp

JAVA网络编程之模拟表单提交

这一篇博客是对上一篇<JAVA网络编程之获取网络资源>的扩充,这一篇将使用HttpURLConnection来模拟一个表单的提交.在B/S架构的系统中,请求时通过浏览器与服务端进行交互的,提交请求参数时使用form表单进行提交,但是有很多时候,我们需要在程序中直接调用HTTP接口,同时需要传递一些参数,那么这个时候我们就可以通过使用HttpURLConnection来模拟表单的提交过程. 首先,我们可以对请求进行封装 import java.util.ArrayList; import jav

Java网络编程从入门到精通 (9):使用isXxx方法判断地址类型

本文为原创,如需转载,请注明作者和出处,谢谢! 上一篇:Java网络编程从入门到精通(8):用getAddress方法获得IP地址     IP地址分为普通地址和特殊地址.在前面的文章中所使用的大多数都是普通的IP地址,在本文中将介绍如何利用InetAddress类提供的十个方法来确定一个IP地址是否是一个特殊的IP地址. 一.isAnyLocalAddress方法     当IP地址是通配符地址时返回true,否则返回false.这个通配符地址对于拥有多个网络接口(如两块网卡)的计算机非常拥有

java网络传递对象时该对象继承父类的属性在网络接收端接收该属性值总是null,why?

问题描述 java网络传递对象时该对象继承父类的属性在网络接收端接收该属性值总是null,why? //=========================== 情形一: ===============================//在网络上传递User1类对象时info属性值在网络的另一端能够接收到! public class User1 implements Serializable { public String info = null; public String userName =

Java网络服务器编程(NIO版)

编程|服务器|网络 从Java 1.4开始提供的NIO API常用于开发高性能网络服务器,本文演示了如何用这个API开发一个TCP Echo Server.   Java网络服务器编程 一文演示了如何使用Java的Socket API编写一个简单的TCP Echo Server.其阻塞式IO的处理方式虽然简单,但每个客户端都需要一个单独的Thread来处理,当服务器需要同时处理大量客户端时,这种做法不再可行.使用NIO API可以让一个或有限的几个Thread同时处理连接到服务器上的所有客户端.

Java网络编程从入门到精通

Hibernate从入门到精通(十一)多对多双向关联映射 Hibernate从入门到精通(十)多对多单向关联映射 Hibernate从入门到精通(九)一对多双向关联映射 Hibernate从入门到精通(八)一对多单向关联映射 Hibernate从入门到精通(七)多对一单向关联映射 Hibernate从入门到精通(六)一对一双向关联映射 Hibernate从入门到精通(五)一对一单向关联映射 Hibernate从入门到精通(四)基本映射 Hibernate从入门到精通(三)Hibernate配置文

Java网络编程从入门到精通(34)

Java网络编程从入门到精通(34):读写缓冲区中的数据---使用get和put方法按顺序读写单个数据 对于缓冲区来说,最重要的操作就是读写操作.缓冲区提供了两种方法来读写缓冲区中的数据:get.put方法和array方法.而get.put方法可以有三种读写数据的方式:按顺序读写单个数据.在指定位置读写单个数据和读写数据块.除了上述的几种读写数据的方法外,CharBuffer类还提供了用于专门写字符串的put和append方法.在本文及后面的文章中将分别介绍这些读写缓冲区的方法. 虽然使用all