Maven学习笔记-05-Jersey 与 Spring 的集成

     最近对自己做过的项目进行一个梳理,其中主要用到了RESTful的Web服务框架 Jersey ,并与Spring进行了集成。在此对Jersey框架进行一个总结。

一  RESTful的web框架 Jersey

  Jersey RESTful 框架是开源的RESTful框架, 实现了 JAX-RS 规范。它扩展了JAX-RS 参考实现, 提供了更多的特性和工具, 可以进一步地简化 RESTful service 和 client 开发。
  REST 中最重要的概念是资源(resources),使用全球 ID(通常使用 URI)标识。客户端应用程序使用 HTTP 方法(GET/ POST/ PUT/ DELETE)操作资源或资源集。RESTful Web 服务是使用 HTTP 和 REST 原理实现的 Web 服务. 比如 RESTful Web 服务示例如下图所示:

 

二 Jersey与Spring进行集成

项目中使用到的技术和环境:

Jersey 1.8
Spring 3.0.5.RELEASE
Maven 3
JDK 1.7
Eclipse 4.5.1

1. 项目依赖

   在项目中 Jersey , Spring 的依赖文件放在了 Maven工程的 pom.xml文件

<dependencies>
    <!-- Jersey -->
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-server</artifactId>
        <version>1.8</version>
    </dependency>
    <!-- Spring 3 dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>3.0.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.0.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>3.0.5.RELEASE</version>
    </dependency>
    <!-- Jersey + Spring -->
    <dependency>
        <groupId>com.sun.jersey.contribs</groupId>
        <artifactId>jersey-spring</artifactId>
        <version>1.8</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
<!-- Json --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.23</version> </dependency> </dependencies> <repositories> <repository> <id>maven2-repository.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2/</url> </repository> <repository> <id>oschina Releases</id> <name>oschina Releases</name> <url>http://maven.oschina.net/content/groups/public</url> </repository> <repository> <id>nexus-osc</id> <name>Nexus osc</name> <url>http://maven.oschina.net/content/groups/public/</url> </repository> <repository> <id>nexus-osc-thirdparty</id> <name>thirdparty</name> <url>http://maven.oschina.net/content/repositories/thirdparty/</url> </repository> <!-- jesery插件仓库 --> <repository> <id>snapshot-repository.java.net</id> <name>Java.net Snapshot Repository for Maven</name> <url>https://maven.java.net/content/repositories/snapshots/</url> <layout>default</layout> </repository> </repositories>

 2. Spring Bean

  生成一个简单的 ”transactionBo“ Bean,然后把它注册于 Spring Container容器中。稍后把它注入到  Jersey 服务中。

TransactionBo.java
package com.xinping.transaction;

import com.alibaba.fastjson.JSONObject;

public interface TransactionBo
{
    String save();
    
    public JSONObject findInfo();
}
TransactionBoImpl.java
package com.xinping.transaction.impl;

import com.alibaba.fastjson.JSONObject;
import com.xinping.transaction.TransactionBo;

public class TransactionBoImpl implements TransactionBo 
{
    public String save() {

        return "Jersey集成Spring 测试例子";

    }
    
    public JSONObject findInfo(){
        JSONObject json = new JSONObject();
        json.put("name", "xinping");
        json.put("age", "35");
        return json;
    }
    
}

 在 src/main/resources下新建 applicationContext.xml 文件,负责注册bean 和启动组件自动扫描功能。

<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-3.0.xsd 
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
    <context:component-scan base-package="com.xinping.rest" />
    
    <bean id="transactionBo" 
           class="com.xinping.transaction.impl.TransactionBoImpl" />
 
</beans>

3. Jersey

在 RESTFUL方法中,可以使用Spring 框架的自动注入功能,把 transactionBo 注入到 Jersey 服务中。

