使用 Spring + CXF 发布 REST 服务

第一步:添加 Maven 依赖


<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>demo.ws</groupId>
    <artifactId>rest_spring_cxf</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.0.6.RELEASE</spring.version>
        <cxf.version>3.0.0</cxf.version>
        <jackson.version>2.4.1</jackson.version>
    </properties>

    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- CXF -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <!-- Jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-json-provider</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>

</project>

这里仅依赖 Spring Web 模块(无需 MVC 模块),此外就是 CXF 与 Jackson 了。

第二步:配置 web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         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"
         version="3.0">

    <!-- Spring -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- CXF -->
    <servlet>
        <servlet-name>cxf</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxf</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>

</web-app>

使用 Spring 提供的 ContextLoaderListener 去加载 Spring 配置文件 spring.xml;使用 CXF 提供的 CXFServlet 去处理前缀为 /ws/ 的 REST 请求。

第三步:将接口的实现类发布 SpringBean


package demo.ws.rest_spring_cxf;

import org.springframework.stereotype.Component;

@Component
public class ProductServiceImpl implements ProductService {
    ...
}

使用 Spring 提供的 @Component 注解,将 ProductServiceImpl 发布为 Spring Bean,交给 Spring IOC 容器管理,无需再进行 Spring XML 配置。

第四步:配置 Spring

以下是 spring.xml 的配置:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:component-scan base-package="demo.ws"/>

    <import resource="spring-cxf.xml"/>

</beans>

在以上配置中扫描 demo.ws 这个基础包路径,Spring 可访问该包中的所有 Spring Bean,比如,上面使用 @Component 注解发布的 ProductServiceImpl。此外,加载了另一个配置文件 spring-cxf.xml,其中包括了关于 CXF 的相关配置。

以下是 spring-cxf.xml 的配置:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://cxf.apache.org/jaxrs
       http://cxf.apache.org/schemas/jaxrs.xsd">

    <jaxrs:server address="/rest">
        <jaxrs:serviceBeans>
            <ref bean="productServiceImpl"/>
        </jaxrs:serviceBeans>
        <jaxrs:providers>
            <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
        </jaxrs:providers>
    </jaxrs:server>

</beans>

使用 CXF 提供的 Spring 命名空间来配置 Service Bean(即上文提到的 Resource Class)与 Provider。注意,这里配置了一个 address 属性为“/rest”,表示 REST 请求的相对路径,与 web.xml 中配置的“/ws/*”结合起来,最终的 REST 请求根路径是“/ws/rest”,在 ProductService 接口方法上 @Path 注解所配置的路径只是一个相对路径。

第五步:调用 REST 服务


<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <link href="http://cdn.bootcss.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>

<div class="container">
    <div class="page-header">
        <h1>Product</h1>
    </div>
    <div class="panel panel-default">
        <div class="panel-heading">Product List</div>
        <div class="panel-body">
            <div id="product"></div>
        </div>
    </div>
</div>

<script src="http://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="http://cdn.bootcss.com/handlebars.js/1.3.0/handlebars.min.js"></script>

<script type="text/x-handlebars-template" id="product_table_template">
    {{#if data}}
        <table class="table table-hover" id="product_table">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Product Name</th>
                    <th>Price</th>
                </tr>
            </thead>
            <tbody>
                {{#data}}
                    <tr data-id="{{id}}" data-name="{{name}}">
                        <td>{{id}}</td>
                        <td>{{name}}</td>
                        <td>{{price}}</td>
                    </tr>
                {{/data}}
            </tbody>
        </table>
    {{else}}
        <div class="alert alert-warning">Can not find any data!</div>
    {{/if}}
</script>

<script>
    $(function() {
        $.ajax({
            type: 'get',
            url: 'http://localhost:8080/ws/rest/products',
            dataType: 'json',
            success: function(data) {
                var template = $("#product_table_template").html();
                var render = Handlebars.compile(template);
                var html = render({
                    data: data
                });
                $('#product').html(html);
            }
        });
    });
</script>

</body>
</html>

使用一个简单的 HTML 页面来调用 REST 服务,也就是说,前端发送 AJAX 请求来调用后端发布的 REST 服务。这里使用了 jQuery、Bootstrap、Handlebars.js 等技术。

posted on 2017-08-17 17:11  baorant  阅读(445)  评论(0编辑  收藏  举报

导航