0

我正在尝试使用ManagedProperty注释来依赖注入到另一个 ManagedBean,但我总是得到一个NullPointerException. 我将尝试描述我的应用程序是如何工作的。

这是一个 PDF 生成器。首先,我的xhtml页面有一个选项卡式窗格。在每个选项卡中,我使用<ui:include>标签。所有这些 bean 都有ViewScope

在第一个选项卡中,我有标题inputText和描述textArea字段,这很奇怪,因为这些字段运行良好,即使我不使用 DI。

当我转到另一个选项卡时,我的问题就开始了,我想添加一些额外的信息/文本。

我的应用程序是这样工作的:我在 inputText 字段 ( 1 ) 中写入一些文本,然后按“Ready”( 2 ) 按钮将this对象传递给工厂,然后按“Print”( 3 ) 按钮生成 .pdf 文件。在这张图片中你可以看到PanelInneBeanContainerBean区域。

在此处输入图像描述

让我显示我的来源:

@ManagedBean(name="inne")
@ViewScoped
public class PanelInneBean extends AbstractPanel implements Serializable {
    private static final long serialVersionUID = 1L;
    private final int CODE = 4;
    private boolean use;
    private String tytul, opis;
    private PdfFactory pdf;

    @PostConstruct
    private void init() {
    pdf = PdfFactory.getPdfObject();
    use = false;
    }

    public PanelInneBean() {
    }

    public boolean getUse() {
    return use;
    }

    public String getTytul() {
    return tytul;
    }

    public void setTytul(String tytul) {
    this.tytul = tytul;
    }

    public String getOpis() {
    return opis;
    }

    public void setOpis(String opis) {
    this.opis = opis;
    }

    public int getCode() {
    return CODE;
    }

    private void add() {
    use = true;
    }

    public void addBean() {
    add();
    pdf.addElement(this);
    System.out.println("InnePanel after pdf.addElement() this.opis:" + this.opis);
    }
}

工厂来源:

@ManagedBean(name="factory")
@SessionScoped
public class PdfFactory implements Serializable {
//.............
private InneP inn = new InneP() //without new does not work too;
//.............

    public int addElement(PdfElement element) {
    pdfType = true;
    if (element.getUse()) {
        elementList.add(element);
        return 1;
    }
    return 0;
    }

//.............

public List<Element> getDocumentBody() throws DocumentException {
    initSignature();
    List<Element> list = new ArrayList<Element>();
    list.add(createDocDate());
    list.add(Chunk.NEWLINE);
    for (PdfElement p : elementList) {
        if (p.getUse()) {
        switch (p.getCode()) {
//............
        case 4:
            list.addAll(inn.generatePharse());
            break;
        }
        }
    }
    list.addAll(sF.generatePharse());
    return list;
    }

此类中的最后一个InneP源(此类生成要打印的段落)我得到了NPE

@ManagedBean
@RequestScoped
public class InneP {
    private List<Element> list = new ArrayList<Element>();
    private Font font;

    @ManagedProperty("#{inne}")
    private PanelInneBean panelInneBean;

    public InneP(){}

    public InneP(Font font) {
    this.font = font;
    }

    public void setPanelInneBean(PanelInneBean inne) {
    this.panelInneBean = inne;
    }

    public List<Element> generatePharse() {
    if (panelInneBean.getTytul().length() > 0) {
        System.out.println("drukowanie tytulu");
        list.add(createTitle(panelInneBean.getTytul()));
        list.add(Chunk.NEWLINE);
    }
    if (panelInneBean.getOpis().length() > 0) {
        list.add(createDescription(panelInneBean.getOpis()));
        list.add(Chunk.NEWLINE);
    }

    return list;
    }

    private Paragraph createTitle(String tytul) {
    System.out.println("inne tytul: " + tytul);
    font.setStyle(Font.NORMAL);
    Paragraph t = new Paragraph(tytul, font);
    t.setAlignment(Element.ALIGN_LEFT);
    return t;
    }

    private Paragraph createDescription(String opis) {
    System.out.println("inne opis:" + opis);
    font.setStyle(Font.BOLD);
    Paragraph d = new Paragraph(opis, font);
    d.setAlignment(Element.ALIGN_LEFT);
    return d;
    }

}

打印按钮只是将列表添加到for循环中并打印所有段落;我使用 iText lib 和 OpenFaces 来生成选项卡式窗格。

我希望我写了足够的信息。

4

1 回答 1

0

首先,如果您希望 bean 由 JSF 管理,您可以手动实例化它(使用new),您必须使用@ManagedProperty让容器实例化并设置您的属性(例如,就像您对panelInneBean字段所做的那样)。在您的情况下,这将不起作用,因为您想在会话范围的 bean 中使用请求范围的 bean,所以您不能注入它。原因是因为在一个会话范围 bean 的生命周期中,将有许多请求范围 bean 实例。因此,您需要以InneP其他方式获取您的实例。

在要使用InneP实例的方法中,您必须手动获取它,不要将它分配给某个类字段,使用局部变量,因为您将在每个请求中都有另一个实例:

InneP inneP = (InneP) context.getApplication().getExpressionFactory()
        .createValueExpression(FacesContext.getCurrentInstance().getELContext(), "#{inneP}", InneP.class)
            .getValue(FacesContext.getCurrentInstance().getELContext());
于 2013-03-10T19:37:10.790 回答