0
votes

I have a requirement where need to put version in request URI to hit the respective service. For ex: if path is like : localhost:8080/context-root/rest/v1/company

then this service can be hit with below URLs: localhost:8080/context-root/rest/v1/company localhost:8080/context-root/rest/company

To achieve this in rest service filter I am adding v1 in case second URL is hit. It is working fine when I was using jersey 1.8 with servlet com.sun.jersey.spi.spring.container.servlet.SpringServlet

But when I am using jersey 2.4 with servlet org.glassfish.jersey.servlet.ServletContainer it is not working, it is not able to hit the filter altogether since there is no path for /rest/company. v1 was getting added in filter.

I was thinking if partial URL(up to /rest) can be hit and in filter I will change the request url for correct path.

Working web.xml:

<servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>
            com.sun.jersey.spi.spring.container.servlet.SpringServlet
        </servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.abc.ws.rest</param-value>
        </init-param>        
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
        <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
        <param-value>com.abc.filters.RestServiceFilter</param-value>
    </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

Not working web.xml

<servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.abc.ws.rest</param-value>
        </init-param>        
        <init-param>
            <param-name>jersey.config.server.provider.classnames</param-name>
            <param-value>com.abc.filter.RestServiceFilter</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

Working one is hitting the filter class even /rest/company URL is hit, whereas not working one is not hitting filter for same url

REST endpoint class:

    @Path("/v1/company")
public class CompanyRestService {
}

Updated pom.xml

<dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.4.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.glassfish.hk2.external</groupId>
                    <artifactId>asm-all-repackaged</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.glassfish.hk2.external</groupId>
                    <artifactId>cglib</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.4.1</version>
        </dependency>

RestServiceFilter code:

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import org.apache.commons.lang.math.NumberUtils;

public class RestServiceFilter implements ContainerRequestFilter {

    private static Logger _logger = Logger.getLogger(RestServiceFilter.class.getName());

    @Override
    public void filter(ContainerRequestContext crc)  {

        _logger.info("***** REST FILTER*********************");
        crc = updateURLForVersion(crc);
    }

    private ContainerRequestContext updateURLForVersion(ContainerRequestContext cr) {
        String baseURI = cr.getUriInfo().getBaseUri().toString();
        String requestURI = cr.getUriInfo().getRequestUri().toString();
        String pathURI = requestURI.substring(baseURI.length(), requestURI.length());
        String version = null;
        if (pathURI.startsWith("v") && pathURI.contains("/")) {
            String versionInURL = pathURI.substring(1, pathURI.indexOf("/"));
            if (NumberUtils.isNumber(versionInURL)) {
                version = "v" + versionInURL;
            }
        }
        if (StringUtil.isNullOrEmpty(version)) {
            version = ConfigReader.getinstance().get(Constants.REST_LATEST_VERSION);
            pathURI = version + "/" + pathURI;
            requestURI = baseURI + pathURI;
            try {
                cr.getUriInfo().getRequestUriBuilder().replacePath(requestURI);
//            cr.setRequestUri(new URI(requestURI));
            } catch (Exception ex) {
                ex.printStackTrace();
                Logger.getLogger(RestServiceFilter.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return cr;
    }
1
Can we see the code ? - Slim Soltani Dridi
Please refer the original post for code - kapil gupta
If I remember, you don't need to use a web.xml with jersey 2, you have to create a class which inherit ResourceConfig - Slim Soltani Dridi
your param-name is wrong. please use that javax.ws.rs.Application instead of jersey.config.server.provider.packages - Slim Soltani Dridi

1 Answers

0
votes

I think that's your problem :

<servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.abc.ws.rest</param-value>
        </init-param>
        ...
    </servlet>

https://jersey.java.net/documentation/2.4/deployment.html