使用Spring 3.1和基于Java的配置构建RESTful Web服务,第2部分

1.概述

本文介绍了如何在Spring中设置REST –控制器和HTTP响应代码,有效负载编组配置和内容协商。

2.在Spring了解REST

Spring框架支持两种创建RESTful服务的方式:

  • ModelAndView一起使用MVC
  • 使用HTTP消息转换器

ModelAndView方法较旧,文档记载得更好,但也很冗长,配置繁重。 它试图将REST范式转换为旧模型,但这并非没有问题。 Spring团队对此有所了解,并从Spring 3.0开始提供了一流的REST支持。

基于HttpMessageConverter注释的新方法轻巧得多,易于实现。 配置是最小的,它为RESTful服务提供了合理的默认值。 但是,它在文档方面比较新,有点轻松。 更重要的是,参考并不能完全消除两者之间的区别和权衡取舍。 尽管如此,这是在Spring 3.0之后构建RESTful服务的方式。

3. Java配置

@Configuration
@EnableWebMvc
public class WebConfig{
   //
}

新的@EnableWebMvc注释做了很多有用的事情-特别是在REST的情况下,它检测到类路径中存在Jackson和JAXB 2,并自动创建并注册默认的JSON和XML转换器 。 注释的功能等效于XML版本:

<mvc:注释驱动/>

这是一个捷径,尽管在许多情况下可能有用,但它并不完美。 当需要更复杂的配置时,请删除注释并直接扩展WebMvcConfigurationSupport

4.测试Spring上下文

Spring 3.1开始, 我们获得@Configuration类的一流测试支持:

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( classes = { ApplicationConfig.class, PersistenceConfig.class },
 loader = AnnotationConfigContextLoader.class )
public class SpringTest{

   @Test
   public void whenSpringContextIsInstantiated_thenNoExceptions(){
      // When
   }
}

只需使用@ContextConfiguration批注指定Java配置类,新的AnnotationConfigContextLoader即可@Configuration类加载Bean定义。

注意, WebConfig配置类未包含在测试中,因为它需要在未提供的Servlet上下文中运行。

5.控制器

@Controller是RESTful API整个Web层中的中心构件。 出于本文的目的,控制器正在对简单的REST资源– Foo建模:

@Controller
@RequestMapping( value = "foo" )
class FooController{

   @Autowired
   IFooService service;

   @RequestMapping( method = RequestMethod.GET )
   @ResponseBody
   public List< Foo > getAll(){
      return service.getAll();
   }

   @RequestMapping( value = "/{id}", method = RequestMethod.GET )
   @ResponseBody
   public Foo get( @PathVariable( "id" ) Long id ){
      return RestPreconditions.checkNotNull( service.getById( id ) );
   }

   @RequestMapping( method = RequestMethod.POST )
   @ResponseStatus( HttpStatus.CREATED )
   @ResponseBody
   public Long create( @RequestBody Foo entity ){
      RestPreconditions.checkNotNullFromRequest( entity );
      return service.create( entity );
   }

   @RequestMapping( method = RequestMethod.PUT )
   @ResponseStatus( HttpStatus.OK )
   public void update( @RequestBody Foo entity ){
      RestPreconditions.checkNotNullFromRequest( entity );
      RestPreconditions.checkNotNull( service.getById( entity.getId() ) );
      service.update( entity );
   }

   @RequestMapping( value = "/{id}", method = RequestMethod.DELETE )
   @ResponseStatus( HttpStatus.OK )
   public void delete( @PathVariable( "id" ) Long id ){
      service.deleteById( id );
   }

}

Controller的实现是非公开的 –这是因为不需要这样做。 通常,控制器是依赖关系链中的最后一个控制器–它从Spring前端控制器( DispathcerServlet )接收HTTP请求,然后简单地将它们委托给服务层。 如果没有用例必须通过直接引用来注入或操纵控制器,则我不希望将其声明为公共。

请求映射很简单–与任何控制器一样,映射的实际以及HTTP 方法都用于确定请求的目标方法。 @ RequestBody将方法的参数绑定到HTTP请求的主体,而@ResponseBody对响应和返回类型执行相同的操作。 它们还确保使用正确的HTTP转换器对资源进行编组和解组。 尽管也可以使用其他HTTP头来确定表示形式,但将主要根据Accept头进行内容协商,以选择使用哪个活动转换器。

6.映射HTTP响应代码

HTTP响应的状态码是REST服务最重要的部分之一,因此主题很快就会变得非常复杂。 正确执行这些操作可能会导致或中断服务。

6.1。 未映射的请求

如果Spring MVC收到没有映射的请求,则认为该请求不被允许,并向客户端返回405 METHOD NOT ALLOWED NOT ALLOWED 。 这也是很好的做法,包括允许 HTTP标头返回一个405到客户端时,以指定哪些操作允许的。 这是Spring MVC的标准行为,不需要任何其他配置。

6.2。 有效的映射请求

对于任何确实具有映射的请求,Spring MVC认为该请求有效,如果未指定其他状态代码,则响应为200 OK 。 因此,控制器为createupdatedelete动作声明了不同的@ResponseStatus ,但为get声明了不同的@ResponseStatus ,实际上应该返回默认的200 OK。

6.3。 客户端错误

如果发生客户端错误 ,则会定义自定义异常并将其映射到适当的错误代码。 只需从Web层的任何层抛出这些异常,即可确保Spring在HTTP响应上映射相应的状态代码。

@ResponseStatus( value = HttpStatus.BAD_REQUEST )
public class BadRequestException extends RuntimeException{
   //
}
@ResponseStatus( value = HttpStatus.NOT_FOUND )
public class ResourceNotFoundException extends RuntimeException{
   //
}

这些例外是REST API的一部分,因此,仅应在与REST相对应的适当层中使用; 例如,如果存在DAO / DAL层,则不应直接使用异常。 还要注意,这些不是经过检查的异常,而是运行时异常 –与Spring的实践和习惯用法一致。

6.4。 使用@ExceptionHandler

将自定义异常映射到特定状态代码的另一种方法是在控制器中使用@ExceptionHandler批注。 这种方法的问题在于,注释仅适用于定义了它的控制器,而不适用于整个Spring容器,这意味着需要在每个控制器中分别声明它。 这很快变得很麻烦,尤其是在具有许多控制器的更复杂的应用程序中。 目前,Spring已解决了一些JIRA问题 ,以解决此限制和其他相关限制: SPR-8124SPR-7278SPR-8406

7.其他Maven依赖项

除了标准Web应用程序所需spring-webmvc依赖关系之外,我们还需要为REST API设置内容编组和解编组:

<dependencies>
   <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
   </dependency>
   <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>${jaxb-api.version}</version>
      <scope>runtime</scope>
   </dependency>
</dependencies>

<properties>
   <jackson.version>2.2.2</jackson.version>
   <jaxb-api.version>2.2.9</jaxb-api.version>
</properties>

这些库用于将REST资源的表示形式转换为JSONXML

8.结论

这篇文章介绍了使用Spring 3.1和基于Java的配置对RESTful服务的配置和实现,并讨论了HTTP响应代码,基本内容协商和封送处理。

在本系列的下一篇文章中,我将重点介绍API的可发现性 ,高级内容协商以及使用资源的其他表示形式 。 同时,检查github项目

参考:来自baeldung博客的JCG合作伙伴 Eugen Paraschiv 使用Spring 3和Java Config构建REST API

翻译自: https://www.javacodegeeks.com/2011/11/building-restful-web-service-with.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值