我遇到过我写过的客户转换器的问题。我从转换器调用我的DAL并将其作为托管属性注入。当我从我的一个ui组件调用转换器时,一切正常;但是当我从另一个组件调用它时,注入的DAL为空。如果这是一个骗局我道歉,我已经到处寻找答案了。
我正在使用primefaces 3.5。
这是转换器:
@ManagedBean(name = "fanlistConverter")
public class FanlistConverter implements Converter, Serializable {
private List<Fanlist> fanlist;
@ManagedProperty(value="#{dAL}")
private DAL dAL;
private static Session session;
public FanlistConverter(){
}
@PostConstruct
public void init(){
session = dAL.getSession();
}
public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
if (!submittedValue.equals(null) && !submittedValue.equals("null")) {
Fanlist fanlist = new Fanlist();
try {
fanlist = (Fanlist)session.get(Fanlist.class, UUID.fromString(submittedValue));
} catch(NumberFormatException exception) {
System.out.println("error: " + exception.getMessage());
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid player"));
}catch(Exception e){
System.out.println("error get as Object: " + e.getMessage());
}
}
return fanlist;
}
public String getAsString(FacesContext facesContext, UIComponent component, Object value) {
if (value == null || value.equals("")) {
return "";
} else {
return String.valueOf(((Fanlist) value).getId());
}
}
public DAL getdAL() {
return dAL;
}
public void setdAL(DAL dAL) {
this.dAL = dAL;
}
}
以下是两个ui组件
这个有效:
<p:panelGrid columns="3">
<p:outputLabel for="fanlist" value="Subscription Opt-In List " />
<p:autoComplete id="fanlist" dropdown="true"
value="#{campaignWizard.selectedList}"
completeMethod="#{campaignWizard.complete}" var="f"
itemLabel="#{f.name}" itemValue="#{f}" converter="#{fanlistConverter}" />
<p:commandLink value="Add List"
actionListener="#{campaignWizard.addFanList}" update=":formbox2"
ajax="false" />
</p:panelGrid>
而且这个不起作用
<p:selectManyMenu id="fanlist2" value="#{blast.selectedLists}"
var="fl" showCheckbox="true" converter="#{fanlistConverter}"
style="width:250px;height:100px">
<f:selectItems value="#{blast.fanlists}" var="fanl"
itemLabel="#{fanl.name}" itemValue="#{fanl}" />
<p:column>
Name: #{fl.name}
</p:column>
<p:column>
Size: #{fl.name}
</p:column>
</p:selectManyMenu>
@ManagedBean(name = "blast")
@ViewScoped
public class BlastBean implements Serializable {
@ManagedProperty(value="#{globalVars}")
private GlobalVars globalVars;
@ManagedProperty(value="#{dAL}")
private DAL dAL;
@ManagedProperty(value="#{messaging}")
private Messaging messaging;
private User u;
private Blast blast;
private List<Fanlist> fanlists;
private List<Fanlist> selectedLists;
private List<Fanlisttoparent> fltops = new ArrayList<Fanlisttoparent>();
public BlastBean(){
}
@PostConstruct
public void init(){
fetchData();
}
public void fetchData(){
u = globalVars.getUser();
blast = new Blast();
fanlists = dAL.query("FROM Fanlist where client.id ='" + globalVars.getUser().getClient().getId() + "'");
}
...
public String sendBlast(){
System.out.println("blast:" + blast.getMessage());
dAL.upsert(blast);
final List<String> phoneNumbers = new ArrayList<String>();
List<Profile> profiles = new ArrayList<Profile>();
for(Fanlist fl: selectedLists){
Set<Fantolist> fantolist = fl.getFantolists();
for(Fantolist ftol: fantolist){
profiles.add(ftol.getFanprofile().getProfile());
}
for(Profile p: profiles){
phoneNumbers.add("+1"+ p.getPhonenumber());
}
}
...
答案 0 :(得分:1)
首先,我们需要了解何时会发生Validation Error: Value is not valid
。如果当前所选项目的equals()
测试未针对任何当前可用的项目返回true
,则会发生此错误。
因此,此错误在技术上有两个原因:
equals()
方法丢失或损坏。与初始请求相比,当前可用项目列表的更改不相同。
当涉及转换器时,则有第三个原因:
转换器已返回null
而不是getAsObject()
中的所需对象。
根据目前提供的信息,转换器可在一页中正常工作,但在其他页面中则无效。因此原因1可以安全地划伤。留下原因2和3.
对于原因2,您需要保证在处理表单提交期间<f:selectItems value="#{blast.fanlists}">
不会返回不同的值。如果#{blast}
bean是请求范围的,并且fanlists
属性是基于在表单提交期间丢失的某个请求范围变量初始化的,则可能发生这种情况。您可以通过将bean放在视图范围内来确定它(并确保您没有在getter中执行业务逻辑)。
至于原因3,调试器/记录器应该提供足够的线索,说明转换器是否正常工作。这个问题实际上超出了JSF的范围。开发人员有责任根据提交的值返回正确的对象实例。
无关。转换器上的@FacesConverter
注释是超级的。它没有在这个结构中使用。如果您已经使用过它,那么根本不会注入托管属性。另见其他How can I inject in @FacesConverter?