package com.xinping.rest;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.xinping.transaction.TransactionBo; @Component @Path(
"/payment") public class PaymentService { @Autowired TransactionBo transactionBo;
@GET
    @Path("/sayHello")
    @Produces("application/json")
    public Response sayHello(@DefaultValue("") @QueryParam("name") String name) {
        JSONObject userObj = new JSONObject();
        userObj.put("name", name);
        userObj.put("age", new Integer(20));
        userObj.put("time", new Date());
        userObj.put("address", null);
        System.out.println(userObj.toJSONString());

        return Response.status(200).entity(userObj.toJSONString()).build();
    }
@GET @Path(
"/save")
  @Produces("application/json")
public Response savePayment() { String result = transactionBo.save(); return Response.status(200).entity(result).build(); } @GET @Path("/findInfo") public Response findInfo() { JSONObject result = transactionBo.findInfo(); Map<String,String> map = new HashMap<String,String> (); map.put("name", "wangwu"); map.put("addresss", "beijing"); return Response.ok(result.toJSONString()).build(); } }

4. 集成 Jersey与 Spring

  核心的注入代码在  web.xml中。

1.  注册Spring “ContextLoaderListener”  监听器。

2.  配置Jersey servlet 为 “com.sun.jersey.spi.spring.container.servlet.SpringServlet“。

web.xml

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Restful Web Application</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>
            com.sun.jersey.spi.spring.container.servlet.SpringServlet
        </servlet-class>
        <init-param>
            <param-name>
                   com.sun.jersey.config.property.packages
            </param-name>
            <param-value>com.xinping.rest</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

</web-app>

5. 测试访问

http://localhost:8080/oneWeb1/rest/payment/save
http://localhost:8080/oneWeb1/rest/payment/findInfo
http://localhost:8080/oneWeb1/rest/payment/sayHello?name=lisi

 

 

6 异步调用服务

http://docs.huihoo.com/jersey/2.13/async.html

TestCaseModel.java

package cn.com.ctsi.csdp.user.api.rest.biscuit;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
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.QueryParam;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.container.TimeoutHandler;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.wordnik.swagger.annotations.Api;

import cn.com.ctsi.csdp.base.rest.WebService;
import cn.com.ctsi.csdp.base.rest.result.ObjectRESTResult;

@Path("/testcase")
@Api(value = "/testcase", description = "rest api for api gateway",position=0)
@Component("biscuitTestcase")
public class TestCaseModel extends WebService {

    Logger logger = Logger.getLogger(TestCaseModel.class);
    
    public TestCaseModel(@Context UriInfo uriInfo, @Context HttpHeaders headers,
            @Context SecurityContext securityContext) {
        super(uriInfo, headers, securityContext);
    }

    public TestCaseModel() {
    }
    
    
    @Context
    private HttpServletRequest request;
    
    
        
    /**
     * 显示时间
     * http://127.0.0.1:8083/auth/api/v2/testcase/showTime
     * 
     */
    @GET
    @Path("/showTime")
    @Produces(MediaType.APPLICATION_JSON)
    public Response showTime() {
        logger.info("*********  TestCaseModel showTime  **************");
        
        Map<String, Object> result = new HashMap<String, Object>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        result.put("time", dateFormat.format(new Date()));
        result.put("desc", "resource showTime");
        return Response.ok(result).build();
    }
    
    /**
     * 显示时间
     * http://127.0.0.1:8083/auth/api/v2/testcase/sayHello?name=wangwu&age=20
     * 
     */
    @GET
    @Path("/sayHello")
    @Produces(MediaType.APPLICATION_JSON)
    public Response sayHello(@QueryParam("name") String name,@QueryParam("age") String age) {
        logger.info("*********  TestCaseModel sayHello  **************");
        logger.info("name=" + name);
        logger.info("age=" + age);
        Map<String, Object> result = new HashMap<String, Object>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        result.put("time", dateFormat.format(new Date()));
        result.put("name", name);
        result.put("age", age);
        
        return Response.ok(result).build();
    }
    
    /**
     * http://127.0.0.1:8083/auth/api/v2/testcase/findProjectsById/1112222
     * 
     */
    @GET
    @Path("/findProjectsById/{project_id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response findProjectsById(@PathParam("project_id") String projectId,@QueryParam("name") String name ) throws Exception{
        logger.info("*********  TestCaseModel findProjectsById  **************");
        logger.info("projectId" + projectId);
        logger.info("name" + name);
        
        Map<String, Object> result = new HashMap<String, Object>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        result.put("time", dateFormat.format(new Date()));
        result.put("projectId", projectId);
        result.put("name", name);
        
        return Response.ok(result).build();
    }

