whitfin
whitfin

Reputation: 4629

Optional path segment in Jersey JAX-RS

I've searched for hours on this and haven't quite got it right.

An API on a project I'm working on is not versioned (/controller/blah), so we want to introduce versioning. For example, we have a class with @Path("/controller") associated to it. Naturally to avoid API breakage, this now has to support either / or /v1/, so the following would be valid:

/controller/blah
/v1/controller/blah

I feel there must be an easy solution to this that I am missing?

Thanks in advance!

Upvotes: 1

Views: 935

Answers (2)

mukh007
mukh007

Reputation: 339

You can do this very easily with option regex to prefix your URI.

The below path will match both /foo & /v1/foo

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

Upvotes: 1

JavierFromMadrid
JavierFromMadrid

Reputation: 621

I would use a Filter to redirect those requests which matched certain pattern (on your case /v1/*).

Your Filter should look like:

@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

    }

}

And then on 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>

UPDATE

Really you just need to add new url-pattern for your servlet-mapping. So just need on web.xml:

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

Upvotes: 1

Related Questions