我正在使用PrimeFaces,JPA,Hibernate和JSF 2.0开发Web应用程序。
我的JSF p:selectOneMenu
有一个转换器。我的问题是,当我运行我的应用程序时,服务descriptifService
未自动装配,它返回NULL
!
转换器:
@Component
@FacesConverter(value = "descriptifConverter")
public class DescriptifConverter implements Converter {
@Autowired
@RmiClient
private IDescriptifService descriptifService;
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
if (arg2 == null || arg2.isEmpty()) {
return null;
}
String descriptif = arg2;
Long value = Long.valueOf(descriptif);
DescriptifDto result = new DescriptifDto();
result = descriptifService.findById(value);
return result;
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
if(arg2 == null || ((DescriptifDto) arg2).getIdDescriptif() == null) return null;
DescriptifDto descriptif = new DescriptifDto();
if(arg2 instanceof DescriptifDto) {
descriptif = (DescriptifDto) arg2;
String idDescriptif = descriptif.getIdDescriptif().toString();
return (idDescriptif != null) ? String.valueOf(idDescriptif) : null;
} else throw new ConverterException("Something wrong!" + arg2.hashCode() + arg2.toString());
}
}
JSF代码:
<p:selectOneMenu value="#{lotController.selectedDescriptif}"
effect="fade">
<f:selectItems value="#{lotController.listDescriptifs}" var="descriptif"
itemLabel="#{descriptif.libelle}" itemValue="#{descriptif}" />
<f:converter binding="#{descriptifConverter}" />
</p:selectOneMenu>
答案 0 :(得分:2)
这里有两个选项:
1 - 注册上下文提供者bean:
AppContext类:
import org.springframework.context.ApplicationContext;
public class AppContext {
private static ApplicationContext ctx;
public static void setApplicationContext(
ApplicationContext applicationContext) {
ctx = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return ctx;
}
}
ApplicationContextProvider类:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ApplicationContextProvider implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
AppContext.setApplicationContext(applicationContext);
}
}
注册bean:
<bean id="contextApplicationContextProvider" class="com.example.ApplicationContextProvider" />
现在,通过上下文,您可以获得对服务bean的任何引用:
IDescriptifService descriptifService = AppContext.getApplicationContext()。getBean( IDescriptifService.class);
2 - 将转换后的值存储在ViewMap中(受this帖子启发)
我喜欢这个解决方案,因为它不需要数据库访问,这可以提高应用程序的性能。
AbstractConverter类
import java.util.HashMap;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
public abstract class AbstractConverter implements Converter {
private static final String KEY = "com.example.converters.AbstractConverter";
protected Map<String, Object> getViewMap(FacesContext context) {
Map<String, Object> viewMap = context.getViewRoot().getViewMap();
@SuppressWarnings({ "unchecked", "rawtypes" })
Map<String, Object> idMap = (Map) viewMap.get(KEY);
if (idMap == null) {
idMap = new HashMap<String, Object>();
viewMap.put(KEY, idMap);
}
return idMap;
}
@Override
public final Object getAsObject(FacesContext context, UIComponent c,
String value) {
if (value == null || value.isEmpty()) {
return null;
}
return getViewMap(context).get(value);
}
@Override
public final String getAsString(FacesContext context, UIComponent c,
Object value) {
if (value != null) {
String id = getConversionId(value);
if (id == null || id.isEmpty()) {
throw new IllegalArgumentException(
"Objeto não pode ser convertido.");
}
getViewMap(context).put(id, value);
return id;
}
return null;
}
//Every concrete class must provide an unique conversionId String
//to every instance of the converted object
public abstract String getConversionId(Object value);
}
这里我们在ViewMap中创建一个存储位置。我们现在可以用它来存储我们需要的任何转换器对象。
以下是具体转换器的示例:
EntityConverter类
import javax.faces.convert.FacesConverter;
import com.example.AbstractEntity;
@FacesConverter("entity")
public class EntityConverter extends AbstractConverter {
@Override
public String getConversionId(Object value) {
if (value instanceof AbstractEntity) {
AbstractEntity entity = (AbstractEntity) value;
StringBuilder sb = new StringBuilder();
sb.append(entity.getClass().getSimpleName());
sb.append("@");
sb.append(entity.getId());
return sb.toString();
}
return null;
}
}
答案 1 :(得分:0)
迟到的响应,但我遇到了无法将Spring bean自动装入JSF转换器的问题,所以我删除了@FacesConverter注释,并将转换器组件声明为会话范围,然后,就像你所做的那样,使用f:带有绑定属性的转换器标签解决了这个问题。在你的情况下:
@Component
@Scope(WebApplicationContext.SCOPE_SESSION)
public class DescriptifConverter implements Converter {
...
}
应该有用......