SpringMVC构建REST服务

一、REST简介

    REST (Representional State Transfer 表述性状态转移)是 Web 服务的一种架构风格;使用 HTTP、URI、XML、JSON、HTML 等广泛流行的标准和协议;轻量级,跨平台,跨语言的架构设计风格。

REST架构主要原则
  • 网络上的所有事物都被抽象成资源
  • 每个资源都有唯一的资源标识符
  • 同一个资源具有多种表现形式(XML、JSON 等)
  • 对资源的各种操作不会改变资源标识符
  • 所有的操作都是无状态的
    符合 REST 原则的架构方式 即可 称为 RESTful。

二、Spring 支持 REST

1.支持的方式
  • 控制器可以处理所有的 HTTP 方法,包括四个主要的 REST 方法:
GET
PUT
DELETE
POST
  • 通过 @PathVariable 注解,控制器能够处理参数化 URL(把变量作为 URL 的一部分)
  • 借助 Spring 的视图 和 视图解析器,资源能够以 多种方式 进行表达,包括将模型数据 渲染成 XML、JSON、AtomRSS 的 view 实现
  • 使用 ContentNegotiatingViewResolver (内容协商视图解析器) 来选择最合适的客户端的表述
  • 借助 @ResponseBody 注解 和 各种 HttpMessageConverter 实现,能够替换基于视图的渲染方式
  • 借助 @RequestBody 注解 和 各种 HttpMessageConverter 实现,能够将传入的 HTTP 请求数据转化为传入控制器处理方法的 Java 对象
  • 借助 RestTemplate 类 Spring应用能方便地使用 REST 资源
2.资源转换

    Spring 提供了两种方法将资源的 Java 表达形式 转换成 发送给客户端的表述形式。

  • 内容协商(Content Negotiation):
    选择一个视图,它能够将模型渲染为 呈现给客户端的表述形式。

  • 消息转换器(Message Conversion):
    通过一个消息转化器将控制器所返回的对象转换成 呈现给客户端的表述形式。

3.内容协商

    内容协商是在 Spring MVC 之上构建的 REST 资源表述层,控制器代码无需修改,相同的一套控制器方法能够 面向人类用户 产生 HTML 内容,也能针对不是人类的 客户端 产生 JSON 或 XML。
    如果面向人类用户的接口 和 面向非人类的 客户端 的接口有很多重叠的话,那么内容协商就是一种很便利的方案。(反之,它的优势就体现不出来了)
    内容协商还有一个严重的限制,作为 ViewResolver 实现,它 只能决定 资源如何渲染到客户端 ,并没有涉及到 客户端要发送什么样的表述给控制器使用。如果客户端发送 JSON 或者 XML 的话,那么内容协商就无法提供帮助了。

消息转换器

    消息转换器提供了一种更为直接的方法,它能够将控制器产生的数据 转换为 服务 与 客户端 的 表述形式。当使用消息转换功能时, DispatchServlet 不再需要那么麻烦地将模型数据传送到 视图中。 实际上,也根本没有了模型和视图,只有控制器产生的数据,以及消息转换器 (Message Conversion)转换数据之后所产生的资源表述。
    
举例:假设 客户端通过请求的 Accept 头信息 表明 它能够接受 application/json,并且 Jackson JSON 库在类路径下,那么处理方式返回的对象将交给 MappingJacksonHttpMessageConvert ,并且 它转换为 客户端的 JSON 表述形式。另外,如果请求头的信息表明 客户端相应 text/xml 格式,那么
Jaxb2RootElementHttpMessageConverter 将会作为客户端产生 XML 相应。

    Spring 提供了多个 HTTP 消息转换器,用于实现资源表述与各种Java类型之间的互相转换,下面列出几个常用的消息转换器:

  • MappingJackson2HttpMessageConverter :
    在JSON和类型化对象或者非类型化的 HashMap 间互相读取和写入,如果 Jackson 2 JSON 库在类路径下将进行注册。

  • GsonHttpMessageConverter :
    在JSON和类型化对象或者非类型化的 HashMap 间互相读取和写入,如果
    Gson 库在类路径下将进行注册。

  • FormHttpMessageConverter :
    application/x-www-form-urlencoded 内容读入到 MultiValueMap<String,String> 中,也会将 MultiValueMap<String,String> 写入到 application/x-www-form-urlencoded 中或将MultiValueMap<String,Object>写入到 multipart/form-data 中。

  • StringHttpMessageConverter :
    将所有媒体类型(/)读取为String,将String写入为text/plain

  • Jaxb2RootElementHttpMessageConverter :
    在XML(text/xml或者application/xml)和使用JAXB2注解对象间相互读取和写入,如果JAXB v2库在类路径下将进行注册
    等等

    尽管Spring支持了多种资源表述形式,以及多种消息转化器。但是在定义REST API的时候,不一定全部使用它们。
    对于大多数客户端来说,使用 JSON 和 XML 来进行表述就足够了。

  • 备注:实际在REST API中大多数情况表述都是用JSON格式

三、创建 REST 项目

    首先创建Maven Web项目,选择 webapps 骨架;接下来修改项目结构:
创建WEB项目中需的目录:
在这里插入图片描述
在 pom.xml 中导入 jar 包依赖:

<?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>com.jia</groupId>
  <artifactId>SpringMVCRESTful</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SpringMVCRESTful Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--Spring MVC依赖-->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <!--日志依赖-->
    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <!--文件上传依赖-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
    <!--第一种-->
    <!--MappingJacksonHttpMessageConverter依赖-->
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.8</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider -->
    <dependency>
      <groupId>com.fasterxml.jackson.jaxrs</groupId>
      <artifactId>jackson-jaxrs-json-provider</artifactId>
      <version>2.9.9</version>
    </dependency>
    <!--第二种-->
    <!--GsonHttpMessageConverter依赖,JSON处理库-->
    <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.8.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>SpringMVCRESTful</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

接下来,配置 web.xml:

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
   <display-name>欢迎来到Spring REST的世界</display-name>
  <description>这是一个Spring REST的学习示例</description>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!--注册ContextLoaderListener-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
<!--前端控制器,注册DispatherServlet-->
   <servlet>
  <servlet-name>servlet</servlet-name>
  <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationServlet.xml</param-value>
</init-param>
</servlet>
  <!--将DispatcherServlet映射到'/'-->
  <servlet-mapping>
    <servlet-name>servlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值