有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JAXRS/Jersey资源路径会尊重继承吗?

假设我希望我的JAX-RS/Jersey应用程序公开以下URL:

http://myapp.example.com/app/fizz
http://myapp.example.com/app/buzz
http://myapp.example.com/app/foo
http://myapp.example.com/app/bar

假设我希望/app成为父基资源,/app/*成为“子”资源。以下内容能否实现我正在寻找的URL策略(?):

@Path('/app')
@Produces(MediaType.APPLICATION_JSON)
public abstract class AppResource {
    // Whatever...
}

@Path('/fizz') // <--- right here, will FizzResource live at /app/fizz?
@Produces(MediaType.APPLICATION_JSON)
public class FizzResource extends AppResource {
    // Whatever...
}

这个FizzResource会暴露在/app/fizz还是仅仅暴露在/fizz


共 (3) 个答案

  1. # 1 楼答案

    Will the FizzResource be exposed at /app/fizz or just /fizz?

    简短回答

    FizzResource将在/fizz曝光

    长话短说

    引用JSR 339(关于注释继承3.6节):

    If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the superclass or interface method are ignored.

    specification还说:

    For consistency with other Java EE specifications, it is recommended to always repeat annotations instead of relying on annotation inheritance.

    创建子资源

    {a3}解释了如何创建子资源:

    @Path may be used on classes and such classes are referred to as root resource classes.

    @Path may also be used on methods of root resource classes. This enables common functionality for a number of resources to be grouped together and potentially reused.

    The first way @Path may be used is on resource methods and such methods are referred to as sub-resource methods.

    因此,请执行以下操作来创建子资源:

    @Path("/app")
    public class YourHandler {
    
        @Produces(MediaType.APPLICATION_JSON)
        public String yourHandlerForApp() {
            // This method is be exposed at /app
        }
    
        @Path("/fizz") 
        @Produces(MediaType.APPLICATION_JSON)
        public String yourHandlerForAppSlashFizz() {
            // This method is be exposed at /app/fizz
        }
    }
    
  2. # 2 楼答案

    我不认为给出的答案对最初的问题陈述是最好的

    他想把他的子资源分在不同的班级。这是可以理解和令人钦佩的,因为不这样做意味着将他的所有端点放在同一个类中,这将是巨大的

    如果这个端口上的所有端点都以/app开头,那么我认为最好的方法是配置过滤器,将其放入@ApplicationPath

    如果不是所有端点都以相同的前缀开头,那么您将不得不使用这种风格的JAX-RS子资源,在其中指定@Path而不是HTTP方法注释(@GET,等等),并返回要委托给的资源的实例:

    @Path("/app")
    public class AppResource {
        @Context UriInfo uriInfo;
    
        @Path("fizz")
        public FizzResource getItemContentResource() {
            return new FizzResource ();
        }
    }
    
    @Produces(MediaType.APPLICATION_JSON)
    public class FizzResource extends AppResource {
        // Whatever...
    }
    

    这种处理资源的方法在JAX-RS documentation中提供

    还可以让所有子资源将其路径声明为

        @Path(BASE_URL + "/fizz")
    

    其中BASE_URL是一个静态字符串,但我会尽量避免,因为对@Path使用一个不完全恒定的参数似乎会导致我见过的每个JAX-RS IDE插件出现问题。他们无法计算实际路径,所以放弃了。因此,您可能会失去“JAX-RS视图”的能力,该视图允许您通过路径可视化/导航JAX-RS资源

  3. # 3 楼答案

    你想要的是

    @Path("/app")
    public class YourHandler {
       @Path('/')
       @Produces(MediaType.APPLICATION_JSON)
       public String yourHandlerForApp() {
          // Whatever...
       }
    
       @Path('/fizz') // < - right here, will FizzResource live at /app/fizz?
       @Produces(MediaType.APPLICATION_JSON)
       public String yourHandlerForAppSlashFizz() {
           // Whatever...
       }
    }