假设我有一个Web服务/一个使用某些HTTP标头参数调用的REST资源。resource方法构建一个复杂的数据对象(当前为POJO),并最终将其返回给客户端(通过Gson作为JSON,但这无关紧要)。
所以我有这个调用层次结构:
@Path(foo) ProjectResource @GET getProject()
-> new Project()
-> new List<Participant> which contains lots of new Participant()s
-> new Affiliation()
Run Code Online (Sandbox Code Playgroud)
如果我想Affiliation根据标题参数以英语或德语填充对象,则必须将其作为参数传递给链下。我想避免这样做。也许这从根本上讲是不可能的,但是感觉太不对了。所有这些对象仅存在于请求中,因此能够从任何地方访问与请求相关的信息是否方便?
我希望我可以例如定义一个CDI @RequestScoped对象,该对象会初始化自身(或由某些WebFilter填充),然后可以在可能需要的位置注入。
但是显然,这在POJO内部是行不通的,而且我也很难从请求范围的对象内部获取标头。
我已经阅读了许多关于EJB,JAX-RS上下文和CDI的SO问题/答案,但是我无法解决。
我期望太多了吗?传递参数确实是首选选项吗?
如果我了解您的需求,则可以尝试以下方法(只是从头开始编写此解决方案,但它应该可以工作):
定义一个带有注释的类,该类@RequestScoped将存储您需要的数据:
@RequestScoped
public class RequestMetadata {
private Locale language;
// Default constructor, getters and setters ommited
}
Run Code Online (Sandbox Code Playgroud)
确保您使用的@RequestScoped是javax.enterprise.context包装中的注释。
创建一个ContainerRequestFilter以填充RequestMetadata:
@RequestScoped
public class RequestMetadata {
private Locale language;
// Default constructor, getters and setters ommited
}
Run Code Online (Sandbox Code Playgroud)
然后,您最终可以执行RequestMetadatausing 的注入@Inject:
@Provider
@PreMatching
public class RequestMetadataFilter implements ContainerRequestFilter {
@Inject
private RequestMetadata requestMetadata;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
requestMetadata.setLanguage(requestContext.getLanguage());
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,任何地方都太广泛了:注入将对容器管理的bean起作用,例如servlet,JAX-RS类,EJB和CDI bean。
您将无法对自己创建的bean或JPA实体进行注入。
| 归档时间: |
|
| 查看次数: |
968 次 |
| 最近记录: |