如何在jsf页面中显示数据后销毁会话

如何在jsf页面中显示数据后销毁会话,jsf,session,Jsf,Session,我有一个问题:我正在制作这个精彩的教程。但是,我并没有像前面介绍的那样在JSP中创建它,而是创建了一个JSF版本。只是为了理解构建这样一个应用程序的逻辑 在ControllerServlet.java的某些部分中,有以下代码: int orderId = orderManager.placeOrder(name, email, phone, address, cityRegion, ccNumber, cart); // if order processed s

我有一个问题:我正在制作这个精彩的教程。但是,我并没有像前面介绍的那样在JSP中创建它,而是创建了一个JSF版本。只是为了理解构建这样一个应用程序的逻辑

在ControllerServlet.java的某些部分中,有以下代码:

int orderId = orderManager.placeOrder(name, email, phone, address, cityRegion, ccNumber, cart);

                // if order processed successfully send user to confirmation page
                if (orderId != 0) {

                    // dissociate shopping cart from session
                    cart = null;

                    // end session
                    session.invalidate();

                    // get order details
                    Map orderMap = orderManager.getOrderDetails(orderId);

                    // place order details in request scope
                    request.setAttribute("customer", orderMap.get("customer"));
                    request.setAttribute("products", orderMap.get("products"));
                    request.setAttribute("orderRecord", orderMap.get("orderRecord"));
                    request.setAttribute("orderedProducts", orderMap.get("orderedProducts"));

                    userPath = "/confirmation";

                // otherwise, send back to checkout page and display error
如您所见,作者使会话无效,以便允许另一个采购订单。我制作了一个具有会话范围的托管Bean,以便在整个会话中保持数据的可用性。但是,当我试图清理会话时,正如作者在教程中所做的那样,我无法收到用于确认的数据

然后,我制作了一个不同的托管bean,以便有一个用来处理订单(CartManagerBean),另一个用来表示确认(ConfirmationMBean)。我只是将confirmatioBean注入cartBean中,以传递orderId,这是显示数据所必需的。在confirmationBean中,我创建了一个cleanUp()方法,使会话无效

但通常情况下,数据并不呈现。因此,如果有人能告诉我该做什么,我将不胜感激

下面是我的cartBean代码中将数据传递给确认bean的部分:

...
@ManagedProperty(value ="#{confirmationBean}")
private ConfirmationMBean confirmationBean;
...
public String  makeConfirmation() {
    FacesContext fc = FacesContext.getCurrentInstance();
    if (!cartMap.isEmpty()) {
        int orderId = orderManager.placeOrder(name, email, phone, address, credicard, cartMap);

        // if order processed successfully send user to confirmation page
        if (orderId != 0) {
            // get order details
            confirmationBean.setOrderId(orderId);

            // dissociate shopping cart from session
             cartMap.clear();

            // end session
            //fc.getExternalContext().invalidateSession();
        }
    }

   return "confirmation";
}
如您所见,我对使会话无效的部分进行了注释。以下是我为确认MBean实现的代码:

@ManagedBean(name = "confirmationBean")
@会议范围 公共类确认MBean实现可序列化{

private Customer customer;
private List<OrderedProduct> orderedProducts;
private CustomerOrder orderRecord;
private List<Product> products;
private int orderId;

@EJB
private OrderManager orderManager;

public void cleanUp(){
    FacesContext fc = FacesContext.getCurrentInstance();
    fc.getExternalContext().invalidateSession();
}

private void init(){
    Map<String, Object> orderMap = orderManager.getOrderDetails(orderId);

    customer = (Customer) orderMap.get("customer");
    orderRecord = (CustomerOrder) orderMap.get("orderRecord");
    orderedProducts = (List<OrderedProduct>) orderMap.get("orderedProducts");
    products = (List<Product>) orderMap.get("products");
}

public Customer getCustomer() {
    return customer;
}

public void setCustomer(Customer customer) {
    this.customer = customer;
}

public List<OrderedProduct> getOrderedProducts() {
    return orderedProducts;
}

public void setOrderedProducts(List<OrderedProduct> orderedProducts) {
    this.orderedProducts = orderedProducts;
}

public CustomerOrder getOrderRecord() {
    return orderRecord;
}

public void setOrderRecord(CustomerOrder orderRecord) {
    this.orderRecord = orderRecord;
}

public List<Product> getProducts() {
    return products;
}

public void setProducts(List<Product> products) {
    this.products = products;
}

public int getOrderId() {
    return orderId;
}

public void setOrderId(int orderId) {
    this.orderId = orderId;
    init();
    cleanUp();
}
私人客户;
私有列表订购产品;
私人客户订单记录;
私人上市产品;
私有int-orderId;
@EJB
私人订单管理器订单管理器;
公共空间清理(){
FacesContext fc=FacesContext.getCurrentInstance();
fc.getExternalContext().invalidateSession();
}
私有void init(){
Map orderMap=orderManager.getOrderDetails(orderId);
customer=(customer)orderMap.get(“customer”);
orderRecord=(CustomerOrder)orderMap.get(“orderRecord”);
orderedProducts=(列表)orderMap.get(“orderedProducts”);
products=(List)orderMap.get(“products”);
}
公共客户getCustomer(){
退货客户;
}
公共作废设置客户(客户){
this.customer=customer;
}
公共列表getOrderedProducts(){
退货订购的产品;
}
public void setOrderedProducts(列出orderedProducts){
this.orderedProducts=orderedProducts;
}
公共CustomerOrder getOrderRecord(){
退货订单记录;
}
公共无效setOrderRecord(CustomerOrder orderRecord){
this.orderRecord=orderRecord;
}
公共列表产品(){
退货产品;
}
公共产品(列出产品){
这一点。产品=产品;
}
public int getOrderId(){
返回订单ID;
}
公共无效setOrderId(int-orderId){
this.orderId=orderId;
init();
清理();
}
}

如您所见,当orderId由前面的bean设置时,将从数据库请求数据,并填充变量以显示在facelet中。?为了获得与本教程相同的结果,我必须在何处或如何使用清理方法


提前感谢。

将调用操作的bean放在请求范围而不是会话范围中,并将所需的会话范围bean作为(托管)属性保存

@ManagedBean
@RequestScoped
public class SubmitConfirmationBean {

    @ManagedProperty("#{cartBean}")
    private CartBean cartBean;

    // ...
}
并通过
{submitconformationbean.cartBean…}
而不是
{cartBean…}
引用它

或者,将所需的会话作用域bean显式放置在请求作用域中,操作方法与使会话无效的操作方法相同:

externalContext.getRequestMap().put("cartBean", cartBean);

这样,
#{cartBean…}
将引用请求范围内的会话,而不是会话范围内的会话,会话范围内的会话是在此时重新创建的,因为您破坏了会话。请求范围内的一个已被下一个请求丢失。

谢谢BalusC,我按照您的建议更改了代码,但这样我没有找到发送orderId的方法,该orderId包含所有要在确认页面中显示的数据。我得到了一个NullPointerException,在这里我必须获得orderId值才能从数据库请求数据。我还在工作,如果我找到了解决办法,我会把它贴在这里也许你改变太多了?它应该只应用于使会话无效的submit按钮,而不应用于所有其他方法/视图!另外,我不确定在invalidate期间,您希望在最后一页中显示哪个bean。很可能您实际上打算保留
ConfirmationBean
而不是
CartBean
。你的问题不清楚。没错,我想保留
确认bean
,但是这个bean使用orderId值,它是在
CartBean
中生成的。那么,我如何将这个值从一个bean传递到另一个bean呢?在答案中,只需将
CartBean
替换为
ConfirmationBean
。我不理解您的第一个答案,对此表示歉意。解决方案“或者,将所需的会话作用域bean显式地放在请求作用域中,与使会话无效的操作方法相同:externalContext.getRequestMap().put(“cartBean”,cartBean);”是关键。在读了几遍你的答案后,我做到了,而且效果很好。谢谢