1

I have this web.xml, don't want a suffix for the url-pattern so I'm using a /* pattern:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
    <servlet>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

This is my RestVersion.java class that I want to manage the root requests:

import javax.ejb.EJB;
import javax.ws.rs.Path;

@Path("/")
public class RestVersion implements IRestVersion{
    @EJB
    private VersionBean versionBean;
    
    @Override
    public VersionInfo version() {
        return versionBean.getVersion();
    }
}

Where IRestVersion.java is the following:

import javax.ejb.Local;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Local
public interface IRestVersion {
    @GET
    @Path("/")
    @Produces(MediaType.APPLICATION_JSON)
    public VersionInfo version();
}

The problem is that any other path is intercepted by this RestVersion class, like this:

  • http://localhost:8080/ ---> it answers correctly with the RestVersion.version() json
  • http://localhost:8080/asd ---> it is intercepted always by RestVersion but I would like to manage this on another class which will have a @Path("/asd") on top (but in this moment I cannot with this configuration)

How can I intercept just the project root without compromising all the other paths?

madx
  • 6,723
  • 4
  • 55
  • 59
  • This may help - https://stackoverflow.com/questions/10874188/jax-rs-application-on-the-root-context-how-can-it-be-done – ramp Nov 16 '21 at 13:46

1 Answers1

2

Add @Path("/") at class level. And in the other classes you want to manage, add their specific @Path("/asd").

At the end is all a hierarchy, starting by @ApplocationPath, followed by @Path at class level and ending in @Path at method level.

With combinations of those you should be able to manage any case.

The @GET, if found in a method without @Path, will manage GET requests of the @Path of the class level annotation.

Update: Adding an example

So, avoiding interfaces for simplification (although I only use them if necessary), you should accomplish what you want with this 2 classes:

@Path("/")
public class RestVersion {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getVersion() {
        return "1.0.0";
    }
}

and

@Path("/asd")
public class ASDController {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getAsd() {
        return "ASD";
    }
}

And to activate JAX-RS you can do it via web.xml or simply by adding this other class:

@ApplicationPath("/")
public class JaxRSActivator extends Application {
}
gmanjon
  • 1,483
  • 1
  • 12
  • 16
  • The problem, is that using `@Path("/")` all the others (like `@Path("/asd")`) are shadowed by the `@Path("/")`, maybe I'm missing something... – madx Nov 17 '21 at 14:12
  • 1
    Hi. I updated the response to add an example. Just tested it in a Wildfly server and `/` responds `1.0.0` and `/asd` responds `ASD`. – gmanjon Nov 17 '21 at 15:01
  • 1
    It seems to work... No shadowing... I tried even with my `web.xml` and without your `JaxRSActivator` and it's ok too. Maybe I was confused. Thank you very much, I'll make some other tests and I'll approve this answer soon. – madx Nov 17 '21 at 15:48
  • 1
    Glad to hear that. You are most welcome :) – gmanjon Nov 17 '21 at 15:52