许多Java专 业人员都有兴趣学习一下REST式WEB服务的基础知识,但是他们常常发现那些操作指南太复杂了。在本篇速成教材中,我们将直接使用基础知识,演示一下如 何创建一个基于REST的WEB服务。你会发现竟是如此容易,我们所需要的仅仅是一套JDK,一个象记事本那样简单的文本编辑器,以及安装一套Tomcat 7。
首先,是关于RESTful WEB服务的几点介绍。这类服务在HTTP协议上运行,并按照HTTP原本设计的使用方式运转。HTTP协议提供了四种基本方法:GET,POST,PUT和DELETE。在我们的示例中,我们将只处理GET方法,其他方法留待以后再说。
访问一个基于REST的Web服务
作为我们这个基于REST的WEB服务实施过程的第一阶段,我们将创建一个简单的URL,它只能处理GET请求。这个服务可以通过下面这个URL进行访问:http://localhost:8080/restful/resources/helloworld
一开始首先搞懂URL可能比较费力,但是我们最好还是了解一下URL是如何组成的。因为在我们开始创建Web服务的时候,你会接触到URL的各个不同部 分-也就是,context root部分“restful”,RESTful资源文件容器“resources”,以及服务本身的名字,所有这些都将出现在代码中或者在XML配置文 件中。
所需要的WEB应用文件夹结构
顾名思义,一个基于Java实 现的REST式WEB服务,需要部署在一个符合Java企业版规范的Servlet容器中,同时,这个服务本身也必须符合Servlet和ASP应用编程 接口所要求的文件夹结构格式。基本上说,这意味着在应用根目录下,我们需要一个WEB-INF目录,并且该目录需要有一个部署描述符,一个lib目录用来 存放各种在运行时需要的JAR文件,一个在WEB-INF目录下的classes目录用来存放所有编译后的Java代码:
以下是引用片段: +\(root folder) ++WEB-INF\ ++++classes\ ++++lib\ |
对于本例中的应用,根目录的名称为_restful,它位于C盘的根目录下:
在建立了上述所需的文件夹结构之后,现在我们就要创建合适的资源到WEB-INF文件夹,classes文件夹和lib文件夹中。首先我们来创建lib目录的内容。
获取Jersey:JSR-311的实现
实现RESTful WEB服务并不是一个“自编自演”式的实施过程。JSR-311是实施RESTful WEB服务的API规范,我们可以利用利用JSR规范的一个实现。Jersey是JSR-311的一个开源实现,它可以从jersey.java.net下载得到。
在jersey.java.net上有多个文件可供下载,您需要下载的是那个包含有“Jersey jars,核心依赖和JavaDoc”的zip格式的文件。我下载的该文件名字为jersey-archive-1.6.zip ,大小为5.7兆字节。当将它解压缩到硬盘驱动器上时,它里面包含了一个lib文件夹,这里面就包含了各种“可爱”的jar文件。
所下载的Jersey文件夹lib下面的各个jar文件都需要拷贝到我们正在开发的WEB应用的WEB-INF\lib目录下,你要注意WEB应用的运行时和编译时依赖关系。
在本示例的开发过程中,对于基于Java的 组件,我们将只是编写一个名为HelloWorldResource 的类,这个类位于com.mcnz.ws包中。这个类有一个叫做getMessage()的方法,它返回字符串‘Rest Never Sleeps’。这个方法本身并无多大意义,但是我们感兴趣的是在代码中的各个标识符。
当你为这个类编写代码时,要注意这个类必须被放在WEB- INF文件夹下的classes目录中,并且所在的文件夹结构,如下图所示,能够映射到包名com.mcnz.ws。
下面就是我们所要用到的代码,把它保存在上面指定的目录下以HelloWorldResource.java命名的一个文件中。
要实现的类
以下是引用片段: package com.mcnz.ws; import javax.ws.rs.*; @Path("helloworld") public class HelloWorldResource { @GET @Produces("text/plain") public String getMessage() { return "Rest Never Sleeps"; } } |
前面我们说过,这个服务要只响应HTTP GET请求,因此,你会看到,这个getMessage()方法带有一个@GET的修饰符。并且,后面紧跟着一个@Produces标记,指示这个方法仅 仅返回一个普通文本("text/plain"),这是MIME类型中最简单的一种。当客户通过指定的URL调用我们的服务时,这个文本字符串“Rest Never Sleeps”就会被返回。
在最开始的时候,我们就已经提到,调用这个服务所用的URL将会是:http://localhost:8080/restful/resources/helloworld
你会发现,@Path("helloworld") 标记直接对应了在URL末尾处指定的资源名称。
在Java文件保存完毕后,可以使用下述命令来编译我们的代码:
以下是引用片段: C:\> c:\_jdk1.6\bin\javac -classpath "C:\_restful\WEB-INF\lib\*" C:\_restful\WEB-INF\classes\com\mcnz\ws\*.java |
编译结束后,原来保存.java文件所在的目录下将会生成一个相同名称的.class文件。
在部署描述符中配置Jersey
在我们将需要的jar文件放到WEB-INF\lib目录下,HelloWorldResource.java文件编译结束后,在部署前的最后一个步骤是,编辑部署描述符以便让Servlet容器知道这个Jersey实现将被用来处理RESTful Web服务的调用请求。因此,创建一个名为web.xml的文件,把它放到WEB-INF目录下,其内容如下:
以下是引用片段: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0" 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"> <servlet> <servlet-name>RestfulContainer</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.mcnz.ws</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>RestfulContainer</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> </web-app> |
对于这个web.xml文件,有两点值得注意。其一是,一个Servlet已经被配置为处理RESTful调用。这个Servlet的名称是ServletContainer ,它是我们从Sun网站上下载下来的Jersey库文件的一部分,我们早已经将它放到WEB应用的\lib目录下了。
另一个值得注意的重要事情是,在Servlet映射中,“url-pattern”的名称为/resources/*。注 意:URL-pattern(在本例中是“resources”)对应于URL中在资源名称(在本例中是“helloworld”)之前,在WEB应用 context root(在本例中是“restful”)之后的那个部分。http://localhost:8080/restful/resources /helloworld
现在,web.xml已经写好并保存完毕,我们可以将这个应用打包成一个war文件并部署到Tomcat了。你可以最终检查一下,你的开发环境应该在以下目录结构中包含有以下资源:
以下是引用片段: + \ ( root folder C:\_restful ) ++ WEB-INF\ ++++ web.xml ++++ lib\ ++++++ asm-3.1.jar ++++++ jackson-core-asl-1.7.1.jar ++++++ jackson-jaxrs-1.7.1.jar ++++++ jackson-mapper-asl-1.7.1.jar ++++++ jackson-xc-1.7.1.jar ++++++ jersey-client-1.6.jar ++++++ jersey-core-1.6.jar ++++++ jersey-json-1.6.jar ++++++ jersey-server-1.6.jar ++++++ jettison-1.1.jar ++++++ jsr311-api-1.1.1.jar ++++ classes\ ++++++ com\mcnz\ws\HelloWorldResource.class ++++++ com\mcnz\ws\HelloWorldResource.java |
部署及测试
在_restful目录下面执行以下命令,能够将_restful目录下的所有资源文件打包成一个可部署的war文件。这个命令实际上会把这个war文件放到Tomcat 7安装时创建的webapps目录下面。如果你安装Tomcat时指定了不同的目录名称,下面的命令要做相应修改:
以下是引用片段: C:\_restful> %JAVA_HOME%\bin\jar -cvf C:\_tomcat\webapps\restful.war *.* |
将war文件放到webapps目录下后,剩下的事情就只有启动Tomcat和调用这个服务了。
我们已经将servlet引擎安装到了_tomcat目录,下述命令可以启动Tomcat:
以下是引用片段: C:\_tomcat\bin> startup |
一旦Tomcat启动起来以后,由于在一个WEB浏览器中输入一个URL将会触发一个HTTP GET调用,这个RESTful WEB服务可以通过一个浏览器经由下述的URL来调用:http://localhost:8080/restful/resources /helloworld(注意,context root目录restful,对应的是war文件restful.war的名称)
通过Chrome浏览器调用这个服务后的结果如下图所示:
总结
搞定!你看,配置一个RESTful WEB服务的基本开发环境是多么轻松,编码实现一个极简易的RESTful WEB服务(本例目前只能处理GET请求)是多么容易!