文章目录
  1. 1. RESTEasy入门
    1. 1.0.1. RESTEasy入门

RESTEasy入门

RestEasy

RESTEasy入门

RESTEasy是JBoss的开源项目之一,是一个RESTful Web Services框架。RESTEasy的开发者Bill Burke同时也是JAX-RS的J2EE标准制定者之一。JAX-RS是一个JCP制订的新标准,用于规范基于HTTP的RESTful Web Services的API。

我们已经有SOAP了,为什么需要Restful WebServices?用Bill自己的话来说:”如果是为了构建SOA应用,从技术选型的角度来讲,我相信REST比SOAP更具优势。开发人员会意识到使用传统方式有进行SOA架构有多复杂,更不用提使用这些做出来的接口了。这时他们就会发现Restful Web Services的光明之处。”

说了这么多,我们使用RESTEasy做一个项目玩玩看。首先创造一个maven1的web项目

Java代码  收藏代码

    mvn archetype:create -DgroupId=org.bluedash \    

      

    -DartifactId=try-resteasy -DarchetypeArtifactId=maven-archetype-webapp   

 

准备工作完成后,我们就可以开始写代码了,假设我们要撰写一个处理客户信息的Web Service,它包含两个功能:一是添加用户信息;二是通过用户Id,获取某个用户的信息,而交互的方式是标准的WebService形式,数据交换格式为XML。假设一条用户包含两个属性:Id和用户名。那么我们设计交换的XML数据如下:

Java代码  收藏代码

     

        1  

        liweinan  

     

 

首先要做的就是把上述格式转换成XSD2,网上有在线工具可以帮助我们完成这一工作3,在此不详细展开。使用工具转换后,生成如下xsd文件:

Java代码  收藏代码

     

    <xsd:schema attributeFormDefault=”unqualified” elementFormDefault=”qualified”  

    version=”1.0” xmlns:xsd=”http://www.w3.org/2001/XMLSchema">  

      <xsd:element name=”user” type=”userType” />  

      <xsd:complexType name=”userType”>  

        xsd:sequence  

          <xsd:element name=”id” type=”xsd:int” />  

          <xsd:element name=”name” type=”xsd:string” />  

         

       

     

 

有了xsd文件,我们便可以使用JDK自带工具的xjc将xsd转换成为Java的Class。将上述xsd文件存为 user.xsd,并使用如下命令进行转换:

Java代码  收藏代码

    xjc user.xsd  

 执行结束后我们会得到一系列的类文件:

Java代码  收藏代码

    Li-Weinans-MacBook-Pro:Desktop liweinan$ xjc user.xsd   

    parsing a schema…  

    compiling a schema…  

    generated/ObjectFactory.java  

    generated/UserType.java  

 

这样,我们的XML格式的交换数据便转化为面向对像的Java类了,是不是感觉有点像Hibernate的ORM理念?没错,将XML映射成成面向对象的数据类,这个过程叫做XML Binding,即XML绑定。这个过程也有J2EE标准,叫做JAXB4。而RESTEasy是全面支持JAXB的。可以说RESTEasy所支持的JAX-RS标准,当与JAXB标准结合在一起使用时,就可以发挥出最大优势,让程序员少写一堆一堆的代码。有关JAXB标准,会在 独立的篇章中 详细讨论,在此先不展开。总之我们将生成的Java类放进项目中等候使用。我们可以看一下UserType类的内容:

Java代码  收藏代码

    package org.bluedash.resteasy;  

      

    import javax.xml.bind.annotation.XmlAccessType;  

    import javax.xml.bind.annotation.XmlAccessorType;  

    import javax.xml.bind.annotation.XmlElement;  

    import javax.xml.bind.annotation.XmlType;  

      

    @XmlAccessorType(XmlAccessType.FIELD)  

    @XmlType(name = “userType”, propOrder = {  

        “id”,  

        “name”  

    })  

    public class UserType {  

      

        protected int id;  

        @XmlElement(required = true)  

        protected String name;  

      

        /** 

         * Gets the value of the id property. 

         *  

         */  

        public int getId() {  

            return id;  

        }  

      

        /** 

         * Sets the value of the id property. 

         *  

         */  

        public void setId(int value) {  

            this.id = value;  

        }  

      

        /** 

         * Gets the value of the name property. 

         *  

         * @return 

         *     possible object is 

         *     {@link String } 

         *      

         */  

        public String getName() {  

            return name;  

        }  

      

        /** 

         * Sets the value of the name property. 

         *  

         * @param value 

         *     allowed object is 

         *     {@link String } 

         *      

         */  

        public void setName(String value) {  

            this.name = value;  

        }  

      

    }  

 可以看到,XML格式就是通过一些JAXB的标记被映射成了Java类。我们没写什么代码,已经把数据模型定义清楚了。接下来我们撰写最核心的WebService API。我们的WebService包含两个接口:一个是添加用户接口createUser,另一个是获取用户接口getUser:

