【问题标题】:JSf request scope in simple blog简单博客中的 JSf 请求范围
【发布时间】:2012-03-08 07:26:40
【问题描述】:

我正在尝试使用 jsf 2.0 创建简单的博客。它包含 2 个类:

BlogManager(在会话范围内) 博客(在请求范围内)

@Named("blogManager")
@SessionScoped
public class BlogManager {
    private List<Blog> blogs;

    @ManagedProperty(value = "#{blog}")
    Blog blog;

    public BlogManager() {
        blogs = new ArrayList<Blog>();
    }

    public List<Blog> getBlogs() {
        return blogs;
    }

    public void setBlogs(List<Blog> blogs) {
        this.blogs = blogs;
    }

    public Blog getBlog() {
        return blog;
    }

    public void setBlog(Blog blog) {
        this.blog = blog;
    }

    public void addBlog() {
        blogs.add(blog);
    }

    public void removeBlog(Blog blog) {
        blogs.add(blog);
    }
}

博客类:

@Named("blog")
@RequestScoped
public class Blog {

    private Integer id;

    private String title;
    private String text;
    private Date date;

    public Blog() {
        id = (int) System.currentTimeMillis();
    }

    private Integer readed;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Integer getReaded() {
        return readed;
    }

    public void setReaded(Integer readed) {
        this.readed = readed;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

}

然后在我的 xhtml 表单中我正在写这个东西:

<h:form>
            <fieldset>
                <legend>Blog</legend>
                <p>
                    Title:
                    <h:inputText value="#{blog.title}" />
                </p>
                <p>
                    Text:
                    <h:inputTextarea value="#{blog.text}" />
                </p>
                <p>
                    <h:commandButton action="#{blogManager.addBlog}" />
                </p>
            </fieldset>
        </h:form>

当我点击提交时,它说博客目标无法访问。它是请求范围。我在想一旦 jsf 找不到博客对象,它就会创建并将用户输入分配给博客对象。然后我可以在 blogManager 中看到它。但它不起作用。我应该为博客类使用什么范围?我可以在 blogManager 中注入请求范围吗?

谢谢

【问题讨论】:

  • 只是好奇,您的blog bean 似乎没有任何行为,那么将其定义为RequestScoped bean 有什么需要呢?为什么不让它成为一个简单的 pojo?
  • 如果我做简单的 pojo 那么我不能在 xhml 页面中使用它来进行用户输入:例如:跨度>
  • 如果你使用@ManagedBean("YourBean")注解而不是@Named("YourBean")会发生什么?试一试。
  • @elbek:当然可以。在下面检查我的答案。

标签: java jsf-2 scope


【解决方案1】:

您正在混合 JSF 和 CDI 注释。您已经通过 CDI 的 @Named 管理您的 bean,但是您尝试使用 JSF 特定的 @ManagedProperty 注释将一个 CDI 托管 bean 注入另一个 CDI 托管 bean。这是行不通的。您需要改用 CDI 自己的 @Inject 注释。 @ManagedProperty 仅适用于 JSF @ManagedBean 类。

相应地修复它:

@Inject
private Blog blog;

此外,您还需要绝对确保当您通过 CDI 的 @Named 管理 bean 时,所有像 @SessionScoped 这样的范围注释都来自 javax.enterprise.context 包,而不是来自 javax.faces.bean 包。


与具体问题无关,这种设计有缺陷。 Blog 类不应是托管 bean,而应是 @Entity 并且只是 BlogManager 类的普通属性。

【讨论】:

  • oops.. 我显然忽略了它的 CDI 注释这一事实。你的应该被标记为答案而不是我的!
【解决方案2】:

理想情况下,您的 Blog 类应该只是一个 POJO。它应该是BlogManager 的成员。所以你唯一需要的豆子是 博客管理器:

@Named("blogManager")
@SessionScoped
public class BlogManager {
    private List<Blog> blogs;

    private Blog blog;

    public BlogManager() {
        blogs = new ArrayList<Blog>();
            blog = new Blog();
    }

    // getter setters for blog and blogs

    public void addBlog() {
        blogs.add(blog);
    }

    public void removeBlog(Blog blog) {
        blogs.add(blog);
    }
}

博客类:

public class Blog {

    private Integer id;

    private String title;
    private String text;
    private Date date;
    private Integer readed;

    public Blog() {
        id = (int) System.currentTimeMillis();
    }

    // getters-setters

}

还有你的 xhtml:

<h:form>
            <fieldset>
                <legend>Blog</legend>
                <p>
                    Title:
                    <h:inputText value="#{blogManager.blog.title}" />
                </p>
                <p>
                    Text:
                    <h:inputTextarea value="#{blogManager.blog.text}" />
                </p>
                <p>
                    <h:commandButton action="#{blogManager.addBlog}" />
                </p>
            </fieldset>
        </h:form>

【讨论】:

  • 这是我第二次做的,但问题是每个请求的 BlogManager 的所有时间 jsf 类构造函数?它应该在会话中,并且应该在每个会话中创建一次。我错了吗?
  • 这确实很奇怪!你是对的,它不应该被多次调用。其他地方出了点问题..
【解决方案3】:

您不能将较低范围的对象注入到较高范围的对象中。因此,您不能将请求范围的对象blog 注入到您的会话范围blogManager。如果你将它创建为一个简单的 pojo,你可以像 &lt;h:inputText value="#{blogManager.blog.title}" /&gt; 一样访问它

【讨论】:

  • You cannot inject a lower scoped object to a higher scoped object+1
  • 错了,这仅适用于 JSF 托管 bean,不适用于 CDI 托管 bean。
猜你喜欢
  • 2011-11-11
  • 2011-08-15
  • 2011-09-02
  • 2014-12-02
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多