Jsf 为实体创建母版详细信息页,如何链接它们以及选择哪个bean范围
我已经开始学习JSF,但遗憾的是,大多数教程只提供了登录或注册部分 你能给我举一些更深入的例子吗?我感兴趣的一件事是展示产品列表的页面。我在主页上,按产品页面,以便查看添加的最新产品。每次我访问页面时,都会根据数据库中的最新条目创建产品列表。我该怎么办 解决这个问题的一种方法是创建一个会话范围的托管bean,我将在其中放置通过其他托管bean更新的不同实体。我在一些教程中发现了这种方法,但它似乎相当困难和笨拙 解决这样的问题最好的方法是什么?在两页master detail用户界面中,会话作用域的正确用法是什么 会话作用域的正确用法是什么 仅将其用于会话范围的数据,而不用于其他数据。例如,登录用户、其设置、所选语言等 另见:Jsf 为实体创建母版详细信息页,如何链接它们以及选择哪个bean范围,jsf,session,scope,master-detail,Jsf,Session,Scope,Master Detail,我已经开始学习JSF,但遗憾的是,大多数教程只提供了登录或注册部分 你能给我举一些更深入的例子吗?我感兴趣的一件事是展示产品列表的页面。我在主页上,按产品页面,以便查看添加的最新产品。每次我访问页面时,都会根据数据库中的最新条目创建产品列表。我该怎么办 解决这个问题的一种方法是创建一个会话范围的托管bean,我将在其中放置通过其他托管bean更新的不同实体。我在一些教程中发现了这种方法,但它似乎相当困难和笨拙 解决这样的问题最好的方法是什么?在两页master detail用户界面中,会话作用域
每次我访问页面时,都会根据数据库中的最新条目创建产品列表。我该怎么办 通常使用请求或视图范围。列表的加载应在
@PostConstruct
方法中进行。如果页面不包含任何
,则请求范围可以。视图作用域bean的行为就像没有
时的请求作用域
所有“查看产品”和“编辑产品”链接/按钮,这些链接/按钮仅检索信息(即幂等元),这些链接/按钮可以是纯GET
/
,其中您通过
将实体标识符作为请求参数传递
所有“删除产品”和“保存产品”链接/按钮都将操作信息(即非幂等项),它们应该通过
/
执行POST操作(您不希望它们可以被书签/搜索机器人索引!)。这又需要一个
。为了为验证和ajax请求保留数据(这样就不需要在每个请求上重新加载/预初始化实体),bean最好是视图范围
请注意,基本上每个视图都应该有一个单独的bean,并且还请注意,这些bean不一定需要相互引用
因此,考虑到这个“产品”实体:
这个“产品服务”EJB:
此转换器用于“编辑产品”的
:
您甚至可以使用通用转换器,这在中进行了解释
另见:
中删除所需的/部分,而使用编辑表单的有条件呈现(正如BalusC所做的),并使用相反的条件来为用户推荐特定的链接“list/master”屏幕,甚至可以使用viewAction来测试参数并强制重定向到该列表。好的,谢谢。在这种情况下,我应该将产品列表存储在哪里?现在我有一个名为products Controller的控制器Bean(包含为产品实体调用的所有操作)和一个产品模型(与相应数据库表具有相同属性的JavaBean)。我应该将productList属性存储在何处,以便我可以从product page中访问它。Well in need仅在product page中访问products list。每次我访问该页时,都会从数据库中的最新条目创建product list。我该如何处理此问题?我希望有更多类似于此的问题和答案可供选择CKK bean用法。你看到的大多数例子都是完全错误的。问题标题并不代表你的内容。主细节概念与简单的产品列表页面完全不同。+1在JSF中进行主/细节编辑的模式非常好。只是这应该放在某个地方的蓝图中。谢谢!你的博客文章给了me我需要的所有答案。@BalusC如果这篇文章有一个设置编辑布尔值的支持bean方法,但你在这里建议一个简单的GET链接,你会如何将你的建议合并到这篇文章中使用相同的页面进行编辑和查看?我喜欢上面的内容,它很简单,但我也想说“嘿,你无权编辑”d redirec/fwd仅当有人猜到URL“edit.xhtml?product#id=####我知道这篇文章很旧,也许你现在有了一些更新的方法。非常感谢这个伟大的例子,你救了我一天:)ProductService.save()
method,在EditProduct.save()中引用)
,似乎在ProductService
EJB类中缺少。
@Entity
public class Product {
@Id
private Long id;
private String name;
private String description;
// ...
}
@Stateless
public class ProductService {
@PersistenceContext
private EntityManager em;
public Product find(Long id) {
return em.find(Product.class, id);
}
public List<Product> list() {
return em.createQuery("SELECT p FROM Product p", Product.class).getResultList();
}
public void create(Product product) {
em.persist(product);
}
public void update(Product product) {
em.merge(product);
}
public void delete(Product product) {
em.remove(em.contains(product) ? product : em.merge(product));
}
// ...
}
@Named
@RequestScoped
public class ViewProducts {
private List<Product> products; // +getter
@EJB
private ProductService productService;
@PostConstruct
public void init() {
products = productService.list();
}
// ...
}
@Named
@ViewScoped
public class EditProduct {
private Product product; // +getter +setter
@EJB
private ProductService productService;
public String save() {
productService.update(product);
return "/products?faces-redirect=true";
}
// ...
}
@Named
@RequestScoped
public class ProductConverter implements Converter {
@EJB
private ProductService productService;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value == null || value.isEmpty()) {
return null;
}
try {
Long id = Long.valueOf(value);
return productService.find(id);
} catch (NumberFormatException e) {
throw new ConverterException("The value is not a valid Product ID: " + value, e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return "";
}
if (value instanceof Product) {
Long id = ((Product) value).getId();
return (id != null) ? String.valueOf(id) : null;
} else {
throw new ConverterException("The value is not a valid Product instance: " + value);
}
}
}