Jim*_*ugh 8 java jsf serialization dependency-injection httpsession
我不确定我做的是不是错了,或者我错过了某个地方的注释或配置项.情况如下:
我有一个JSF应用程序与一个名为session的作用域bean SessionData
.这个bean ApplicationData
在创建时注入了一个应用程序范围的bean引用(类型).首次创建会话时,这可以正常工作.依赖注入是使用文件中的<managed-bean>
元素完成的,faces-config.xml
如下所示:
<managed-bean>
<managed-bean-name>sessionData</managed-bean-name>
<managed-bean-class>my.package.SessionData</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>applicationData</property-name>
<property-class>my.package.ApplicationData</property-class>
<value>#{applicationData}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>applicationData</managed-bean-name>
<managed-bean-class>my.package.ApplicationData</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
Run Code Online (Sandbox Code Playgroud)
因为在序列化时我的SessionData
对象包含ApplicationData
对象没有意义,所以我在对象中将ApplicationData
引用标记为瞬态SessionData
:
transient private ApplicationData applicationData;
Run Code Online (Sandbox Code Playgroud)
一切都很好,直到Web应用程序停止(在我的Tomcat 6.x容器中)并且会话被序列化.当我重新启动应用程序并反序列化会话时,我的引用ApplicationData
不会被JSF重新注入.我知道反序列化应该留下没有值的瞬态字段.有没有办法告诉JSF这个会话范围的对象要求在反序列化后再次设置其依赖项?
我使用MyFaces JSF 1.2和Tomcat 6.0.26作为我的Web应用程序容器.
虽然Bozho提供的解决方案可以工作,但我不想将代理对象引入到当前没有使用它们的应用程序中.我的解决方案不太理想,但它完成了工作.
我把瞬态场留在了原地:
transient private ApplicationData _applicationData;
Run Code Online (Sandbox Code Playgroud)
我还将setter留在原位,因此JSF可以SessionData
在第一次创建对象时初始设置引用:
public void setApplicationData(ApplicationData applicationData) {
_applicationData = applicationData;
}
Run Code Online (Sandbox Code Playgroud)
我做的改变是在getter方法中.SessionData
对象中的方法现在需要停止直接访问_applicationData
字段,而是通过getter获取引用.getter将首先检查null引用.如果为null,则通过获取托管bean FacesContext
.这里的约束是,FacesContext
仅在请求的生命周期内可用.
/**
* Get a reference to the ApplicationData object
* @return ApplicationData
* @throws IllegalStateException May be thrown if this method is called
* outside of a request and the ApplicationData object needs to be
* obtained via the FacesContext
*/
private ApplicationData getApplicationData() {
if (_applicationData == null) {
_applicationData = JSFUtilities.getManagedBean(
"applicationData", // name of managed bean
ApplicationData.class);
if (_applicationData == null) {
throw new IllegalStateException(
"Cannot get reference to ApplicationData object");
}
}
return _applicationData;
}
Run Code Online (Sandbox Code Playgroud)
如果有人关心,这是我的getManagedBean()
方法的代码:
/**
* <p>Retrieve a JSF managed bean instance by name. If the bean has
* never been accessed before then it will likely be instantiated by
* the JSF framework during the execution of this method.</p>
*
* @param managedBeanKey String containing the name of the managed bean
* @param clazz Class object that corresponds to the managed bean type
* @return T
* @throws IllegalArgumentException Thrown when the supplied key does
* not resolve to any managed bean or when a managed bean is found but
* the object is not of type T
*/
public static <T> T getManagedBean(String managedBeanKey, Class<T> clazz)
throws IllegalArgumentException {
Validate.notNull(managedBeanKey);
Validate.isTrue(!managedBeanKey.isEmpty());
Validate.notNull(clazz);
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext == null) {
return null;
}
Validate.notNull(facesContext.getApplication());
ELResolver resolver = facesContext.getApplication().getELResolver();
Validate.notNull(resolver);
ELContext elContext = facesContext.getELContext();
Validate.notNull(elContext);
Object managedBean = resolver.getValue(
elContext, null, managedBeanKey);
if (!elContext.isPropertyResolved()) {
throw new IllegalArgumentException(
"No managed bean found for key: " + managedBeanKey);
}
if (managedBean == null) {
return null;
} else {
if (clazz.isInstance(managedBean)) {
return clazz.cast(managedBean);
} else {
throw new IllegalArgumentException(
"Managed bean is not of type [" + clazz.getName() +
"] | Actual type is: [" + managedBean.getClass().getName()+
"]");
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且不要选择我的验证电话.在完成开发之后我会把它们拿出来!:)
归档时间: |
|
查看次数: |
7552 次 |
最近记录: |