我正在尝试创建自定义“userContext”作为具有请求范围的SpringBean,但我无法这样做。基本上我有一个Jersey REST api,我想使用自定义过滤器进行身份验证和授权,我在其中自动装配我的“userContext”bean。这个过程如下:
当我第一次调用REST api(服务器重启后)时,它按预期工作,但任何其他调用都失败,因为AutorizationFilter获取了userBean的空实例。我希望对我的范围有一些根本性的误解。
顺便说一句:我想避免直接使用ThreadLocal,因为请求范围应该处理它
我想知道,为什么authorizationFilter没有看到userBean的填充版本以及第一次调用的原因。提前感谢您的帮助。
代码的某些部分:
@Secured({Role.ADMIN}) //custom annotation
@GET
@Path("{id}")
public Response getUserById(@PathParam("id") Long id) throws IOException, MainException {
@Secured //custom annotation
@Provider
@Priority(Priorities.AUTHENTICATION)
@Scope(value="request", proxyMode= ScopedProxyMode.TARGET_CLASS)
public class AuthenticationFilter implements ContainerRequestFilter
@Autowired
private User userContext;
@Secured //custom annotation
@Provider
@Priority(Priorities.AUTHORIZATION)
@Scope(value="request", proxyMode= ScopedProxyMode.TARGET_CLASS)
public class AuthorizationFilter implements ContainerRequestFilter {
@Autowired
private User userContext;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class User extends ModelBase implements Serializable {
答案 0 :(得分:0)
由于Providers不是请求作用域,我必须注入整个ApplicationContext,这样我就可以直接修改userContext bean的正确实例(这是请求作用域)。基本上我在两个过滤器中做了类似的事情:
@Autowired
private ApplicationContext applicationContext;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
User userBean=applicationContext.getBean(User.class);
....
userBean.setSomething("aaa");
然后我可以在我的REST资源中自动装配这样的bean,因为它们是由defaul确定的请求:
@Component
@Api(value="/users", description = "Endpoint for Users listing")
@Consumes({MediaType.APPLICATION_JSON, Constants.API_VERSIONS.V1_HEADER_XML, Constants.API_VERSIONS.V1_HEADER_JSON})
@Produces({MediaType.APPLICATION_JSON, Constants.API_VERSIONS.V1_HEADER_XML, Constants.API_VERSIONS.V1_HEADER_JSON})
@Path("/users")
public class UserResource {
private static final Logger logger = LoggerFactory.getLogger(UserResource.class);
@Autowired
private User authenticatedUser;
此解决方案应该是可行的,并且可以抵抗线程竞争条件等。