在我的申请中,我有城市(A)和邮政编码(B)之间的关系。
所以我有两个SelectOneMenu,其中第一个代表A,第二个代表所选A的B,它们通过ajax更新。
由于我多次使用这两个菜单,我为它们编写了一个自定义标签,通常可以正常工作,因为A和B值被分配给会话bean中的现有变量。
但是有一种情况我想将一个新的关系对象传递给我的bean,它不能使用标签组件。
我想作为参数传递给逻辑会话bean的add方法的新请求作用域AToB对象的属性A和B为空!
* 附加说明
环境:
Mojarra 2.14
GlassFish 3.01
我简化了删除构造函数和getter&的类。 setter方法。
DTO,Pojo:
public Class A{}
public Class B{}
public Class AToB
{
private A a;
private B b;
}
会话Bean:
public Class Bean
{
private List<A> as;
private List<B> bs;
private AConverter aConverter;
private BConverter bConverter;
//updates bs list
public void updateBsByA(AjaxBehaviorEvent event) {}
//does something with the given AToB
public void add(AToB aToB)
}
面-config.xml中:
<managed-bean>
<managed-bean-name>beanLogic</managed-bean-name>
<managed-bean-class>package.Bean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<description>new AToB Object I want to add at database</description>
<managed-bean-name>newAToB</managed-bean-name>
<managed-bean-class>package.Bean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
abSelect标记文件:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:abcd="http://store24.de/jsf/admin">
<h:selectOneMenu value="#{tagA}" converter="#{beanLogic.aConverter}">
<f:selectItems value="#{beanLogic.as}"/>
<p:ajax event="change" listener="#{beanLogic.updateBsByA}" update="selectB"/>
</h:selectOneMenu>
<h:selectOneMenu id="selectB" value="#{tagB}" converter="#{beanLogic.bConverter}">
<f:selectItems value="#{beanLogic.bs}"/>
</h:selectOneMenu>
</ui:composition>
abcd.taglib.xml
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://abcd.com/jsf</namespace>
<tag>
<tag-name>abSelect</tag-name>
<source>tags/abSelect.xhtml</source>
<attribute>
<display-name>a</display-name>
<name>tagA</name>
<required>true</required>
<type>package.A</type>
</attribute>
<attribute>
<display-name>a</display-name>
<name>tagB</name>
<required>true</required>
<type>package.B</type>
</attribute>
</tag>
</facelet-taglib>
致电网站:
<abcd:abSelect a="#{newAToB.a} b="#{newAToB.b}"/>
<p:commandButton value="add" action="#{beanLogic.add(newAToB)}"/>
相反,在没有标记组件的情况下添加新的AToB(参见上面的#2)
<h:selectOneMenu value="#{newAToB.a}" converter="#{beanLogic.aConverter}">
<f:selectItems value="#{beanLogic.as}"/>
<p:ajax event="change" listener="#{beanLogic.updateBsByA}" update="selectB"/>
</h:selectOneMenu>
<h:selectOneMenu id="selectB" value="#{newAToB.b}" converter="#{beanLogic.bConverter}">
<f:selectItems value="#{beanLogic.bs}"/>
</h:selectOneMenu>
<p:commandButton value="add" action="#{beanLogic.add(newAToB)}"/>
答案 0 :(得分:0)
你真的需要AToB课吗?不能private A
a;和private B b;
在会话范围内的bean?我发现重新创建代码的主要问题是,每次我想要使用它时,请求scooped AToB都会重新创建 - 只需将System.out.println()
添加到它的构造函数中即可查看它。我不知道为什么会这样。但我会使用JSF依赖注入来执行您可能想要的操作(将AToB注入会话bean)。
您可能缺少转换器(没有转换器) - 将p:commandButton
更改为h:commandButton
以查看我的意思。我不知道为什么Primefaces的按钮不会抛出任何错误,但我之前已经看过了。
如果您使用string在selectMany中显示A和B,并在处理之前解码并重新创建它会更容易。
这对我有用:
的web.xml
...
<!-- registering my custom tag -->
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/mytags.taglib.xml</param-value>
</context-param>
mytags.taglim.xml
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://mytags.com/jsf</namespace>
<tag>
<tag-name>abSelect</tag-name>
<source>tags/mytags/abselect.xhtml</source>
<attribute>
<display-name>a</display-name>
<name>tagA</name>
<required>true</required>
<type>mytagstest.A</type>
</attribute>
<attribute>
<display-name>a</display-name>
<name>tagB</name>
<required>true</required>
<type>mytagstest.B</type>
</attribute>
</tag>
</facelet-taglib>
面-confix.xml
...
<!-- Converters -->
<converter>
<converter-id>aConverter</converter-id>
<converter-class>mytagstest.AConverter</converter-class>
</converter>
<converter>
<converter-id>bConverter</converter-id>
<converter-class>mytagstest.BConverter</converter-class>
</converter>
abselect.xml
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
>
<h:selectOneMenu value="#{tagA}"> <!-- {aBBean.a} or {tagA} -->
<f:converter converterId="aConverter" />
<f:selectItems value="#{aBBean.as}"/>
<!--I dont know why you are tyring to update sth in aBBean, new value from menu is used to update tagA -->
<f:ajax event="change" listener="#{aBBean.updateBsByA}" execute="@form"/>
</h:selectOneMenu>
<h:selectOneMenu id="selectB" value="#{tagB}"> <!-- {aBBean.b} or {tagB} -->
<f:converter converterId="bConverter" />
<f:selectItems value="#{aBBean.bs}"/>
<f:ajax event="change" listener="#{aBBean.updateBsByA}" execute="@form"/>
</h:selectOneMenu>
答:#{aBBean.a} B:#{aBBean.b}
请注意,如果您真的不需要AToB,则可以跳过标记中的属性,并将用户选择保存在会话bean中。这可能会更清洁。
A.java(注意equals和hashCode方法)
package mytagstest;
import java.io.Serializable;
public class A implements Serializable{
private String name ="";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public A() {
}
A(String n) {
this.name = n;
}
@Override
public String toString() {
return "A{" + "name=" + name + '}';
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final A other = (A) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
hash = 19 * hash + (this.name != null ? this.name.hashCode() : 0);
return hash;
}
}
此类的转换器(如果用h:commandButton替换p:commandButton,您将看到创建转换器修复时出现一些错误)
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
public class AConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
// Convert the unique String representation of an object to the actual object.
return new A(value); //Dont need to create new
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
// Convert the Foo object to its unique String representation.
return ((A) value).getName();
}
}
B级和BConverter
看起来几乎相同。
AToB.java
@ManagedBean
@RequestScoped
public class AToB implements Serializable {
private A a;
private B b;
public AToB() {
System.out.println("Creating AToB");
}
public A getA() {
System.out.println("Get a");
return a;
}
public void setA(A a) {
System.out.println("set b");
this.a = a;
}
public B getB() {
System.out.println("get b");
return b;
}
public void setB(B b) {
System.out.println("set b");
this.b = b;
}
}
ABBEan(会话范围的bean,两种情况都有方法 - 使用AToB而不是)
@ManagedBean
@SessionScoped
public class ABBean implements Serializable {
private List<A> as = new ArrayList<A>();
private List<B> bs = new ArrayList<B>();
private A a;
private B b;
public A getA() {
System.out.println("Get a");
return a;
}
public void setA(A a) {
System.out.println("set b");
this.a = a;
}
public B getB() {
System.out.println("get b");
return b;
}
public void setB(B b) {
System.out.println("set b");
this.b = b;
}
public void updateAB() {
System.out.println("Selected A and B are:");
System.out.println(a + " " + b);
}
public ABBean() {
System.out.println("Creating ABBean");
A a1 = new A("a1");
B b1 = new B("b1");
this.a = a1;
this.b = b1;
as.add(a1);
as.add(new A("a2"));
bs.add(b1);
bs.add(new B("b2"));
}
//updates bs list
public void updateBsByA(AjaxBehaviorEvent event) {
System.out.println("updateBsByA");
System.out.println("Selected A and B are:");
System.out.println(a + " " + b);
}
public List<A> getAs() {
return as;
}
public void setAs(List<A> as) {
this.as = as;
}
public List<B> getBs() {
return bs;
}
public void setBs(List<B> bs) {
this.bs = bs;
}
//does something with the given AToB
public void add(AToB aToB) {
System.out.println("AToB added! - aToB");
System.out.println(aToB.getA() + " " + aToB.getB());
}
public void add(A a, B b) {
System.out.println("AToB added! - A a, B b");
System.out.println(a + " " + b);
}
}
用法:
<h:form>
<mt:abSelect tagA="#{aBBean.a}" tagB="#{aBBean.b}"/>
<p:commandButton value="add2works" action="#{aBBean.updateAB}"/> <!-- works -->
</h:form>
或
<h:form>
<mt:abSelect tagA="#{aToB.a}" tagB="#{aToB.b}"/>
<p:commandButton value="add7" action="#{aBBean.add(aToB)}"/>
</h:form>