简体   繁体   中英

Get only URI from HttpServletRequest

I have an API - http://localhost:8080/api/version/<versionA> where versionA is a Path Parameter.

HttpServletRequest getRequestURI() returns -> /api/version/<versionA>

How do we ensure that only /api/version is returned back? Is there any way to generalize this for all endpoints and return only the first part of the URI excluding path params? For example -

/api/version/<param1> Should Return /api/version
/api/<param1> Should return /api
/api/version/<param1>/name/<param2> Should return /api/version

Path Parameter is not a Query Parameter; it is rather a part/segment of the URL Path. So, there is no (and there should not be) built-in Servlet API method, that will return your, "custom-sub-stringed" path.

Q: Why?
A: Because you may have more than one path parameters /a/b/<param1>/<param2>/c/<param3>


Is there any way to generalize this for all endpoints and return only the first part of the URI excluding path params?

In your case, one option would be to implement some utility method, which will find the the lastIndexOf "/" and then will return the substring to that last "/" .

It depends a bit on how you've constructed things but let's take an example.

http://localhost:8080/sample/rest/v1/classLevel/methodLevel/param1/param2/something/param3

and a service defined as:

@Path("/v1/classLevel")
public class NewService {

    @Path("/methodLevel/{param1}/{param2}/something/{param3}")
    public Response getSomeStuff(@PathParam("param1") String param1,
                                 @PathParam("param2") String param2,
                                 @PathParam("param3") String param3,
                                 @Context HttpServletRequest request) {
        return Response.ok().build();
    }
}

This webapp is deployed under the context root "sample" . That means that if I were to go to http://localhost:8080/sample/ I'd get the root element (perhaps index.html) for the webapp. In my Application I have:

@ApplicationPath("/rest")
public class RestApplicationConfig extends Application {
    // intentionally empty
}

So the parameters in the URL are:

  1. request.getServletPath() returns "/rest"
  2. request.getContextPath() returns "/sample"
  3. request.getPathInfo() returns "/v1/classLevel/methodLevel/param1/param2/something/param3"

So I believe that what you want is request.getContextPath() + request.getServletPath() . But it's a bit unclear which part you really need.

EDIT To find out what path is at the class level a little reflection is needed. Within a class that is being called (ie non-static methods of the NewService class above) you would be able to get that with:

public String getClassLevelPath() {
    if( this.getClass().isAnnotationPresent(Path.class)) {
        Path annotation = this.getClass().getAnnotation(Path.class);
        return annotation.value();
    }

    return null;
}

As my class is defined, this returns "/v1/classLevel". I would personally cache this in something like a static variable as it's not going to change during runtime unless you're doing something else to change it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM