将信息传递到Vaadin 8中使用BrowserWindowOpener打开的新的Web浏览器窗口/标签

时间:2018-07-24 03:28:56

标签: parameter-passing vaadin vaadin8 new-window

在Vaadin 8中,我们可以让用户通过单击与BrowserWindowOpener关联的按钮,在Web浏览器中打开新的标签/窗口。作为discussed in the manual的一个新UI代表我们实例化。我们传递的只是一个.class对象,我们的UI子类的类将被实例化以显示在新窗口/选项卡中。例如:

BrowserWindowOpener opener = new BrowserWindowOpener( PersonDetailUI.class );

对我有用。我的问题是:如何在新窗口/标签中将一些信息传递给新的UI对象?

例如,我可能需要通过:

  • 要在数据库中查找的记录的ID号或UUID
  • 准备在布局中显示的JavaBean对象。

我看到了I asked about this same issue for Vaadin 7。考虑这是Vaadin 8问题的更新版本。唯一的答案推测是有关向新窗口的URI添加参数。但这将我限制为一小段文字。我更喜欢传递一个智能对象,而不是一个哑字符串。

2 个答案:

答案 0 :(得分:2)

基本上可以使用三种方法,以及这些方法的组合

  1. 使用URI参数。如您所述,这仅限于String类型的数据。

    • 您可以通过以下方式在UI中读取URI片段: String uriFragment = Page.getCurrent().getUriFragment();
    • 您可以使用VaadinRequest.getParameter()读取URI参数,在主UI的init(...)中将VaadinRequest作为参数给出
  2. 不同浏览器选项卡中的
  3. UI共享相同的Vaadin会话。这提供了一些工具,即

    • 您可以使用会话属性,即VaadinSession.getCurrent().getAttribute(…)VaadinSession.getCurrent().setAttribute(…)

    • 如果使用CDI或Spring,则可以注入/自动装配@VaadinSessionScoped bean。然后,该实例绑定到Session,因此在选项卡之间共享。

  4. 从数据库中读取数据(可能使用1.和/或2.作为键的帮助)

答案 1 :(得分:0)

Answer by Tatu隆德提到将URI参数传递给正在打开的新窗口。

示例应用程序,将URI参数传递到新窗口

这里是Vaadin 8.5.0中一个简单的小演示应用程序,用于演示该技术。

enter image description here

我们从假装从数据库中取回的三只猫开始。每次用户选择一只猫时,我们都会得到该猫的标识符UUID对象。我们生成该UUID的规范的32个字符的十六进制字符串表示形式。并且我们将其指定为要通过参数键cat_id传递的参数值。我们通过调用BrowserWindowOpener::setParameter来指定该参数。

请注意,我们是在Grid列出的猫中选择一个项目时执行的。由于浏览器在打开窗口时的限制,必须在用户单击其按钮之前 配置BrowserWindowOpener。据我所知,我们无法对单击按钮做出反应来运行代码。

新的浏览器窗口填充有UI的自动实例化的子类。在这种情况下,CatUI是我们写的。在CatUI中,我们获得URI参数,提取表示UUID的字符串,重新创建UUID对象,然后将其传递给我们假装的数据库服务以获取有问题的猫。然后,使用Cat对象值填充布局的字段。我们不会为数据绑定猫到布局而烦恼,因为这并不是本演示的重点。

注意事项:这只是一个演示,它忽略了与通过URI参数将信息传递到新窗口的问题没有直接关系的问题。例如,并发性的关键问题在这里被忽略了,但是在实际工作中并不会出现。

该演示包含四个类文件,所有文件都粘贴在下面。

  • MainUI(在应用启动时默认打开)
  • CatUI(当用户单击按钮时打开)
  • Cat(业务对象,具有nameid属性)
  • DatabaseService(假装猫记录的仓库)

MainUI

package com.basilbourque.example;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.BrowserWindowOpener;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Grid;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import javax.servlet.annotation.WebServlet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * This UI is the application entry point. A UI may either represent a browser window
 * (or tab) or some part of an HTML page where a Vaadin application is embedded.
 * <p>
 * The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
 * overridden to add component to the user interface and initialize non-component functionality.
 */
@Theme ( "mytheme" )
public class MainUI extends UI {
    private Grid< Cat > grid;
    private Button button;

    @Override
    protected void init ( VaadinRequest vaadinRequest ) {
        // Configure button to open now browser window/tab.
        this.button = new Button( "Open in new window" );
        BrowserWindowOpener opener = new BrowserWindowOpener( CatUI.class );
        opener.setFeatures( "height=300,width=500,resizable" );
        opener.extend( this.button );
        opener.setParameter( "cat_id" , new UUID(0,0).toString());  // Send nil UUID (all zeros) if nothing selected.
        System.out.println( "BWO URL: " + opener.getUrl() );
        this.button.setEnabled( false );

        this.grid = new Grid<>( Cat.class );
        this.grid.setCaption( "Cats" );
        List<Cat> cats = new DatabaseService().fetchAllCats() ;
        this.grid.setItems( cats  );
        // Every time the user selects a cat in the Grid, assign that cat’s ID to our `BrowserWindowOpener`. This way our button is always prepared to open a window for the selected cat.
        this.grid.addSelectionListener( event -> {
            Set< Cat > selectedCats = event.getAllSelectedItems();
            this.button.setEnabled( selectedCats.size() > 0 );
            if ( selectedCats.size() > 0 ) {  // If the user selected an item.
                Cat cat = selectedCats.stream().findFirst().get();
                opener.setParameter( "cat_id" , cat.getId().toString() );  // A UUID’s canonical presentation is as a 36-character hexadecimal string in five groups with HYPHEN-MINUS as delimiter.
            } else {
                opener.setParameter( "cat_id" , new UUID(0,0).toString());  // Send nil UUID (all zeros) if nothing selected.
            }
            System.out.println( "BWO URL: " + opener.getUrl() );
        } );
        this.grid.select( cats.stream().findFirst().get() ); // Select first item arbitrarily, to provoke the grid’s selection-listener above to fire.

        button.addClickListener( e -> {
            System.out.println( "BASIL opening now window" );
        } );

        final VerticalLayout layout = new VerticalLayout();
        layout.addComponents( this.grid , button );
        setContent( layout );
    }

