我有一些旧代码,使用以下代码将对象作为http session 属性:
MyObject object = new MyObject();
Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
sessionMap.put("attrname", object);
旧的facelets使用以下代码访问代码
@ManagedProperty("#{attrname}")
private MyObject object;
有什么方法可以使用CDI(
@Inject
)将该 session 属性注入(inject)Bean?在使用CDI的新代码中,更好的方法是创建和注入(inject)需要以受控方式创建的对象。
最佳答案
在具有getter上的 @Produces
@Named
的 session 范围内的受管bean中获取它。
@SessionScoped
public class MyObjectProducer implements Serializable {
private MyObject myObject;
@Produces
@Named("attrname")
public MyObject getMyObject() {
return myObject;
}
public void setMyObject(MyObject myObject) {
this.myObject = myObject;
}
}
当您通过某种方式进行设置时
myObjectProducer.setMyObject(myObject)
在其他地方(或CDI @Observes
事件),然后可以使用@Inject @Named
将其注入(inject)到任何地方。@Inject
@Named("attrname")
private MyObject myObject;
是的,它仍然可以通过EL中的
#{attrname}
正常使用。不,它不会在未设置时自动创建,它将保留为null
,直到您将其实际设置为生产者类的属性为止。另外,如果您确实打算保留通过
ExternalContext#getSessionMap()
设置实例的旧方法(例如,因为它是第三方,因此您不能更改它),那么您也可以让生产者直接从 session 映射中返回它:@SessionScoped
public class MyObjectProducer implements Serializable {
@Produces
@Named("attrname")
public MyObject getMyObject() {
return (MyObject) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("attrname");
}
}
但是,当注入(inject)非JSF工件(例如任意
@WebServlet
)时,不能保证此方法有效,因为FacesContext#getCurrentInstance()
显然会返回null
。