Dropwizard请求使用URI模式的过滤器

时间:2016-11-04 23:33:04

标签: java jersey dropwizard

我正在Dropwizard中构建一个RESTful应用程序。在连接到数据库时,我想设置一个UserNotFoundFilter来实现ContainerRequestFilter,以便传入的请求首先通过此过滤器。

我的想法是,我希望这个特定的过滤器只映射到某些URI模式。例如,我希望过滤器仅适用于/users/*而不是其他任何内容。有没有办法在不使用DynamicFeature的自定义注释和实现的情况下执行此操作?

@Provider
public class UserNotFoundFilter implements ContainerRequestFilter {
    @Context
    UriInfo uriInfo;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        MultivaluedMap pathParams = uriInfo.getPathParameters(); // Should contain (uid: 1) pair for /users/1
        boolean userExists = // check against the database using above pathparam pair to see if user exists
        if (!userExists) 
            throw new WebApplicationException("User does not exist", Status.NOT_FOUND);
        // let the request through as user exists
    }
}

我的UserResource类

public class UserResource {
    @GET
    @Path("/users/{uid}")
    @Produces(MediaType.APPLICATION_JSON)
    public User getUser(@PathParam("uid") String uid) {
        // Now I don't need to do the check here !
        // boolean userExists = check against database using uid path param
        // if (!userExists)
        //     throw new WebApplicationException("User does not exist", Status.NOT_FOUND);
        return database.getUser(uid);
    }
}

我的ItemResource类

public class ItemResource {
    @GET
    @Path("/items/{uid}")
    @Produces(MediaType.APPLICATION_JSON)
    public Item getItem(@PathParam("uid") String uid) {
        return database.getItem(uid);
    }
}

我正在尝试做什么

public class MyApplication extends Application<MyConfiguration> {
    // ...
    @Override
    public void run(MyConfiguration config, Environment environment) throws Exception {
        // ... do other things, register resources
        // this pseudocode, the UserNotFoundFilter only applies to URIs of the kind /users/*
        environment.jersey().register(new UserNotFoundFilter()).forUriPattern("/users/*");

我感谢任何示例代码段。

2 个答案:

答案 0 :(得分:1)

适用于Servlet过滤器 -

您正在寻找addMappingForUrlPatterns来自javax.servlet.FilterRegistration界面的run()可能会在 environment.servlets().addFilter("FilterName", UserNotFoundFilter.class) .addMappingForUrlPatterns(EnumSet .allOf(DispatcherType.class), true, "/users/*"); 中使用 -

public void addMappingForUrlPatterns(
        EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
        String... urlPatterns);

上述方法的签名是 -

DynamicFeature

编辑 - 动态绑定:

尝试使用@Provider public class UserNotFoundDynamicFilter implements DynamicFeature { @Override public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) { if (resourceInfo.getResourceMethod().getAnnotation(UserRequired.class) != null) { featureContext.register(UserNotFoundFilter.class); } } } 作为

UserRequired

您可以将import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface UserRequired { } 注释定义为 -

/users/*

并在您的资源中标记所有@GET @Path("/users/{uid}") @Produces(MediaType.APPLICATION_JSON) @UserRequired public User getUser(@PathParam("uid") String uid) { // Now I don't need to do the check here ! // boolean userExists = check against database using uid path param // if (!userExists) // throw new WebApplicationException("User does not exist", Status.NOT_FOUND); return database.getUser(uid); } api,其注释与 -

相同
unlink('/var/www/test/'.$fpath);

来源 - jersey-filters

答案 1 :(得分:1)

你会在((ContainerRequest) requestContext).getUriInfo()中获得一堆有用的东西,例如匹配/users/*

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {

    String uriTemplate = ((ContainerRequest) requestContext).getUriInfo().getMatchedTemplates().stream().map(o -> o.getTemplate()).reduce("", (acc, template) -> template + acc);
    if (uriTemplate == "/users/{id}") {
        // matched!
    }

    String path = ((ContainerRequest) requestContext).getUriInfo().getPath();
    if (path.startsWith("users/")) {
        // matched!
    }
}

以类似的方式获取实际用户id以进行数据库查找。