`
qqchinaok
  • 浏览: 217476 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论
阅读更多



JAX-RS 从傻逼到牛叉 2:开发一个简单的服务

Posted on 2011-09-20 17:22 蜀山兆孨龘 阅读(1554) 评论(0)  编辑  收藏  所属分类: Java EE 、SOA






    JAX-RS 使用注解进行配置,所以用它开发 REST 风格的服务非常简单。楼主在本文用一个小例子来说明 JAX-RS 的基本用法。
   
    假设楼主要开发一个小电影服务,客户端可以通过请求 URI 对电影进行 CRUD 操作。为简明起见,这儿不使用数据库,只在内存中模拟。先用一个非常简单的 Movie 类,在后续的文章中根据情况逐步扩充:
   
        public class Movie {
            private int id;
            private String title;
            // 此处省略若干行
        }
   
    嗯,就是一个很普通的 JavaBean,实际项目中可以根据需要加上 @Entity 等注解。接下来看看如何编写 JAX-RS 服务。
   
    一个 JAX-RS 服务就是一个使用了 JAX-RS 注解来将 HTTP 请求绑定到方法的 Java 类,一共支持两种类型:单请求对象或单例对象。单请求对象意味着每来一个请求,就创建一个服务对象,在请求结束时销毁。单例对象则意味着只有一个服务对象处理所有的请求,从而可以在多个请求间维持服务状态。JAX-RS 服务可通过继承 javax.ws.rs.core.Application 来定义,其中的 getClasses 方法返回单请求对象的类型,getSingletons 方法返回单例对象的类型。这两个方法是可选的。在 Java EE 6 环境中,如果这两个方法都返回 null 或者空集合,那么应用程序中的所有 JAX-RS 都将被部署。这时可以用 CDI 的 @javax.inject.Singleton 或者 EJB 的 @javax.ejb.Singleton 注解来指定单例对象。
    如果电影服务的上下文根路径为 http://localhost/ms,而楼主希望将服务部署到 http://localhost/ms/rest 下面,只需要写一个类:
   
        @ApplicationPath("rest")
        public class RestApplication extends Application {
        }
   
    @ApplicationPath 注解指定所有服务的相对基址,如果为空字符串,则直接使用上下文根路径。另一种配置方式是在 web.xml 文件中进行声明,那是为了使 JAX-RS 能在 Servlet 容器(例如 Tomcat)中运行,此处略过。这项配置必不可少,否则无法部署服务。
   
    很好很强大,现在开始编写电影服务类 MovieService,先看看声明和初始化:
   
        @Singleton
        @Path("movie")
        public class MovieService {
            private AtomicInteger ai;
            private ConcurrentMap<Integer, Movie> movieMap;

            &#64;PostConstruct
            private void init() {
                ai = new AtomicInteger();
                movieMap = new ConcurrentHashMap<>();
                int id = ai.getAndIncrement();
                movieMap.put(id, new Movie().setId(id).setTitle("Avatar"));
            }
   
    因为楼主只需要一个“内存数据库”,所以用单例对象即可,此处使用 CDI 的 &#64;javax.inject.Singleton 来声明单例。&#64;Path 声明了一个服务,它指示 MovieService 负责处理发送到 http://localhost/ms/rest/movie 的请求。路径的拼接方式非常直观。init 方法带有 &#64;PostConstruct 注解,因此将在 MovieService 构造完成后立即调用,它向 movieMap 中存入了一个 ID 为 0 的 Movie 对象。为简化代码,Movie 的设置方法都返回 this,有点伪造构建者模式的味道。
   
    接下来看看如何处理 HTTP 请求。
    GET
    GET 请求用于获取一个或多个资源。在本例中用来获取一部电影的信息:
   
        &#64;GET
        &#64;Path("{id}")
        &#64;Produces(MediaType.APPLICATION_JSON)
        public Movie find(&#64;PathParam("id") int id) {
            Movie movie = movieMap.get(id);
            if (movie != null) {
                return movie;
            } else {
                throw new WebApplicationException(Response.Status.NOT_FOUND);
            }
        }
   
    该方法标注了 &#64;GET,表示用来处理向 http://localhost/ms/rest/movie/{id} 发送的 GET 请求。&#64;Path 再次用来绑定路径,注意其参数 {id},它带有花括号,对应 URI 的最后一段,也正好和方法参数 id 的 &#64;PathParam 的值相对应。这种参数还有很多高级用法,以后再介绍。&#64;Produces 注解指定输出格式为 JSON。JAX-RS 内置了很多格式,详见 MediaType 的文档。如果找到了相应 ID 的对象,则将其返回,JAX-RS 会自动加上响应码 200 OK;否则抛出异常,错误码为 404 Not Found。
    例如,通过浏览器访问 http://localhost/ms/rest/movie/0,得到的结果为 {"&#64;id":"0","&#64;title":"Avatar"}。
    POST
    POST 请求用于创建一个资源。在本例中用来创建一部电影:
   
        &#64;POST
        &#64;Consumes(MediaType.APPLICATION_JSON)
        public Response create(Movie movie) {
            int id = ai.getAndIncrement();
            movieMap.put(id, movie.setId(id));
            return Response.created(URI.create(String.valueOf(id))).build();
        }
   
    由于没有 &#64;Path 注解,所以 POST 请求的目标就直接是 http://localhost/ms/rest/movie。Consumes 和 &#64;Produces 相反,表示接受的数据类型,此处 JAX-RS 会自动把 JSON 数据转换为 Movie 对象。返回的响应码为 201 Created,并且带有所创建资源的 URI。
    例如,向 http://localhost/ms/rest/movie 发送 POST 请求,正文为 {"&#64;title": "007"},则可以从 FireBug 的网络监控中看到返回的响应码,以及头部中 Location 的值为 http://localhost:8080/rest/service/movie/1。多次发送该 POST 请求,将会创建多个资源,以保证 POST 不是幂等的。
    PUT
    PUT 请求用于创建或更新一个资源。与 POST 不同,PUT 请求要指定某个特定资源的地址。在本例中用来更新一部电影的信息:
   
        &#64;PUT
        &#64;Path("{id}")
        &#64;Consumes(MediaType.APPLICATION_JSON)
        public Response update(&#64;PathParam("id") int id, Movie movie) {
            movie.setId(id);
            if (movieMap.replace(id, movie) != null) {
                return Response.ok().build();
            } else {
                throw new WebApplicationException(Response.Status.NOT_FOUND);
            }
        }
   
    更新成功就返回 200 OK,否则返回 404 Not Found。这儿先把 movie 对象的 ID 强制改为 URI 所指定的,以免出现不一致。也可以根据需求,将不一致作为异常处理,给客户端返回一个错误码。
    顺便啰嗦一句,反正代码在自己手中,楼主也可以把 PUT 搞成非幂等的,例如将 PUT 当成 POST 来处理,就像以前把 GET 和 POST 一视同仁那样。不过咱既然在搞 JAX-RS,就还是要沾染一点 REST 风格,严格遵守 HTTP 才是。
    DELETE
    DELETE 请求用于删除一个资源。在本例中用来删除一部电影:
   
        &#64;DELETE
        &#64;Path("{id}")
        public Response delete(&#64;PathParam("id") int id) {
            if (movieMap.remove(id) != null) {
                return Response.ok().build();
            } else {
                throw new WebApplicationException(Response.Status.NOT_FOUND);
            }
        }
   
    没什么特别的,该说的前面都说了。
    HEAD 和 OPTIONS 请求就忽略吧,用得不太多,也同样挺简单的。
   
    JAX-RS 服务的部署和部署常规 Web 程序一样,打包成 war 文件就可以了。最后赞一下 NetBeans 可以为 REST 风格的服务自动生成测试页面,很好用,虽然在 Firefox 下页面显示不正常(对此我已经提了一个 bug),但 IE 是可以的。

0
3
分享到:
评论

相关推荐

    jax-rs jax-ws所需包,亲测可用

    **标题与描述解析:** 标题"jax-rs jax-ws所需包,亲测可用"表明这个压缩包包含了用于开发...通过以上步骤,开发者可以快速搭建一个能正确处理JAX-RS和JAX-WS服务的环境,无需手动解决依赖问题,大大提高了开发效率。

    [Jax-RS] RESTful Java 开发 (Jax-RS 2.0 实现) (英文版)

    [奥莱理] RESTful Java 开发 (Jax-RS 2.0 实现) (英文版) [奥莱理] RESTful Java with JAX-RS 2.0 (E-Book) ☆ 图书概要:☆ Learn how to design and develop distributed web services in Java, using RESTful ...

    [Jax-RS] RESTful Java 开发 (Jax-RS 实现) (英文版)

    [奥莱理] RESTful Java 开发 (Jax-RS 实现) (英文版) [奥莱理] RESTful Java with Jax-RS (E-Book) ☆ 图书概要:☆ Learn how to design and develop distributed web services in Java using RESTful ...

    jackson-jaxrs-json-provider-2.7.8-API文档-中文版.zip

    赠送jar包:jackson-jaxrs-json-provider-2.7.8.jar; 赠送原API文档:jackson-jaxrs-json-provider-2.7.8-javadoc.jar; 赠送源代码:jackson-jaxrs-json-provider-2.7.8-sources.jar; 赠送Maven依赖信息文件:...

    JAX-WS API, JAX-RS API

    它是Sun Microsystems在2004年推出的一个重要框架,旨在简化Web服务的开发,使得Java开发者能够更方便地实现基于SOAP(Simple Object Access Protocol)的服务。JAX-WS取代了早期的Java API for XML Processing ...

    一个包含jax-ws和jax-rs的例子(含服务端和客户端)

    标题中的“一个包含jax-ws和jax-rs的例子(含服务端和客户端)”是指这是一个示例项目,它演示了如何使用Java API for XML Web Services (JAX-WS)和Java API for RESTful Web Services (JAX-RS)来创建和消费Web服务。...

    Jax-RS所需要的依赖jar

    2. **服务器容器**:虽然JAX-RS是一个标准,但需要一个服务器容器来运行这些服务。在提供的标签中提到了Jetty,这是一个轻量级、嵌入式的HTTP服务器和Servlet容器。Jetty可以轻松地与JAX-RS实现(如Jersey或RESTEasy...

    JAX-RS Extension

    4. **RESTlet框架**:RESTlet是一个开源的JAX-RS实现,它不仅提供了标准的REST服务开发支持,还引入了组件模型,允许更细粒度的服务构建。RESTlet支持多种角色,如客户端、服务器端和网关,使得开发者可以更轻松地...

    JAX-RS入门jar包集合

    JAX-RS,全称Java API for RESTful Web Services,是Java平台上的一个标准,用于构建RESTful风格的Web服务。REST(Representational State Transfer)是一种轻量级、基于HTTP协议的设计模式,广泛应用于现代Web应用...

    jax-rs开发实例(bookkeeping)

    在"jax-rs开发实例(bookkeeping)"中,我们将深入探讨如何利用JAX-RS构建一个简单的会计记录管理系统。这个实例可能包括创建、读取、更新和删除(CRUD)会计记录的REST接口,展示了RESTful服务的核心概念。 首先,...

    SpringMVC精品资源--JAX-RS &amp; SpringMVC supported maven buil.zip

    2. **JAX-RS示例**:可能提供了一个或多个使用JAX-RS创建的REST服务示例,演示了如何定义资源类、处理HTTP请求和响应,以及如何与其他Java EE组件集成。 3. **Maven配置**:由于提到了"Maven build",所以这个资源...

    JAX-RS+spring

    JAX-RS是Java平台上的标准,用于构建RESTful Web服务,而Spring则是一个全面的后端框架,提供了包括依赖注入、事务管理、AOP(面向切面编程)在内的多种功能。 **JAX-RS 知识点** 1. **定义**: JAX-RS 是JSR 339...

    JAX-RS包(内含1.0和1.4)

    JAX-RS,全称Java API for RESTful Web Services,是Java平台上的一个标准,用于构建RESTful风格的Web服务。REST(Representational State Transfer)是一种轻量级、基于HTTP协议的设计模式,常用于实现分布式系统中...

    jax-rs 2.1规范最终版-英文

    JAX-RS(Java™ API for RESTful Web Services)是Java平台上用于开发基于REST架构风格的Web服务的API。它是Java EE(Java Platform, Enterprise Edition)的一部分,也作为独立的JAX-RS Reference Implementation ...

    JAX-RS-FileUpload-Jersey-Example

    JAX-RS 是Java中的一个标准API,用于构建RESTful Web服务。它提供了一组注解,使得开发人员能够轻松地将HTTP方法(如GET、POST、PUT等)映射到Java方法,并处理HTTP请求和响应。JAX-RS允许开发者以声明式的方式创建...

    RESTful Java with JAX-RS 2.0

    JAX-RS(Java API for RESTful Web Services)是一个Java标准,它简化并促进了RESTful Web服务的开发。JAX-RS 2.0作为该标准的更新版本,引入了新的注解和方法来支持RESTful服务的构建。从定义资源到处理HTTP请求,...

    Spring MVC与JAX-RS比较与分析

    去几年,REST逐渐成为影响Web框架、Web协议与Web应用设计的重要概念...更进一步,如果你手头有一个Spring MVC应用,使用了控制类继承(SimpleFormController等),你可能还意识不到现在的Spring MVC对REST广泛的支持。

    JAX-RS注解及使用方法

    JAX-RS(Java API for RESTful Web Services)是一种基于 Java 语言的 RESTful Web 服务框架,它提供了一种简单、灵活的方式来开发 RESTful Web 服务。JAX-RS 使用注解来定义资源的行为和属性,使得开发者可以轻松地...

    JAX-RS Rest RestLet项目源码

    **JAX-RS与RESTful服务** JAX-RS(Java API for RESTful Web Services)是Java平台上的一个标准,用于...通过这个项目,不仅可以学习到JAX-RS的API,还能熟悉RESTLet框架的特性,为今后的Web服务开发打下坚实基础。

    java_webservice_JAX-RS.zip_cxf_jax_jax-rs_spring cxf

    Java Web服务,特别是JAX-RS(Java API for RESTful Web Services)和Apache CXF,是企业级应用程序中实现服务接口的重要技术。本教程将深入探讨如何在SSH(Spring、Struts、Hibernate)架构中集成Web服务,以及如何...

Global site tag (gtag.js) - Google Analytics