关闭

apache wink集成spring开发rest服务

标签: restspringapachecacheajaxurl
2499人阅读 评论(0) 收藏 举报
分类:

 第一部分 什么是REST服务

 Representational State Transfer,中文名:表征状态转移,简称:REST。它是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。

 需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTPURI,和XML以及HTML这些现有的广泛流行的协议和标准。

· 资源是由URI来指定。

· 对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。

· 通过操作资源的表现形式来操作资源。

· 资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。

 REST的要求

· 客户端和服务器结构

· 连接协议具有无状态性

· 能够利用Cache机制增进性能

· 层次化的系统

· 随需代码 - Javascript (可选)

 以上知识点来源于维基百科(http://zh.wikipedia.org/zh-cn/REST

REST多层调用架构(来源于网络)

上图将传统MVC与Rest服务进行了对别。蓝色部分就是我们今天要讲的Rest服务,红色部分就是传统的MVC结构。

通过上面的比较总结出一下几点供大家参考

1.相对于传统,页面----->Struts-------->Spring------------->数据持久,这样一条龙式的开发模式;Rest显得更加分离,从逻辑上分为了:客服端和服务端,客服端主要关心数据的解析,展示,而服务器端只关注逻辑代码的编写以及接口的定义,从传统的一个人包打天下升级为各司其职,明确的分工,使程序的开发效率大幅提升

2.由于在REST设计时,就已将所有的构建都看成资源,通过统一的URI进行标示,使用传统的http协议进行传输,所以Rest天生就有客服端无关性,即同样的接口,既可以通过Flex进行消费也可以通过Ajax消费,甚至可以通过java后台直接消费,这样优良的特性,带来了客服端丰富多样的展示方式

3.由于Rest面向服务编程,打破了传统开发模式下,一个项目一个后台服务的模式,使一个Rest可以为多个系统服务,同时一个系统也能同时消费多个服务,消费与服务的打断,带来了无限可能的重组,大大提供了代码的可复用性以及系统的可扩展性

4.方便的封装模式,从传统开发模式过渡到Rest架构,程序员只需修改调用后台的方式,特别是wink与spring的集成只需几个常用的标记与接口方法书写,就能将传统业务代码华丽变身为REST服务

第二部分 Apache Wink 结合Spring 开发Rest服务

1. 需要的主要依赖包

本项目使用maven管理,以下是需要的依赖包引用

<dependency>

<groupId>com.hdsx</groupId>

<artifactId>dao</artifactId>

<version>2.0.1</version>

<type>jar</type>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

<version>3.1.0.RELEASE</version>

<type>jar</type>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

<version>3.1.0.RELEASE</version>

<type>jar</type>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aspects</artifactId>

<version>3.1.0.RELEASE</version>

<type>jar</type>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>aspectjweaver</artifactId>

<version>1.6.12</version>

<type>jar</type>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>cglib</groupId>

<artifactId>cglib</artifactId>

<version>2.2.2</version>

<type>jar</type>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>aspectj</groupId>

<artifactId>aspectjrt</artifactId>

<version>1.5.4</version>

<type>jar</type>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>org.apache.wink</groupId>

<artifactId>wink-server</artifactId>

<version>1.1.3-incubating</version>

</dependency>

<dependency>

<groupId>org.apache.wink</groupId>

<artifactId>wink-spring-support</artifactId>

<version>1.1.3-incubating</version>

<exclusions>

<exclusion>

<artifactId>spring</artifactId>

<groupId>org.springframework</groupId>

</exclusion>

</exclusions>

</dependency>

其中dao是对mybatis的简单封装,简化了持久化操作,在下一篇博文里再讨论这个封装,你可以直接使用mybatis进行替换。

2. Web.xml配置文件

         <context-param>

                   <param-name>contextConfigLocation</param-name>

                             <param-value>

                                  classpath:META-INF/server/wink-core-context.xml

                                  classpath:applicationContext.xml

                            </param-value>

       </context-param>

        <listener>

                  <listener-class>

                          org.springframework.web.context.ContextLoaderListener

                 </listener-class>

       </listener>

配置spring监听,需要注意的是对 classpath:META-INF/server/wink-core-context.xml的配置,其位于wink-spring-support中,是winkspring集成的核心配置文件

    <servlet>

              <servlet-name>restService</servlet-name>

             <servlet-class>

                     org.apache.wink.server.internal.servlet.RestServlet

            </servlet-class>

</servlet>

<servlet-mapping>

            <servlet-name>restService</servlet-name>

            <url-pattern>/rest/*</url-pattern>

</servlet-mapping>

配置winkservlet,完对rest服务的调用转发

3. 编写业务逻辑代码

         @Service

           public class TestServerImpl implements TestServer   {

           public string sayHello(String name)

             {

                   return "hello"+name;

             }

           }

     业务代码和以前一样,不需要特别的处理

4. 编写rest接口

     @Path("/test")

     @Service

     public class TestRestServer{

             @Resource(name="testServerImpl")

                  private TestServer testServer;

                 @GET

                 @Path("/hello")

                 @Produces(MediaType.APPLICATION_JSON)

                 public String sayHello(@QueryParam("name") String name)

                  {

                       return testServer.sayHello(name);

                   }

}

该类中有很多rest标注,如果你不懂请参考,(http://www.ibm.com/developerworks/cn/web/wa-apachewink1

该类用来将javabean暴露成rest接口,同时它也是受管于Spring,同样可以通过简单的@Resource注入对应的资源,是不是很简单。

5. Spring 配置文件

     <bean class= "org.apache.wink.spring.Registrar" >

           <property name="classes" >

                  <set value-type= "java.lang.Class" >

                         <value>

                              org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider

                        </value>

                 </set>

       </property>

       <property name="instances" >

                    <set>

                         <ref bean="testRestServer" />

                     </set>

       </property>

</bean>

Registrar类主要完成对ProviderResource的注册工作

有两种属性:

       Classes:指定类,格式;包+类名

       Instances:spring管理对象的引用

通过上述几步我们就完成了Springapache wink的简单集成

第三部分 Ajax调用Rest服务

1. 客服端javascript

     为了方便页面调用,对jqueryajax调用进行了简单封装

     function restClient()

{

/**

 * 使用get方式调用服务

 * @param url 资源地址

 * @param data 参数

 * @param dataType 返回值类型

 * @param contentType 访问类型或参数类型

 * @param cache 是否缓存

 * @param async 是否异步加载

 * @param success 成功时回调函数

 * @param error 失败时回调函数

 */

this.get=function get(url,data,dataType,contentType,cache,async,success,error)

{  

        ajax("GET",url,data,dataType,contentType,cache,async,success,error);

};

/**

 * 使用post方式调用服务

 * @param url 资源地址

 * @param data 参数

 * @param dataType 返回值类型

 * @param contentType 访问类型或参数类型

 * @param cache 是否缓存

 * @param async 是否异步加载

 * @param success 成功时回调函数

 * @param error 失败时回调函数

 */

this.post=function post(url,data,dataType,contentType,cache,async,success,error)

{

 ajax("POST",url,data,dataType,contentType,cache,async,success,error);

};

/**

 * 使用put方式调用服务

 * @param url 资源地址

 * @param data 参数

 * @param dataType 返回值类型

 * @param contentType 访问类型或参数类型

 * @param cache 是否缓存

 * @param async 是否异步加载

 * @param success 成功时回调函数

 * @param error 失败时回调函数

 */

this.put=function put(url,data,dataType,contentType,cache,async,success,error)

{

 ajax("PUT",url,data,dataType,contentType,cache,async,success,error);

};

/**

 * 使用delete方式调用服务

 * @param url 资源地址

 * @param data 参数

 * @param dataType 返回值类型

 * @param contentType 访问类型或参数类型

 * @param cache 是否缓存

 * @param async 是否异步加载

 * @param success 成功时回调函数

 * @param error 失败时回调函数

 */

this.del=function del(url,data,dataType,contentType,cache,async,success,error)

{

ajax("DELETE",url,data,dataType,contentType,cache,async,success,error);

};

/**

 * 将form表单转化为json数组

 * @param formid form表单id

 * @returns json数组

 */

this.form2Json=function form2Json(formid) {   

    var formObj = $("#"+formid);   

    var JsonObj = "'{";   

    var a = formObj.serializeArray();   

    var index = 0;   

    $.each(a, function() {   

        index++;   

        JsonObj += "\"" + this.name + "\":\"" + this.value + "\"";   

        if(a.length != 1 && a.length != index) {   

            JsonObj += ",";   

        }   

    });   

    JsonObj += "}'";   

    return eval(JsonObj);   

};   

/**

 * jquery ajax方法

 * @param type 调用类型

 * @param url 资源地址

 * @param data 参数

 * @param dataType 返回值类型

 * @param contentType 访问类型或参数类型

 * @param cache 是否缓存

 * @param async 是否异步加载

 * @param success 成功时回调函数

 * @param error 失败时回调函数

 */

function ajax(type,url,data,dataType,contentType,cache,async,success,error)

{

      $.ajax(

        {

      type: type,

      data: data,

      dataType:dataType,

      contentType:contentType,

      url:url,

      success: success,

      error: error,

      async:async,

      cache:cache

    });

}

}

2. 调用代码

     function sayHello()

{

var rc=new restClient(); 

Var parameter={};

Parameter.name="xxx";

rc.post("http://xx.x.x.x:xx/xxxx/rest/test/hello",parameter,"json",'application/json',false,false,success,error);

}

function success(data, textStatus)

{

   Alert(data);

}

function error()

{

  alert("调用失败");

};

自此springwink集成与调用就完成了,但是需要注意的是,如果在调用中出行调用失败时,请查看一下是否是:你的服务与你的调用页面不在一个域里,如果出现跨域问题,可以通过apache代理解决

最后祝你工作愉快

注:apache wink 地址:http://incubator.apache.org/wink/

例子下载地址:http://download.csdn.net/detail/kehongyong/4167213

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:16013次
    • 积分:295
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:5篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论