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

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

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

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.0.0.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.0.0.RELEASE</version>
</dependency>


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

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
</dependency>


3. 更改spring 的命名空间
记得一定在 xml 配置文件里面修改


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

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.3.0</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.3.0</version>
</dependency>

另外,如果你是显示的注册了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<ResponseEntity<Series[]>> futureEntity = asyncRestTemplate.getForEntity(BASE_URI, Series[].class);
    logger.info("Doing other async stuff...");
    
    logger.info("Blocking to receive response...");
    ResponseEntity<Series[]> 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<ResponseEntity<Series[]>> futureEntity = asyncRestTemplate.getForEntity(BASE_URI, Series[].class);
    futureEntity.addCallback(new ListenableFutureCallback<ResponseEntity<Series[]>>() {
        @Override
        public void onSuccess(ResponseEntity<Series[]> 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 下面,其实改动并不多.

除非申明,文章均为一号门原创,转载请注明本文地址,谢谢!
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: spring
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.