Java 仅从HttpServletRequest获取URI

Java 仅从HttpServletRequest获取URI,java,jax-rs,Java,Jax Rs,我有一个API-http://localhost:8080/api/version/其中versionA是路径参数 HttpServletRequestgetRequestURI()返回->/api/version/ 我们如何确保只返回/api/version?是否有任何方法可以将其推广到所有端点,并仅返回URI的第一部分(不包括路径参数)? 比如说- /api/version/<param1> Should Return /api/version /api/<param1&g

我有一个API-
http://localhost:8080/api/version/
其中versionA是路径参数

HttpServletRequest
getRequestURI()返回->/api/version/

我们如何确保只返回
/api/version
?是否有任何方法可以将其推广到所有端点,并仅返回URI的第一部分(不包括路径参数)? 比如说-

/api/version/<param1> Should Return /api/version
/api/<param1> Should return /api
/api/version/<param1>/name/<param2> Should return /api/version
/api/version/应返回/api/version
/api/应返回/api
/api/version//name/应返回/api/version
不是查询参数;它是URL路径的一部分/段。因此,没有(也不应该有)内置ServletAPI方法返回“自定义子字符串”路径

问:为什么 答:因为您可能有多个路径参数
/A/b///c///code>


是否有任何方法可以将其推广到所有端点,并仅返回URI的第一部分(不包括路径参数)

在您的情况下,一个选项是实现一些实用方法,它将查找
“/”
,然后将子字符串返回到最后一个
“/”
,不是查询参数;它是URL路径的一部分/段。因此,没有(也不应该有)内置ServletAPI方法返回“自定义子字符串”路径

问:为什么 答:因为您可能有多个路径参数
/A/b///c///code>


是否有任何方法可以将其推广到所有端点,并仅返回URI的第一部分(不包括路径参数)


在您的例子中,一个选项是实现一些实用方法,它将找到
“/”
,然后将子字符串返回到最后一个
“/”
,,这取决于您是如何构造的,但让我们举个例子

http://localhost:8080/sample/rest/v1/classLevel/methodLevel/param1/param2/something/param3
以及定义为以下内容的服务:

@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();
    }
}
此webapp部署在上下文根“sample”下。这意味着如果我去
http://localhost:8080/sample/
我将获得webapp的根元素(可能是index.html)。在我的申请中,我有:

@ApplicationPath("/rest")
public class RestApplicationConfig extends Application {
    // intentionally empty
}
因此,URL中的参数为:

  • request.getServletPath()
    返回“/rest”
  • request.getContextPath()
    返回“/sample”
  • request.getPathInfo()
    返回“/v1/classLevel/methodLevel/param1/param2/something/param3”
  • 所以我相信您想要的是
    request.getContextPath()+request.getServletPath()
    。但你真的需要哪一部分还不清楚

    编辑 要找出类级别的路径,需要进行一些反思。在被调用的类中(即上面的
    NewService
    类的非静态方法),您可以通过以下方式获得该类:

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

    正如我的类定义的那样,它返回“/v1/classLevel”。我个人会将其缓存在一个类似于静态变量的东西中,因为它在运行时不会改变,除非您正在做其他事情来改变它。

    这取决于您是如何构造的,但让我们举个例子

    http://localhost:8080/sample/rest/v1/classLevel/methodLevel/param1/param2/something/param3
    
    以及定义为以下内容的服务:

    @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();
        }
    }
    
    此webapp部署在上下文根“sample”下。这意味着如果我去
    http://localhost:8080/sample/
    我将获得webapp的根元素(可能是index.html)。在我的申请中,我有:

    @ApplicationPath("/rest")
    public class RestApplicationConfig extends Application {
        // intentionally empty
    }
    
    因此,URL中的参数为:

  • request.getServletPath()
    返回“/rest”
  • request.getContextPath()
    返回“/sample”
  • request.getPathInfo()
    返回“/v1/classLevel/methodLevel/param1/param2/something/param3”
  • 所以我相信您想要的是
    request.getContextPath()+request.getServletPath()
    。但你真的需要哪一部分还不清楚

    编辑 要找出类级别的路径,需要进行一些反思。在被调用的类中(即上面的
    NewService
    类的非静态方法),您可以通过以下方式获得该类:

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

    正如我的类定义的那样,它返回“/v1/classLevel”。我个人会将其缓存在一个类似于静态变量的东西中,因为它在运行时不会改变,除非您正在做其他事情来改变它。

    路径参数不一定在URL的末尾。您希望/api//things/返回什么?这个servlet的servlet上下文路径是什么?您是否检查了HttpServletRequest调用
    req.getPathInfo()
    返回的内容,因为它将在注册的servlet上下文路径之后提供所有路径参数?我将编辑这个问题。但如果我有多个参数。我只需要URI的第一部分。Ex-/api/version//abc/>应返回/api/versionPath参数不一定位于URL的末尾。您希望/api//things/返回什么?这个servlet的servlet上下文路径是什么?您是否检查了HttpServletRequest调用
    req.getPathInfo()
    返回的内容,因为它将在注册的servlet上下文路径之后提供所有路径参数?我将编辑这个问题。但如果我有多个参数。我只需要URI的第一部分。Ex-/api/version//abc/>应返回/api/versionI不需要最后一个参数之前的路径,而是第一个参数之前的路径我不需要最后一个参数之前的路径,而是第一个参数之前的路径谢谢您的回答!这更有道理!。基于上面提到的示例,有没有一种方法可以在类级别获取路径?Ex-/rest/sample/v1/classLevel?谢谢你的回答!这更有道理!。基于上面提到的示例,有没有一种方法可以在类级别获取路径?Ex-/rest/sample/v1/classLevel?