    @WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
    @VaadinServletConfiguration ( ui = MainUI.class, productionMode = false )
    public static class MyUIServlet extends VaadinServlet {
    }
}

CatUI

package com.basilbourque.example;

import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.*;

import java.util.Optional;
import java.util.UUID;

public class CatUI extends UI {
    private Cat cat = null;

    @Override
    protected void init ( VaadinRequest vaadinRequest ) {
        // Retrieve a parameter from the URI of this UI/window.
        String catUuidString = vaadinRequest.getParameter( "cat_id" );  // In the URI key-value parameters, "cat_id" is our key, and a UUID’s hex string is the expected value.
        if ( null == catUuidString ) {  // If we did not receive the UUID-string parameter we expected.
            this.setContent( this.buildLayoutForNoCat( null ) );
            return;
        }
        UUID uuid = UUID.fromString( catUuidString );  // Rehydrate the `UUID` from our passed hex string representing the UUID’s value.
        Optional< Cat > cat = new DatabaseService().fetchCat( uuid );
        if ( cat.isPresent() ) {  // NULL check.
            System.out.println( "uuidString: " + uuid + " and cat: " + cat.get() );
            this.setContent( this.buildLayoutForCat( cat.get() ) );  // Retrieve the `Cat` object from our `Optional< Cat >` object by calling `get()` only after checking for NULL.
            return;
        } else {  // Failed to find cat.
            this.setContent( this.buildLayoutForNoCat( uuid ) );
            return;
        }
    }

    private Layout buildLayoutForCat ( Cat cat ) {
        this.cat = cat ;
        this.getPage().setTitle( "Cat details" );

        // Have some content for it
        TextField name = new TextField( "Name: " );
        name.setWidth( 100 , Unit.PERCENTAGE );
        name.setValue( this.cat.getName() );

        TextField id = new TextField( "Id: " );
        id.setWidth( 100 , Unit.PERCENTAGE );
        id.setValue( this.cat.getId().toString() );

        VerticalLayout layout = new VerticalLayout();
        layout.addComponent( name );
        layout.addComponent( id );
        return layout;
    }

    private Layout buildLayoutForNoCat ( UUID uuid ) {
        VerticalLayout layout = new VerticalLayout();
        String message = "No cat found for the id: " + uuid;
        Label label = new Label( message );
        layout.addComponentsAndExpand( label );
        return layout;
    }
}

Cat

package com.basilbourque.example;

import java.util.UUID;

public class Cat {
    private UUID id;
    private String name;

    public Cat ( UUID id , String name ) {
        this.id = id;
        this.name = name;
    }

    public UUID getId () {
        return id;
    }

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

    public String getName () {
        return name;
    }

    public void setName ( String name ) {
        this.name = name;
    }

    // Override `Object`.

    @Override
    public String toString () {
        return "Cat{ " +
                "id=" + id +
                ", name='" + name + '\'' +
                " }";
    }


}

DatabaseService

package com.basilbourque.example;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

// Pretending to be our gateway to a database.
public class DatabaseService {
    static private List< Cat > cats;

    {
        DatabaseService.cats = List.of(  // Produces an unmodifiable list. (A new feature in Java 9 and later.)
                new Cat( UUID.fromString( "adf5c1a0-912e-11e8-9eb6-529269fb1459" ) , "Fluffy" ) ,
                new Cat( UUID.fromString( "d37401c6-912e-11e8-9eb6-529269fb1459" ) , "Spot" ) ,
                new Cat( UUID.fromString( "de29b6d8-912e-11e8-9eb6-529269fb1459" ) , "Lilly Mae" )
        );
    }

    public List< Cat > fetchAllCats () {
        return new ArrayList<>( DatabaseService.cats );  // Copy the list, then return.
    }

    public Optional< Cat > fetchCat ( UUID uuid ) {
        return DatabaseService.cats.stream().filter( cat -> cat.getId().equals( uuid ) ).findFirst();
    }

    public static void main ( String[] args ) {
        Optional< Cat > cat = new DatabaseService().fetchCat(  UUID.fromString( "de29b6d8-912e-11e8-9eb6-529269fb1459" ) );
        if ( cat.isPresent() ) {
            System.out.println( "cat: " + cat.get() );
        } else {
            System.out.println( "No cat found." );
        }
    }
}