Java 使用冒号时将类@Path注释连接到方法@Path注释

Java 使用冒号时将类@Path注释连接到方法@Path注释,java,path,annotations,jersey,jax-rs,Java,Path,Annotations,Jersey,Jax Rs,我在尝试将旧的ERX rest路由移植到Jerey/JAX-RX时遇到了一个问题 我正在尝试这样做: @Path("/v0/user") @Controller public class UserRouteController { @GET public Response getAllUsers(){ ... } @GET @Path("/{name}") public Response getUserWithName(@PathPar

我在尝试将旧的ERX rest路由移植到Jerey/JAX-RX时遇到了一个问题

我正在尝试这样做:

@Path("/v0/user")
@Controller
public class UserRouteController {

    @GET
    public Response getAllUsers(){
    ...
    }

    @GET
    @Path("/{name}")
    public Response getUserWithName(@PathParam("name") String name){
    ...
    }

    @GET
    @Path(":accessibleWithNoRestriction")
    public Response getUsersAccessibleWithNoRestriction(){
        ...
    }

    @GET
    @Path(":withAdminStatus")
    public Response getUsersWithAdminStatus(){
        ...
    }
@Path("v0")
@Controller
public class UserRouteController {
  @GET
  @Path("user")
  public Response getAllUsers(){
    //...
  }

  @GET
  @Path("user/{name}")
  public Response getUserWithName(@PathParam("name") String name){
    //...
  }

  @GET
  @Path("user:accessibleWithNoRestriction")
  public Response getUsersAccessibleWithNoRestriction(){
    //...
  }

  @GET
  @Path("user:withAdminStatus")
  public Response getUsersWithAdminStatus(){
    //...
  }
}
但是,Jersey不想匹配我的http请求

blahblah.com/v0/user:accessibleWithNoRestriction

我得到了一个不允许使用任何方法的响应。

我通常不在路径中包含前导/尾随的
/
,因此我非常确定
@Path(“rootLevel”)
@Path(“methodLevel”)
实际上映射到
rootLevel/methodLevel
而不是
rootLevelMethodLevel

因此,在您的示例中,
@Path(“/v0/user”)
@Path(“:withAdminStatus”)
映射到
/v0/user/:withAdminStatus
。尝试将路径更改为以下内容:

@Path("/v0/user")
@Controller
public class UserRouteController {

    @GET
    public Response getAllUsers(){
    ...
    }

    @GET
    @Path("/{name}")
    public Response getUserWithName(@PathParam("name") String name){
    ...
    }

    @GET
    @Path(":accessibleWithNoRestriction")
    public Response getUsersAccessibleWithNoRestriction(){
        ...
    }

    @GET
    @Path(":withAdminStatus")
    public Response getUsersWithAdminStatus(){
        ...
    }
@Path("v0")
@Controller
public class UserRouteController {
  @GET
  @Path("user")
  public Response getAllUsers(){
    //...
  }

  @GET
  @Path("user/{name}")
  public Response getUserWithName(@PathParam("name") String name){
    //...
  }

  @GET
  @Path("user:accessibleWithNoRestriction")
  public Response getUsersAccessibleWithNoRestriction(){
    //...
  }

  @GET
  @Path("user:withAdminStatus")
  public Response getUsersWithAdminStatus(){
    //...
  }
}

或者,您可以通过某种重定向来实现某些功能。例如,使用一个。我从未做过类似的事情,但文档表明“您甚至可以修改请求URI”。考虑到这一点,您可以将URI中的任何请求替换为
:withAdminStatus
,以便与正确的资源匹配。

我通常不在路径中包含前导/尾随的
/
,因此我非常确定
@Path(“rootLevel”)
@Path(“methodLevel”)
实际上映射到
rootLevel/methodLevel
而不是
rootLevelMethodLevel

因此,在您的示例中,
@Path(“/v0/user”)
@Path(“:withAdminStatus”)
映射到
/v0/user/:withAdminStatus
。尝试将路径更改为以下内容:

@Path("/v0/user")
@Controller
public class UserRouteController {

    @GET
    public Response getAllUsers(){
    ...
    }

    @GET
    @Path("/{name}")
    public Response getUserWithName(@PathParam("name") String name){
    ...
    }

    @GET
    @Path(":accessibleWithNoRestriction")
    public Response getUsersAccessibleWithNoRestriction(){
        ...
    }

    @GET
    @Path(":withAdminStatus")
    public Response getUsersWithAdminStatus(){
        ...
    }
@Path("v0")
@Controller
public class UserRouteController {
  @GET
  @Path("user")
  public Response getAllUsers(){
    //...
  }

  @GET
  @Path("user/{name}")
  public Response getUserWithName(@PathParam("name") String name){
    //...
  }

  @GET
  @Path("user:accessibleWithNoRestriction")
  public Response getUsersAccessibleWithNoRestriction(){
    //...
  }

  @GET
  @Path("user:withAdminStatus")
  public Response getUsersWithAdminStatus(){
    //...
  }
}
或者,您可以通过某种重定向来实现某些功能。例如,使用一个。我从未做过类似的事情,但文档表明“您甚至可以修改请求URI”。考虑到这一点,您可以将URI中的任何请求替换为
:withAdminStatus
,这样就可以将其与正确的资源匹配。

我发现了以下帖子:

尝试使用以下方法:

@WebFilter(urlPatterns = "/*")
public class PathingFilter implements Filter { 
    Pattern[] restPatterns = new Pattern[] {
        Pattern.compile("/v0/user:.*")
    };

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (request instanceof HttpServletRequest) {

            String path = ((HttpServletRequest) request).getPathInfo();

            for (Pattern pattern : restPatterns) {
                if (pattern.matcher(path).matches()) {
                    String[] segments = path.split(":");
                    String newPath = segments[0] + "/" + segments[1];
                    newPath = ((HttpServletRequest) request).getServletPath() + "/" + newPath;
                    request.getRequestDispatcher(newPath).forward(request, response);
                    return;
                }
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
}
然后,您必须将方法中的@Path注释更改为“/accessibleWithNoRestriction”

这将在匹配发生之前更改请求的uri

试试看

我看到了这篇文章:

尝试使用以下方法:

@WebFilter(urlPatterns = "/*")
public class PathingFilter implements Filter { 
    Pattern[] restPatterns = new Pattern[] {
        Pattern.compile("/v0/user:.*")
    };

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (request instanceof HttpServletRequest) {

            String path = ((HttpServletRequest) request).getPathInfo();

            for (Pattern pattern : restPatterns) {
                if (pattern.matcher(path).matches()) {
                    String[] segments = path.split(":");
                    String newPath = segments[0] + "/" + segments[1];
                    newPath = ((HttpServletRequest) request).getServletPath() + "/" + newPath;
                    request.getRequestDispatcher(newPath).forward(request, response);
                    return;
                }
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
}
然后,您必须将方法中的@Path注释更改为“/accessibleWithNoRestriction”

这将在匹配发生之前更改请求的uri


试着提供一些有用的东西,比如web.xml、spring-bean.xml、控制台上的实际输出。它不是
blahblah.com/v0/user:accessibleWithNoRestriction
?(注意缺少的
/v0
)嗨,我编辑了这篇文章来添加v0(在文章中输入错误)。当我在请求路径和方法路径中都放了“/”而不是冒号时,这一切都会起作用。我认为Jersey试图匹配用户:AccessibleWith,而不限制路径。不在类级别将其分解为用户,然后在方法级别:accessibleWithNoRestriction。如果我将方法级别的路径更改为/accessibleWithNoRestriction,并将请求更改为blahblah.com/v0/user/accessibleWithNoRestriction,那么它将匹配并工作。我希望这次我能更好地解释这一点。您可以提供一些有用的东西,比如web.xml、spring-bean.xml,以及您在控制台上获得的实际输出。这不是
blahblah.com/v0/user:accessibleWithNoRestriction
?(注意缺少的
/v0
)嗨,我编辑了这篇文章来添加v0(在文章中输入错误)。当我在请求路径和方法路径中都放了“/”而不是冒号时,这一切都会起作用。我认为Jersey试图匹配用户:AccessibleWith,而不限制路径。不在类级别将其分解为用户,然后在方法级别:accessibleWithNoRestriction。如果我将方法级别的路径更改为/accessibleWithNoRestriction,并将请求更改为blahblah.com/v0/user/accessibleWithNoRestriction,那么它将匹配并工作。我希望这次我解释得更好一点谢谢你的回答。你的解释是正确的,事情就是这样。但是,我们有多个具有“v0”路径的类(在路径中使用分号),即:v0/patient:withNoRequiredAccessetc@Rosa使用描述预匹配过滤器的链接更新了答案。否则,我就没有主意了!Thanx兄弟!预匹配过滤器看起来像一个非常干净的解决方案。我们目前使用的是Jersy的旧版本,1.17中不支持它。但是如果升级是唯一的解决方案,那么我想我们需要升级:)再次感谢!谢谢你的回答。你的解释是正确的,事情就是这样。但是,我们有多个具有“v0”路径的类(在路径中使用分号),即:v0/patient:withNoRequiredAccessetc@Rosa使用描述预匹配过滤器的链接更新了答案。否则,我就没有主意了!Thanx兄弟!预匹配过滤器看起来像一个非常干净的解决方案。我们目前使用的是Jersy的旧版本,1.17中不支持它。但是如果升级是唯一的解决方案,那么我想我们需要升级:)再次感谢!哇!太神了这正是我想要的:)谢谢@allegjdm93Wow!!!!!!太神了这正是我想要的:)谢谢@allegjdm93