Java代码  收藏代码

    package org.bluedash.resteasy;  

      

    import java.net.URI;  

    import java.util.Map;  

    import java.util.concurrent.ConcurrentHashMap;  

    import java.util.concurrent.atomic.AtomicInteger;  

      

    import javax.ws.rs.Consumes;  

    import javax.ws.rs.GET;  

    import javax.ws.rs.POST;  

    import javax.ws.rs.Path;  

    import javax.ws.rs.PathParam;  

    import javax.ws.rs.Produces;  

    import javax.ws.rs.WebApplicationException;  

    import javax.ws.rs.core.Response;  

      

    @Path(“/users”)  

    public class UserServlet {  

      

        private Map<Integer, UserType> userStore =   

            new ConcurrentHashMap<Integer, UserType>();  

        private AtomicInteger idGenerator = new AtomicInteger();  

      

        @POST  

        @Consumes(“application/xml”)  

        public Response createUser(UserType user) {  

            user.setId(idGenerator.incrementAndGet());  

            userStore.put(user.getId(), user);  

            System.out.println(user.getName() + “ created: “   

                + user.getId());  

            return Response.created(URI.create(“/users/“   

                + user.getId())).build();  

        }  

      

        @GET  

        @Path(“{id}”)  

        @Produces(“application/xml”)  

        public UserType getUser(@PathParam(“id”) int id) {  

            UserType u = userStore.get(id);  

            if (u == null) {  

                throw new WebApplicationException(  

                    Response.Status.NOT_FOUND);  

            }  

            return u;  

        }  

      

    }  

 

用几个简单的JAX-RS标记,便把普通的函数变成了WebService接口。而这些标记将由RESTEasy支持生效。接下来我们将要进行RESTEasy的配置工作。RESTEasy的配置方法有多种多样,可以和Spring等容器集成,也可以独立运行,因为我们用的Servlet的形式使RESTEasy进行工作,这也是最主流的方式,因此在这里使用web容器来加载它,首先定义一个配置类:

Java代码  收藏代码

    package org.bluedash.resteasy;  

      

    import java.util.HashSet;  

    import java.util.Set;  

      

    import javax.ws.rs.core.Application;  

      

    public class BluedashResteasyApplication extends Application {  

        private Set singletons = new HashSet();  

        private Set<Class> classes = new HashSet>();  

      

        public BluedashResteasyApplication() {  

    //      classes.add(UserServlet.class);  

            singletons.add(new UserServlet());  

        }  

      

        @Override  

        public Set<Class<?>> getClasses() {  

            return classes;  

        }  

      

        @Override  

        public Set getSingletons() {  

            return singletons;  

        }  

    }  

 

这个类扩展JAX-RS的Application接口,用于封装我们的WebService API方法。我们可以看到JAX-RS支持两种封装方法,一种是classes封装,由容器管理WebServices类的实例化和销毁等动作,一个线程一个实例,开发者不需要关心线程安全问题。但这种方法可能比较浪费资源。如果开发者想自己管理线程安全,共线程共用一个WebServices实例,那么就用singletons封装。我们在这里用的singletons封装,这也就解释了为什么我们在 UserServlet中使用了ConcurrentHashMap和AtomicInteger这些保障线程安全的类。接下来就是在web.xml中启动RESTEasy:

