Jersey containerRequestFilter用于不同的api版本

时间:2015-03-21 09:46:32

标签: java rest jersey

我正在创建一个API,因为我正在使用Jersey。我有一个在containerRequestFilter类中调用的身份验证机制。一切都很好,直到... 现在正在对API进行版本控制,并成功对所有资源进行版本控制,但在requestfilter的情况下我不确定它是如何工作的......我使用注释进行版本控制

示例,对于登录资源,网址将为/v1/signin/v2/signin 使用类似@Path("v1/login")之类的java注释来提及资源类名称..

我如何以这种方式对我的请求进行过滤

请帮助......我真的很新

谢谢

1 个答案:

答案 0 :(得分:0)

假设您正在使用Jersey 2.x,您可以使用Dynamic Binding,稍加反思来检查@Path注释中的值。像

这样的东西
import javax.ws.rs.Path;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;

@Provider
public class Version1Feature implements DynamicFeature {

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
        Path classAnnotation = resourceInfo.getResourceClass().getAnnotation(Path.class);
        if (classAnnotation != null) {
            String pathValue = classAnnotation.value();
            if (pathValue != null) {
                if (pathValue.contains("v1")) {
                    context.register(Version1Filter.class);
                }
            }
        }
    }  
}

这将检查每个资源类的@Path("v1/login")。每个包含"v1"的类注释,它将动态注册该类的Version1Filter。您还可以使用resourceInfo.getResourceMethod().getAnnotation(Path.class)检查方法级别。为您拥有的每种资源方法调用configure方法。

应为每个版本创建不同的功能。您也可以为所有版本使用相同的功能,例如

@Provider
public class VersioningFeature implements DynamicFeature {

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
        Path classAnnotation = resourceInfo.getResourceClass().getAnnotation(Path.class);
        if (classAnnotation != null) {
            String pathValue = classAnnotation.value();
            if (pathValue != null) {
                if (pathValue.contains("v1")) {
                    context.register(Version1Filter.class);
                } else if (pathValue.contains("v2")) {
                    context.register(Version2Filter.class);
                }
            }
        }
    }  
}

但对我来说,为每个版本实现不同的功能更有意义,因为在创建新版本时您不需要触摸功能实现。

对于Jersey 1.x来说,它并不那么优雅。您需要在过滤器中明确进行检查。像

这样的东西
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;

public class Version1Filter implements ContainerResponseFilter {

    @Override
    public ContainerResponse filter(ContainerRequest cr, ContainerResponse cr1) {
        String pathValue = cr.getPath();
        if (pathValue.contains("v1")) {
            cr1.getHttpHeaders().putSingle("X-Header", "Version 1.0");
        }
        return cr1;
    }
}

你可以对泽西2做同样的事情,但就个人而言,我觉得这个功能更优雅。