我过滤了REST服务的BasicAuth并将用户名存储在HttpServletRequest中
AuthFilter的相关代码
public class AuthFilter implements ContainerRequestFilter {
@Context
public transient HttpServletRequest servletRequest;
@Override
public ContainerRequest filter(ContainerRequest containerRequest) throws WebApplicationException {
// all the auth filter actions...
// Set data
servletRequest.setAttribute("auth_username", username);
return containerRequest;
}
}
然后我有一个资源父类(只有一些常规属性称为BaseResource)和扩展它的特定类
示例特定类
@Path("/Plant")
public class PlantResource extends BaseResource {
private List<Plant> plantlist = new LinkedList<Plant>();
@GET
@Path("/GetPlantById/plantid/{plantid}")
@Produces("application/json")
public String getPlantById(@PathParam("plantid") String plantid, @Context HttpServletRequest hsr) {
String username = (String)hsr.getAttribute("auth_username");
// do something
}
}
正如您所见,我通过“@Context HttpServletRequest hsr”处理HttpServletRequest到该函数(如:Get HttpServletRequest in Jax Rs / Appfuse application?中所述)。这很好,我可以正确访问数据!
我现在要做的是在父类的构造函数中访问此数据,因此我不必在指定资源的每个函数中执行此操作,而是在一个地方
我的尝试:
public class BaseResource {
@Context protected HttpServletRequest hsr; // Also tried private and public:
/* ... */
public BaseResource() {
String username = (String)hsr.getAttribute("auth_username"); // line 96
System.out.println("constructur of BaseResource" + username);
}
}
但最终会出现:
Aug 05, 2013 3:40:18 PM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
Schwerwiegend: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.NullPointerException
at de.unibonn.sdb.mobilehelper.resources.BaseResource.<init>(BaseResource.java:96)
看起来HttpServletRequest没有在那里设置。那么如何在我的父类的构造函数中访问它?
答案 0 :(得分:3)
在创建实例后注入BaseResource
的字段,因此您无法在构造函数本身中引用它们。在BaseResource
:
public class BaseResource {
@Context
protected HttpServletRequest hsr;
/* ... */
protected String getUsername() {
return (String)hsr.getAttribute("auth_username");
}
}
或创建如下的层次结构:
public class BaseResource {
protected HttpServletRequest hsr;
/* ... */
public BaseResource(HttpServletRequest hsr) {
this.hsr = hsr;
String username = (String)hsr.getAttribute("auth_username");
System.out.println("constructur of BaseResource" + username);
}
}
和
@Path("/Plant")
public class PlantResource extends BaseResource {
private List<Plant> plantlist = new LinkedList<Plant>();
public PlantResource(@Context HttpServletRequest hsr) {
super(hsr);
}
@GET
@Path("/GetPlantById/plantid/{plantid}")
@Produces("application/json")
public String getPlantById(@PathParam("plantid") String plantid) {
String username = (String)hsr.getAttribute("auth_username");
// do something
}
}
答案 1 :(得分:1)
你必须通过一个函数传递它。正如您所指出的,父级中没有像@Context这样的JAX-RS注释。他们也没有继承下来。此外,您无法在构建时执行此操作,因为在构造期间不保证@Context引用可用(取决于容器如何创建资源)。