使用Jersey 1.14和Spring 3.1.2
我想创建一个这样的过滤器:https://gist.github.com/3031495
但是在那个过滤器中我想要访问我创建的提供程序。
我得到IllegalStateException
。我怀疑在我的生命周期中有些东西被淹没了。我可以访问@Context private HttpServletRequest
并从那里获取我需要的会话信息,但是两个类必须知道在哪里/如何获取我的“AuthUser”对象。
感谢任何帮助!
我的提供者:
@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;
}
}
我的过滤器:
@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;
}
};
}
}
我的服务(又名资源):
@Component
@Path("/rs/todo")
@Produces(MediaType.APPLICATION_JSON)
@ResourceFilters(TodoFilter.class)
public class TodoService {
@GET / @POST methods
}
答案 0 :(得分:1)
所以我想我想出来了......
我将此添加到我的ResourceFilter:
@Context
private HttpContext ctx;
@Autowired
private AuthUserProvider provider;
然后我可以在过滤方法中执行此操作:
public ContainerRequest filter(ContainerRequest request) {
AuthUser authUser = provider.getValue(ctx);
// use authuser in some way
}
这可能不是“正确”......但它正在运行,我没有代码重复
答案 1 :(得分:0)
public ComponentScope getScope() {
return ComponentScope.Singleton;
}
应该是
public ComponentScope getScope() {
return ComponentScope.PerRequest;
}