Jersey JAX-RS 中的可选路径段

Optional path segment in Jersey JAX-RS

我已经为此搜索了几个小时,但还是不太对劲。

我正在处理的项目中的一个 API 没有版本控制 (/controller/blah),因此我们想引入版本控制。例如,我们有一个 class 与 @Path("/controller") 相关联。当然,为了避免 API 损坏,现在必须支持 //v1/,因此以下内容有效:

/controller/blah
/v1/controller/blah

我觉得一定有一个我缺少的简单解决方案?

提前致谢!

我会使用过滤器来重定向那些匹配特定模式的请求(在你的情况下 /v1/*)。

您的过滤器应该如下所示:

@WebFilter(filterName = "MyCustomFilter")
public class MyCustomFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        try {
            String url = ((HttpServletRequest)arg0).getRequestURI();
            //Take into account thet the url here would be the complete url. I just put an example taking into account
            //your application name is JAX-RS_tutorial
            String redirect = url.substring("/JAX-RS_tutorial/v1".length(), url.length());
            arg0.getRequestDispatcher(redirect).forward(arg0, arg1);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new ServletException(e);
        }

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}

然后 web.xml:

<filter>
    <filter-name>MyCustomFilter</filter-name>
    <filter-class>com.myapplication.filter.MyCustomFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyCustomFilter</filter-name>
    <url-pattern>/v1/*</url-pattern>
</filter-mapping>
<servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/api/*</url-pattern>
    <url-pattern>/v1/api/*</url-pattern>
</servlet-mapping>

更新

真的,您只需要为您的 servlet-mapping 添加新的 url-pattern。所以只需要 web.xml:

<servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/api/*</url-pattern>
    <url-pattern>/v1/api/*</url-pattern>
</servlet-mapping>

您可以使用选项 regex 为您的 URI 添加前缀来轻松完成此操作。

以下路径将同时匹配 /foo/v1/foo

@Path("/{ver : (v1/)?}foo")