我已经实现了一个解决方案,可以完美地处理其余版本的问题。
一般说来,有3种主要的REST版本控制方法:
基于路径的方法,其中客户端在URL中定义版本:
http://localhost:9001/api/v1/user
http://localhost:9001/api/v2/user
 
Content-Type标头,其中客户端在Accept标头中定义版本:
http://localhost:9001/api/v1/user with 
Accept: application/vnd.app-1.0+json OR application/vnd.app-2.0+json
 
自定义标头,其中客户端在自定义标头中定义版本。
 
该问题与第一个方法是,如果你改变的版本,让我们从V1说- > V2,也许你需要复制,粘贴并没有改变,以V2路径V1资源
该问题与第二个做法是,一些工具,如http://swagger.io/可以用相同的路径,但不同的内容类型(支票发放操作之间没有明显的https://github.com/OAI/OpenAPI-Specification/issues/ 146)
解决方案
由于我经常使用其余的文档工具,因此我更喜欢使用第一种方法。我的解决方案使用第一种方法处理了该问题,因此您无需将端点复制粘贴到新版本。
假设我们有User控制器的v1和v2版本:
package com.mspapant.example.restVersion.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
 * The user controller.
 *
 * @author : Manos Papantonakos on 19/8/2016.
 */
@Controller
@Api(value = "user", description = "Operations about users")
public class UserController {
    /**
     * Return the user.
     *
     * @return the user
     */
    @ResponseBody
    @RequestMapping(method = RequestMethod.GET, value = "/api/v1/user")
    @ApiOperation(value = "Returns user", notes = "Returns the user", tags = {"GET", "User"})
    public String getUserV1() {
         return "User V1";
    }
    /**
     * Return the user.
     *
     * @return the user
     */
    @ResponseBody
    @RequestMapping(method = RequestMethod.GET, value = "/api/v2/user")
    @ApiOperation(value = "Returns user", notes = "Returns the user", tags = {"GET", "User"})
    public String getUserV2() {
         return "User V2";
    }
 }
的要求是,如果我请求V1为用户资源我必须采取“用户V1” repsonse,否则如果我请求V2,V3等我必须采取“用户V2”响应。

为了在春季实现此功能,我们需要覆盖默认的RequestMappingHandlerMapping行为:
package com.mspapant.example.restVersion.conf.mapping;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class VersionRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    @Value("${server.apiContext}")
    private String apiContext;
    @Value("${server.versionContext}")
    private String versionContext;
    @Override
    protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
        HandlerMethod method = super.lookupHandlerMethod(lookupPath, request);
        if (method == null && lookupPath.contains(getApiAndVersionContext())) {
            String afterAPIURL = lookupPath.substring(lookupPath.indexOf(getApiAndVersionContext()) + getApiAndVersionContext().length());
            String version = afterAPIURL.substring(0, afterAPIURL.indexOf("/"));
            String path = afterAPIURL.substring(version.length() + 1);
            int previousVersion = getPreviousVersion(version);
            if (previousVersion != 0) {
                lookupPath = getApiAndVersionContext() + previousVersion + "/" + path;
                final String lookupFinal = lookupPath;
                return lookupHandlerMethod(lookupPath, new HttpServletRequestWrapper(request) {
                    @Override
                    public String getRequestURI() {
                        return lookupFinal;
                    }
                    @Override
                    public String getServletPath() {
                        return lookupFinal;
                    }});
            }
        }
        return method;
    }
    private String getApiAndVersionContext() {
        return "/" + apiContext + "/" + versionContext;
    }
    private int getPreviousVersion(final String version) {
        return new Integer(version) - 1 ;
    }
}
该实现读取URL中的版本并从spring请求解析该URL。如果此URL不存在(例如客户端请求v3),则尝试使用v2,直到找到该资源的最新版本。
为了看到此实现的好处,我们有两个资源:User和Company:
http://localhost:9001/api/v{version}/user
http://localhost:9001/api/v{version}/company
假设我们对公司的“合同”进行了更改,这改变了客户的利益。因此我们实现了,http://localhost:9001/api/v2/company并要求客户端将其更改为v2,而不是v1。
因此,来自客户端的新请求是: 
http://localhost:9001/api/v2/user
http://localhost:9001/api/v2/company
代替:
http://localhost:9001/api/v1/user
http://localhost:9001/api/v1/company
这里最好的部分是,使用此解决方案,客户端将从v1获取用户信息,从v2 获取公司信息,而无需从用户v2创建新的(相同)端点!
其余文档 
正如我在选择基于URL的版本控制方法之前所说的那样,某些工具(如swagger)不会以相同的URL记录不同的端点,但是内容类型却不同。使用此解决方案,由于具有不同的URL,因此将显示两个端点:

GIT
解决方案的实现位于:https :
 //github.com/mspapant/restVersioningExample/