    /**
     * http://127.0.0.1:8083/auth/api/v2/testcase/v2.0/createV2Project

        {
            "name": "wangwu",
            "age": 23
        }
    
     * 
     */
    @POST
    @Path("/v2.0/createV2Project")
    @Produces(MediaType.APPLICATION_JSON)
    public Response createV2Project(String json) throws Exception{
        logger.info("*********  TestCaseModel createV2Project  **************");
        logger.info("json" + json);
        
        Map<String, Object> result = new HashMap<String, Object>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        result.put("time", dateFormat.format(new Date()));
        JSONObject body = JSONObject.parseObject(json);
        String name = (String) body.get("name");
        Integer age = (Integer) body.get("age");
        result.put("name", name);
        result.put("age", age);
        
        return Response.ok(result).build();
    }
    
    
    /**
     * http://127.0.0.1:8083/auth/api/v2/testcase/showDatas
     * 
     */
    @GET
    @Path("/showDatas")
    @Produces(MediaType.APPLICATION_JSON)
    public Response showDatas( ) throws Exception{
        logger.info("*********  TestCaseModel showDatas  **************");        
        Map<String, Object> result = new HashMap<String, Object>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        result.put("time", dateFormat.format(new Date()));
    
        List list = new ArrayList(); 
        Map record1 = new HashMap();
        record1.put("uuid", "8f6cae8a24ab4d0887dd5907430075e7");
        record1.put("created", "1496800026000");
        record1.put("username", "test03-SD");
        record1.put("contractNumber", "131");
        
        Map record2 = new HashMap();
        record2.put("name", "8bbf9fded675472aa852cf1940bc8234");
        record2.put("created", "1489479452000");
        record2.put("username", "test02");
        record2.put("contractNumber", "132");

        Map record3 = new HashMap();
        record3.put("name", "156b396f9b354467b5d1d1a1014b2d10");
        record3.put("created", "1487576620000");
        record3.put("username", "test01");
        record2.put("contractNumber", "133");
        
        list.add(record1);
        list.add(record2);
        list.add(record3);
        
        result.put("resources", list);
        result.put("total", 3);
        result.put("pageNum", 1);
        
        return Response.ok(result).build();
    }
    
     /**
         http://127.0.0.1:8083/auth/api/v2/testcase/asyncGetWithTimeout
      * 
      */
     @GET
      @Path("/asyncGetWithTimeout")
      @Produces(MediaType.APPLICATION_JSON)
     public void asyncGetWithTimeout(@Suspended final AsyncResponse asyncResponse) {
         logger.info("******** asyncGetWithTimeout **********");
         asyncResponse.setTimeoutHandler(new TimeoutHandler() {

             @Override
             public void handleTimeout(AsyncResponse asyncResponse) {
              /*   asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)
                         .entity("Operation time out.").build());*/
                 
                 Response response = Response.status(Response.Status.SERVICE_UNAVAILABLE.getStatusCode()).entity(new ObjectRESTResult(Response.Status.SERVICE_UNAVAILABLE.getStatusCode(),"Your Operation time out,please check it。",null)).build();
                 asyncResponse.resume(response);                 
             }
         });
         asyncResponse.setTimeout(10, TimeUnit.SECONDS);

         new Thread(new Runnable() {

             @Override
             public void run() {
                     Map msg = new HashMap();
                     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
                     msg.put("begintime", dateFormat.format(new Date()));
                
                     String result = veryExpensiveOperation();
                     msg.put("msg",result);
                    msg.put("endtime", dateFormat.format(new Date()));
                    msg.put("statusCode",200);
                    asyncResponse.resume(msg);
             }

             private String veryExpensiveOperation() {
                 logger.info("* begin veryExpensiveOperation ");
                     try
                    {
                        Thread.sleep( 3 * 1000);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                     logger.info("* end veryExpensiveOperation ");
                     
                     return "hello csdp, bbb";
             }
         }).start();
     }
    
    
}

 

 二 生产环境中的restful

添加资源请求

 

 

修改资源请求

 

删除资源请求

 

查看资源请求

 

参考资料:

http://www.lifeba.org/arch/restlet_develop_jax-rs_service_1.html

 

posted @ 2016-06-10 03:25  陈晓楠  阅读(114)  评论(0编辑  收藏  举报