简体   繁体   English

泽西岛:在资源过滤器中使用提供程序

[英]Jersey: Use Provider in Resource Filter

Using Jersey 1.14 and Spring 3.1.2 使用Jersey 1.14和Spring 3.1.2

I want to create a filter like this: https://gist.github.com/3031495 我想创建一个像这样的过滤器: https : //gist.github.com/3031495

but in that filter I want access to a provider I created. 但是在该过滤器中,我想访问我创建的提供程序。

I'm getting an IllegalStateException . 我收到一个IllegalStateException I suspect something in my lifecycle is hosed up. 我怀疑我生命周期中的某些事情正在恶化。 I can access @Context private HttpServletRequest and pull the session info I need from there, but then two classes have to know about where/how to get my "AuthUser" object. 我可以访问@Context private HttpServletRequest并从那里获取@Context private HttpServletRequest的会话信息,但是然后两个类必须知道从何处/如何获取我的“ AuthUser”对象。

Any help is appreciated! 任何帮助表示赞赏!

My Provider: 我的提供者:

@Component
@Provider
public class AuthUserProvider extends AbstractHttpContextInjectable<AuthUser> implements
        InjectableProvider<Context, Type> {

    private static final Logger LOG = LoggerFactory.getLogger(AuthUserProvider.class);

    @Context
    HttpServletRequest req;

    public void init() {
        LOG.debug("created");
    }

    @Override
    // this may return a null AuthUser, which is what we want....remember, a
    // null AuthUser means the user hasn't authenticated yet
    public AuthUser getValue(HttpContext ctx) {
        return (AuthUser) req.getSession().getAttribute(AuthUser.KEY);
    }

    // InjectableProvider implementation:

    public ComponentScope getScope() {
        return ComponentScope.Singleton;
    }

    public Injectable<AuthUser> getInjectable(ComponentContext ic, Context ctx, Type c) {
        if (AuthUser.class.equals(c)) {
            return this;
        }
        return null;
    }
}

My Filter: 我的筛选器:

@Component
public class TodoFilter implements ResourceFilter {

    private static final Logger LOG = LoggerFactory.getLogger(TodoFilter.class);

    @Autowired
    private JdbcTemplate todoTemplate;

    // this works
    @Context
    private HttpServletRequest servletRequest;

    // this throws a java.lang.IllegalStateException
    // @Context
    // private AuthUser authUser;

    public void init() throws Exception {
        LOG.debug("created");
        LOG.debug(todoTemplate.getDataSource().getConnection().getMetaData()
                .getDatabaseProductName());
    }

    @Override
    public ContainerRequestFilter getRequestFilter() {
        return new ContainerRequestFilter() {
            @Override
            public ContainerRequest filter(ContainerRequest request) {
                LOG.debug("checking if {} is authorized to use {}", "my authenticated user",
                        request.getPath());
                // String name = request.getUserPrincipal().getName();
                // String[] admins = settings.getAdminUsers();
                // for (String adminName : admins) {
                // if (adminName.equals(name))
                // return request;
                // }
                // if (authUser.getUsername().equals("jberk")) {
                // return request;
                // }
                // return HTTP 403 if name is not found in admin users
                throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN)
                        .entity("You are not authorized!").build());
            }
        };
    }

    @Override
    public ContainerResponseFilter getResponseFilter() {
        return new ContainerResponseFilter() {
            @Override
            public ContainerResponse filter(ContainerRequest request,
                    ContainerResponse response) {
                // do nothing
                return response;
            }
        };
    }

}

My Service (aka Resource): 我的服务(又称资源):

@Component
@Path("/rs/todo")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(TodoFilter.class)
public class TodoService {
    @GET / @POST methods
}

so I think I figured this out.... 所以我想我明白了...

I added this to my ResourceFilter: 我将此添加到我的ResourceFilter中:

@Context
private HttpContext ctx;
@Autowired
private AuthUserProvider provider;

then I can do this in the filter method: 那么我可以在filter方法中做到这一点:

public ContainerRequest filter(ContainerRequest request) {
       AuthUser authUser = provider.getValue(ctx);
       // use authuser in some way
}

this might not be "correct"...but it's working and I don't have code duplication 这可能不是“正确的” ...但是它可以正常工作,而且我没有代码重复

public ComponentScope getScope() {
    return ComponentScope.Singleton;
}

It should be 它应该是

public ComponentScope getScope() {
    return ComponentScope.PerRequest;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM