除了将请求路由到带注释方法的方法之外,还使用标头

时间:2015-03-09 16:13:00

标签: java rest jax-rs

我想知道除了HTTP方法之外,JAX-RS是否可以使用标头来路由请求。事实上,我找不到这样做的方法。

我想到了x-header是标题的地方:

@Path("/contacts/")
public class MyResource {
    @POST
    @Header("x-header:content1")
    public void method1(MyContent1 content) {
        (...)
    }

    @POST
    @Header("x-header:content2")
    public void method2(MyContent2 content) {
        (...)
    }
}

这个问题遵循这个答案:How to Update a REST Resource Collection

非常感谢你的帮助! 亨利

2 个答案:

答案 0 :(得分:4)

如果您需要影响请求匹配/路由过程,则必须使用JAX-RS过滤器 - PreMatching过滤器是特定的(@PreMatching)[这将在JAX-RS 2.0以后工作]如果使用头信息资源方法,它没有意义,因为JAX-RS已经匹配方法

以下是过滤器实现的总体流程

  1. 使用ContainerRequestContext获取标题信息
  2. 根据标头值
  3. 应用您的商家标准
  4. 现在的诀窍是能够路由到所需的资源方法 - 你有一个选择是使用ContainerRequestContext的setRequestUri方法,并在不同的URI上设置不同的资源方法(使用@Path)
  5. 泽西岛文档可能会有所帮助 - https://jersey.java.net/documentation/latest/filters-and-interceptors.html#d0e9538

答案 1 :(得分:1)

只是扔另一个选项。您还可以使用Sub-resource locators,它可以控制所选资源(并且是JAX-RS规范的一部分)。例如

@Path("contacts")
public class ContactsResource {

    @Path("/")
    public AbstractHeaderResource doSomething(@HeaderParam("X-Header") String xHeader) {
        if ("RequiredValue".equals(xHeader)) {
            return new WithHeaderResource();
        }
        return new WithOutHeaderResource();
    }

    public static abstract class AbstractHeaderResource {
        @POST
        @Consumes(MediaType.APPLICATION_JSON)
        public abstract Response doSometing(Contact contact);
    }

    public static class WithHeaderResource extends AbstractHeaderResource {
        @Override
        public Response doSometing(Contact contact) {
            return Response.ok("*** With Header ***").build();
        }
    }

    public static class WithOutHeaderResource extends AbstractHeaderResource {
        @Override
        public Response doSometing(Contact contact) {
            return Response.ok("*** WithOut Header ***").build();
        }
    }
}

测试

C:\>curl -v -X POST  
         -d "{\"name\":\"Peeskillet\"}" 
         -H "X-Header:RequiredValue" 
         -H "Content-Type:application/json"
         http://localhost:8080/contacts 

*** With Header ****

C:\>curl -v -X POST  
         -d "{\"name\":\"Peeskillet\"}"  
         -H "Content-Type:application/json"
         http://localhost:8080/contacts 

*** WithOut Header ****

资源方法 不接受相同的参数类型。我这样做只是为了简洁起见。您可以让子资源类扩展一个空的抽象类或接口(仅用于键入),然后根据需要创建方法