spring3 restful 服务迁移到 spring4需要注意的事项

摘要: Spring4 对MVC 应用进行了一些改进, 首先测试了在restful 服务上的改进, 至少目前看来需要注意的有如下两点:1.  从@ResponseBody 改成 @RestController2. Synchronous 和 Asynchronous 调用,也就是同步异步调用.

Spring4 对MVC 应用进行了一些改进, 首先测试了在restful 服务上的改进, 至少目前看来需要注意的有如下两点:
1. 从@ResponseBody 改成 @RestController
2. Synchronous 和 Asynchronous 调用,也就是同步异步调用.

下面是从spring3 mvc 迁移到 spring4 mvc 工程的系列步骤:
1. 引入 spring 4 的jar 包,如果是 maven 的话,用spring4的依赖


    org.springframework
    spring-context
    4.0.0.RELEASE



    org.springframework
    spring-webmvc
    4.0.0.RELEASE



2. 引入 servlet 3.0 的依赖包
这个比较重要,spring4 的有些特性是在 servlet3.0 上实现的。

    javax.servlet
    javax.servlet-api
    3.1.0



3. 更改spring 的命名空间
记得一定在 xml 配置文件里面修改
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
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd


4. jackson 版本的变化,一定要采用2.0 以上版本

    com.fasterxml.jackson.core
    jackson-core
    2.3.0



    com.fasterxml.jackson.core
    jackson-databind
    2.3.0


另外,如果你是显示的注册了message convert, 那么你还得自己配置如下代码, 因为jackson 1.x 版本已经过期了:
//converters.add(new MappingJacksonHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter());


5. 可以在类级别上实现@ResponseBody 注解,下面的方法自动继承这个注解,不需要都配置
@Controller
@ResponseBody
public class SeriesController {
...
}

上面的配置可以用一个更简单的方法来配置, 这两者是等价的.
@RestController
public class SeriesController {
...
}


6. RestTemplate 调用 restful service 时的异步解决方法,和处理回调函数
在使用 RestTemplate 调用 restful service 时将会阻塞, 直到得到结果。在spring4 中增加了异步调用方法, 在调用方法的过程中,仍然可以执行其他计算,在后面在获取得到的结果
@Test
public void getAllSeriesAsync() throws InterruptedException, ExecutionException {
    logger.info("Calling async /series");
    Future> futureEntity = asyncRestTemplate.getForEntity(BASE_URI, Series[].class);
    logger.info("Doing other async stuff...");
    
    logger.info("Blocking to receive response...");
    ResponseEntity entity = futureEntity.get();
    logger.info("Response received");
    Series[] series = entity.getBody();
    
    assertNotNull(series);
    assertEquals(2, series.length);
    assertEquals(1L, series[0].getId());
    assertEquals("The walking dead", series[0].getName());
    assertEquals("USA", series[0].getCountry());
    assertEquals("Thriller", series[0].getGenre());
    assertEquals(2L, series[1].getId());
    assertEquals("Homeland", series[1].getName());
    assertEquals("USA", series[1].getCountry());
    assertEquals("Drama", series[1].getGenre());
}


虽然上面的方法解决了异步调用,但在得到结果的 futureEntity.get() 方法还是会阻塞的,如果结果还没有得到的话。 其实这里用到的就是 多线程里面的 Future 模式,你可以看到 RestTemplate 返回的是 ListenableFuture, 这个类是可以注册一个回调函数的,把结果交给回调函数去处理. 如下例子:
@Test
public void getAllSeriesAsyncCallable() throws InterruptedException, ExecutionException {
    logger.info("Calling async callable /series");
    ListenableFuture> futureEntity = asyncRestTemplate.getForEntity(BASE_URI, Series[].class);
    futureEntity.addCallback(new ListenableFutureCallback>() {
        @Override
        public void onSuccess(ResponseEntity entity) {
            logger.info("Response received (async callable)");
            Series[] series = entity.getBody();
            validateList(series);
        }
        
        @Override
        public void onFailure(Throwable t) {
            fail();
        }
    });
    
    logger.info("Doing other async callable stuff ...");
    Thread.sleep(6000); //waits for the service to send the response
}


这样就能成功的将spring3 工程转移到 sping4 下面,其实改动并不多.

上一篇: Hibernaate 调用存储过程的方法
下一篇: Django 设置cookies与获取cookies.
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号