我刚刚开始使用JSF,我不明白为什么我的服务没有注入我的控制器。
@ManagedBean
@ApplicationScoped
public class MyController {
@ManagedProperty(value = "#{service}")
private MyService service;
public void setService(MyService service) {
this.service = service;
}
public MyService getService() {
return service;
}
public void callToService(AjaxBehaviorEvent event) {
System.out.println(service);
}
}
问:@ManagedProperty
中值的目的是什么?
@ManagedBean
@ApplicationScoped
public class MyService {
}
点击该按钮会调用方法callToService
,但该服务为null
。
<h:form>
<h:commandButton value="Call Service">
<f:ajax listener="#{myController.callToService}"/>
</h:commandButton>
</h:form>
答案 0 :(得分:4)
当#{service}
实际解析为null
时会发生这种情况。
当您使用@ManagedBean
而不使用name
属性时,托管bean名称将默认解析为classname,其中1st char是小写的(至少符合Javabeans规范),所以MyService
bean将有效地获得托管bean名称myService
。
所以基本上有2种方法可以解决这个问题,
请改用#{myService}
。
@ManagedProperty("#{myService}")
private MyService service;
自己指定托管bean名称,使其可用#{service}
。
@ManagedBean(name="service")
@ApplicationScoped
public class MyService {
}
无关具体问题,因为您似乎对ajax事件不感兴趣,而是在动作事件中,那么您还可以简化<f:ajax>
的使用如下:
<h:commandButton value="Call Service" action="#{myController.callToService}">
<f:ajax />
</h:commandButton>
与
public void callToService() {
System.out.println(service);
}
这样当最终用户没有启用JS时它仍然可以工作。
最后,业务服务通常被设计为@Stateless
EJB,而不是JSF托管bean,因为它与JSF视图没有直接关系。然后你可以使用
@EJB
private MyService service;