java Rest学习-第一个Java REST 服务(3)-分析和学习rest项目

文章标签: java-rest
2014-12-13 16:25:12     9 人阅读    

           项目测试通过意味着本地环境没有问题了,接下来可以开始学习simple-service 项目了,为下一步扩展项目做好准备。
           在simple-service 项目的根目录执行“tree /f ”命令,可以纵览simple-service 的文件结构,如图2-1 所示。
          在图2-1 所示的目录结构中,对开发者有价值的内容包括源代码Main.java、MyResource.java 和测试代码MyResourceTest.java。
          首先,定位该项目中的有用信息以去除项目中的噪声。什么是噪声呢?无论使用哪一种IDE 做开发,其自身都会产生具有该IDE 方言的项目文件。除非特殊情况,我们不必理会这些项目文件,如果是团队开发,在提交到版本控制库的时候,应该对其过滤(使用GIT 做SCM时,过滤文件位于项目根目录,名称为 .gitignore )。 target 目录是Maven 的生成目录,类似构建工具Ant、Gradle 的build或者bin 目录,我们也可以忽略。

(1 )资源类分析
套用Web 开发中典型的三层逻辑,资源类位于逻辑分层的最高层——API 层,其下为Service层和数据访问层,如图2-2 所示。在三层逻辑中,API 层用于对外公布接口,对于REST 应用,API 层的资源类用于对外公布REST 服务接口。其下的两层,REST 应用的开发和标准Web 开发的区别不是很大。
本例中的API 层资源类是MyResource,代码示例如下。

package com.example;
...
//关注点1:资源路径
@Path("myresource")
public class MyResource {
//关注点2 :资源方法
    @GET
    @Produces (MediaType.TEXT_PLAIN)
    public String getIt() {
        return "Got it!";
    }
}

       在这段代码中,资源类MyResource使用了JAX-RS 标准中定义的@Path 注解来声明名为myresource 的资源路径,见关注点1 。该类只有一个处理HTTP 协议的GET 方法的getIt()方法,没有输入参数,输出是一个String 类型,传输格式是字符串类型(MediaType.TEXT_PLAIN ),返回字符串值是“ Got it! ”,见关注点 2 。


       在没有测试、运行这个例子之前,我们可以推测通过REST 访问getIt() 方法的资源路径如下,接下来的讲述将验证该资源路径。资源路径即是对外公布的REST 服务接口。HTTP 服务器路径/REST服务名称/myresource/


(2 )入口类分析
            因为这是一个Java SE 的应用,所以需要一个入口类来启动服务器并加载项目资源。对于Java EE 的应用则无须定义这样的入口类,因为 Java EE 容器本身扮演着入口类的角色。
    Main类是simple-service 项目的主类,即入口类,代码示例如下。

package com.example;
...
public class Main {
//关注点1 :服务器路径
    public static final String BASE_URI = "http://localhost:8080/myapp/";
    public static HttpServer startServer() {
//关注点2 :加载资源
        final ResourceConfig rc = new ResourceConfig().packages("com.example" );
//关注点3 :Grizzly HTTP服务器
        return GrizzlyHttpServerFactory.createHttpServer(URI.create (BASE_URI), rc);
    }
    public static void main(String[] args ) throws IOException {
        final HttpServer server = startServer();
        System.out.println (String.format("Jersey app started with WADL available at "
               + "%sapplication.wadl\nHit enter to stop it...", BASE_URI)) ;
        System.in.read();
        server.shutdownNow();
    }
}

                 Main类定义了HTTP 服务器的路径(BASE_URI ), 即 http://localhost:8080/myapp/ ,见关注点1 。在其构造中映射了源代码中资源所在的包名new ResourceConfig().packages(  “com.example”  ),这意味着,服务器启动时会自动扫描该包下的所有类,根据该包中所含类的REST 资源路径的注解,在内存中做好映射,见关注点2 。这样一来,客户端请求指定路径后,服务器就可以根据映射,分派请求给相应的资源类实例的相应方法了。这就是Jersey 中的IoC 机制。这个例子不是运行在Servlet 容器中的,相反,它是一个Java SE 应用。该服务自带了HTTP 服务器的实现,本例使用的服务器是Grizzly,见关注点3 。
(3 )测试类分析
                最后我们来看看真正用于单元测试的测试类MyResourceTest 。它只有一个测试方法testGetIt() 用来测试MyResource类公布的资源路径myresource。其代码示例如下。

package com.example;
...
public class MyResourceTest {
//关注点1 :全局字段
    private HttpServer server;
    private WebTarget target;
//关注点2 :准备测试环境
    @Before
    public void setUp() throws Exception {
        server = Main.startServer();
        Client c = ClientBuilder.newClient();
        target = c.target(Main.BASE_URI );
    }
//关注点3 :释放测试环境
    @After
    public void tearDown() throws Exception {
        server.shutdownNow();
    }
//关注点4 :测试GET 方法
    @Test
    public void testGetIt() {
        String responseMsg = target.path ("myresource" ).request().get (String.class );
        assertEquals("Got it!", responseMsg);
    }
}

               MyResourceTest 定义了两个全局字段,分别是Grizzly服务器类HttpServer 和JAX-RS 2.0 的客户端资源定位类WebTarget,见关注点1 。
注解为@Before 的setUp()方法是JUnit 测试前要执行的方法,为测试准备环境。首先启动Grizzly服务器,然后实例化一个Client,最后将服务器的资源地址作为参数,传给客户端示例,获取到客户端资源定位类实例target ,见关注点2 。testGetIt() 方法用于测试GET 方法,使用资源定位类WebTarget实例target 向myresource资源发出get请求,将返回值作为相等断言的输入参数,和“Got it!”进行比对,见关注点4 。注解为@After的方法tearDown() 在测试结束后执行,以释放测试环境中的资源,如停止服务器实例、释放资源等,见关注点3 。这里需要注意的是,释放资源过程无须处理客户端实例,该实例的连接已经在获取响应实体时断开,详见后文的讲述。

 

                 到此,我们已经掌握了simple-service 项目。在入门学习中,模仿是以后做到收放自如的第一步。接下来,我们重用Main作为环境支撑,模仿MyResource写一个自定义的资源类,并进行扩展性的尝试:引入实体类、逻辑分层类,支持更多的传输类型。还记得本章开始时关于设计一个更新设备的API 的疑问吗?继续轻松的学习之旅吧。


原文地址:http://www.itmmd.com/201412/311.html
该文章由 萌萌的IT人 整理发布,转载须标明出处。

Spring mvc新手入门(10)-ajax +spring mvc 3 实现异步登录   上一篇
下一篇  debug assertion failed f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\winocc.cpp错误的解决

精彩回复
发表评论
姓名:       

《程序员app》专门为程序员量身定做!