Java代码  收藏代码

    <!DOCTYPE web-app PUBLIC  

     “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”  

     “http://java.sun.com/dtd/web-app_2_3.dtd“ >  

      

     

        Archetype Created Web Application  

      

         

            javax.ws.rs.core.Application  

            org.bluedash.resteasy.  

            BluedashResteasyApplication  

         

      

         

            org.jboss.resteasy.plugins.server.  

            servlet.ResteasyBootstrap  

         

      

         

            Resteasy  

            org.jboss.resteasy.plugins.server.servlet.  

            HttpServletDispatcher  

         

      

         

            Resteasy  

            /*  

         

     

 没错,就是这么简单,这样,我们的WebService就完成了!还差点什么呢?嗯,还差一个Test Case来使用我们的WebService接口,并验证它的正确性,让我们来写一个TestUserAPI

Java代码  收藏代码

    package org.bluedash.resteasy.test.integration.test;  

      

    import java.io.IOException;  

    import java.io.OutputStream;  

    import java.net.HttpURLConnection;  

    import java.net.URL;  

      

    import junit.framework.TestCase;  

      

    public class TestUserAPI extends TestCase {  

        public static final String USER_API =   

            “http://127.0.0.1:8080/try-resteasy/users“;  

      

        public void testCreateUserAndGetUser() throws IOException {  

            URL url =   

                new URL(USER_API);  

            HttpURLConnection connection =   

                (HttpURLConnection) url.openConnection();  

            connection.setRequestMethod(“POST”);  

            connection.setRequestProperty(“Content-Type”, “application/xml”);  

            connection.setDoOutput(true);  

            connection.setInstanceFollowRedirects(false);  

            connection.setConnectTimeout(1000);  

      

            String userXML = “liweinan“;  

            OutputStream os = connection.getOutputStream();  

            os.write(userXML.getBytes());  

            os.flush();  

      

            assertEquals(HttpURLConnection.HTTP_CREATED, connection  

                    .getResponseCode());          

            connection.disconnect();  

      

        }  

    }  

 

一切都已经准备就绪,最后我们要配置一下Maven,让它下载所需的RESTEasy等库,然后配置Maven使用Jetty Web服务器,来把我们的服务和测试跑起来:

Java代码  收藏代码

    <project xmlns=”http://maven.apache.org/POM/4.0.0“   

        xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“  

      xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0   

    http://maven.apache.org/maven-v4_0_0.xsd">  

      4.0.0  

      org.bluedash  

      try-resteasy  

      war  

      1.0-SNAPSHOT  

      try-resteasy Maven Webapp  

      http://maven.apache.org  

         

             

                JBossMavenRepo  

                JBoss Maven2 repo  

                http://repository.jboss.org/maven2  

                 

                    true  

                 

                 

                    false  

                 

             

         

         

             

                junit  

                junit  

                4.4  

                test  

             

             

                org.jboss.resteasy  

                resteasy-jaxrs  

                1.2.RC1  

             

             

                org.jboss.resteasy  

                resteasy-jaxb-provider  

                1.2.RC1  

             

             

                javax.servlet  

                servlet-api  

                2.4  

             

         

         

            try-resteasy  

             

                 

                    org.apache.maven.plugins  

                    maven-compiler-plugin  

                     

                        1.6  

                        1.6  

                        UTF-8  

                     

                 

                 

                    org.apache.maven.plugins  

                    maven-surefire-plugin  

                     

                         

                            /integration/ 

                         

                     

                     

                         

                            integration-tests 

                            integration-test 

                             

                                test 

                             

                             

                                false 

                                 

                                    none 

                                 

                                 

                                    /integration/  

                                 

                             

                         

                     

                 

                 

                    org.mortbay.jetty  

                    maven-jetty-plugin  

                    6.1.15  

                     

                        5  

                        foo  

                        9999  

                     

                     

                         

                            start-jetty  

                            pre-integration-test  

                             

                                run  

                             

                             

                                5  

                                true  

                             

                         

                         

                            stop-jetty  

                            post-integration-test  

                             

                                stop  

                             

                         

                     

                 

             

         

     

 

有关Maven的配置就不详细展开了。配置完成后我们便可以运行单元测试,看看WebServices是否正确运行。执行下述命令

Java代码  收藏代码

    mvn integration-test  

 执行结果如下:

Java代码  收藏代码

    ——————————————————-  

     T E S T S  

    ——————————————————-  

    Running org.bluedash.resteasy.test.integration.test.TestUserAPI  

    liweinan created: 1  

    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.372 sec  

      

    Results :  

      

    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0  

 

可以看到,我们的测试按预期执行成功了。这篇文章中,我简单向大家介绍了RESTEasy的初步使用方法,希望对大家在架构SOA应用时,有所帮助。JAX-RS标准做为J2EE家庭中相对较新的一员,其应用前景是十分广阔的。

文章目录
  1. 1. RESTEasy入门
    1. 1.0.1. RESTEasy入门