当前位置: 首页 > 知识库问答 >
问题:

从Vaadin 8应用程序生成HTML页面并在新窗口中打开

廖臻
2023-03-14

在我的Vaadin 8 web应用程序中,我希望用户能够通过单击按钮在另一个窗口中打开报告。内容将由Vaadin应用程序使用普通HTML5生成,而不是使用Vaadin小部件。

Vaadin 8手册有一个页面处理浏览器窗口。它显示了如何使用浏览器WindowOpener对象打开新窗口。但该窗口包含一个VaadinUI子类,而我希望生成自己的HTML内容。

传递数据库标识符值等信息的额外积分。

共有2个答案

习海
2023-03-14

您也可以通过将html字符串作为参数传递到BrowserWindowOpener的UI类来实现这一点:

BrowserWindowOpener opener = new BrowserWindowOpener(MyUI.class);
opener.extend(myButtonForLaunchingNewWindow);
opener.setParameter("text",myHtmlStringWhichIJustGenerated);

public static class MyUI extends UI {
    @Override
    protected void init(VaadinRequest request) {

        String text = request.getParameter("text");
        // Have some content to print
        setContent(new Label(
                text,
                ContentMode.HTML));
    }
}

编辑:使用我以前的方法,我遇到了一个问题,由于HTTP 400错误,弹出页面不显示。这是由于超文本传输协议头大小太大(是的,我生成了一个大的html页面)。

我的解决方案是直接为BrowserWindowOpener生成StreamResource:

StreamResource streamResource = new StreamResource((StreamResource.StreamSource) () -> 
    new ByteArrayInputStream(htmlString.getBytes()), "report.html");
BrowserWindowOpener opener = new BrowserWindowOpener(streamResource);
opener.extend(myButtonForLaunchingNewWindow);
司空鸿熙
2023-03-14

下面是一个完整的示例应用程序,内置于Vaadin 8.5.1中。我们在TextField中将UUID显示为文本,并使用一个按钮打开第二个窗口,显示由我们的Vaadin应用程序生成的HTML网页,而不使用Vaadin小部件或布局。该字段的id被传递到新窗口,在实际应用程序中,该窗口可用于数据库查找。

如手册中该页所示,您确实需要使用浏览器开窗器(或链接)。由于浏览器常见的安全限制,必须在用户单击按钮之前提前配置。因此,与在按钮的单击侦听器中编写代码不同,我们必须更早地配置BrowserWindowOpener对象,并与按钮关联。

定义用户要单击以生成报告的按钮。

Button webPageButton = new Button( "Generate Person report" );

定义要打开的新窗口的目标,它应该使用什么URL作为其web地址。我们想回拨到我们的Vaadin应用程序。因此,请在运行时获取此web应用程序的URL。我们的web应用在Javaservlet术语中的技术术语是“上下文”。因此,我们询问当前上下文的URL(路径)。

String servletPath = VaadinServlet.getCurrent().getServletContext().getContextPath(); // URL for this web app at runtime.

我们需要将该URL缩小到我们的报表,详细说明要从数据库加载的单个Person对象。因此,我们发明了person.html作为URL中请求的资源。

我们希望在不调用Vaadin小部件的情况下请求动态生成的超文本标记语言页面,因此我们使用了ExtranalResources类。

Resource resource = new ExternalResource( servletPath + "/person.html" );  // Defining an external resource as a URL that is not really so external -- will call back into this same web app.

有了资源对象,我们就可以定义浏览器WindowOpener了。

BrowserWindowOpener webPageOpener = new BrowserWindowOpener( resource );

我们来配置一下它的一些属性,比如要打开的窗口的标题。

webPageOpener.setWindowName( "Person ID: " + personUuid.getValue() );  // Set title of the new window to be opened.

我们希望传递“person”行的ID,该行将从数据库中检索,然后显示在生成的网页中。

一种将此类信息作为URL上查询字符串中的参数传递的方法。因此,我们的URL的最后一部分看起来像person。html?人员id=f0e32ddc-18ed-432c-950b-eda3f3e4a80d。这个值必须是文本的,所以我们使用代表UUID的128位的规范的36个字符的十六进制字符串作为数据库标识符。我们为该值提供了一个任意键名,例如person\u id

String param = "person_id";
webPageOpener.setParameter( param , personUuid.getValue() );

我们可以设置要打开的新窗口的大小。我们将在运行时使其与用户的当前窗口大小相同。我们将使窗口的大小可调整,这样用户可以将其拉伸得更大或更小。我们希望以字符串形式描述窗口功能,例如width=800、height=600、resizeable。我们将在运行时插入该宽度和高度。

String windowFeaturesString = String.format( "width=%d,height=%d,resizable" , Page.getCurrent().getBrowserWindowWidth() , Page.getCurrent().getBrowserWindowHeight() ) ; // Same size as original window.
webPageOpener.setFeatures( windowFeaturesString );  // Example: "width=800,height=600,resizable".

我们完成了要打开的新窗口的配置。由于在事件侦听器中用户单击按钮时不能调用窗口打开,通常情况下其他行为也会这样,因此我们必须提前将打开器与按钮关联起来。

webPageOpener.extend( webPageButton ); // Associate opener with button.

为了好玩,我们可以预览新窗口调用的URL。在实际工作中,在这里使用日志框架,如SLF4J和LogBack。对于这个演示,我们转储到控制台。

System.out.println( "TRACE BrowserWindowOpener URL: " + webPageOpener.getUrl() );

很好,我们现在有了一个按钮,它带有一个开瓶器集,用于请求生成基于HTML的报告。接下来,我们必须生成该报告。要做到这一点,请告诉我们的Vaadin应用程序,希望有个人的传入URL。我们在上面指定的htmlURL。我们通过实现RequestHandler接口来实现这一点。请参阅手册。

在我们的Request estHandler中,我们做四件事:

  1. 检索在新窗口中打开的URL的查询字符串中作为参数传递的UUID的十六进制字符串
  2. 从该十六进制字符串重构UUID对象
  3. 将该UUID对象传递给一个例程,该例程生成要在此新窗口中显示的HTML
  4. 通过将HTML传递给VaadinResponse对象,在新窗口中显示该HTML,该对象通过Javaservlet技术传递回用户的web浏览器

并且我们必须实例化我们的刚需处理程序实现,并将实例注册到用户的会话,一个Vaadin会话对象。

VaadinSession.getCurrent().addRequestHandler(
        new RequestHandler() {
            @Override
            public boolean handleRequest ( VaadinSession session ,
                                           VaadinRequest request ,
                                           VaadinResponse response )
                    throws IOException {
                if ( "/panel.html".equals( request.getPathInfo() ) ) {
                    // Retrieve the hex-string of the UUID from the URL’s query string parameter.
                    String uuidString = request.getParameter( "person_id" );  // In real-work, validate the results here.
                    UUID uuid = UUID.fromString( uuidString ); // Reconstitute a `UUID` object from that hex-string. In real-work, validate the results here.
                    System.out.println( "UUID object reconstituted from string passed as parameter in query string of URL opened in new window: " + uuid );
                    // Build HTML.
                    String html = renderHtml( uuid );
                    // Send out the generated text as HTML, in UTF-8 character encoding.
                    response.setContentType( "text/html; charset=utf-8" );
                    response.getWriter().append( html );
                    return true; // We wrote a response
                } else
                    return false; // No response was written
            }
        } );

填写该方法以生成HTML。

// Generate the HTML to report on the details of a `person` from the database, given the UUID of that database row.
private String renderHtml ( UUID uuid ) {
    String eol = "\n"; // End-of-line character(s) to use in the HTML.
    StringBuilder html = new StringBuilder();
    html.append( "<!DOCTYPE html>" ).append( eol );
    html.append( "<html>" ).append( eol );
    html.append( "<head>" ).append( eol );
    html.append( "<title>Person</title>" ).append( eol );
    html.append( "</head>" ).append( eol );
    html.append( "<body style='color:DarkSlateGray' >" ).append( eol );
    html.append( "<h1>Demo</h1>" ).append( eol );
    html.append( "<p>This is a drill. This is only a drill.</p>" ).append( eol );
    html.append( "<p>If this had been a real application, you would have seen some data.</p>" ).append( eol );
    html.append( "<p>Person ID: " ).append( uuid.toString() ).append( ".</p>" ).append( eol );
    html.append( "<p style='color:DimGray ; font-family: Pragmata Hack Menlo monospaced' >Report generated " ).append( Instant.now() ).append( ".</p>" ).append( eol );
    html.append( "</body>" ).append( eol );
    html.append( "</html>" ).append( eol );
    String s = html.toString();
    return s;
}

生成的HTML源代码如下所示:

<!DOCTYPE html>
<html>
<head>
<title>Person</title>
</head>
<body style='color:DarkSlateGray' >
<h1>Demo</h1>
<p>This is a drill. This is only a drill.</p>
<p>If this had been a real application, you would have seen some data.</p>
<p>Person ID: cc5e975b-2632-4c92-a1cb-b25085c60e60.</p>
<p style='color:DimGray ; font-family: Pragmata , Hack , Menlo , monospace' >Report generated 2018-08-05T02:33:13.028594Z.</p>
</body>
</html>

为方便起见,这里是整个Vaadin 8应用程序,MyUI的内容。java文件首先由Vaadin Ltd公司提供的最简单的Maven原型生成。

package com.basilbourque.example;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.*;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import java.io.IOException;
import java.time.Instant;
import java.time.ZonedDateTime;
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 MyUI extends UI {

    @Override
    protected void init ( VaadinRequest vaadinRequest ) {
        final VerticalLayout layout = new VerticalLayout();

        TextField personUuid = new TextField( "UUID of Person:" );
        personUuid.setWidth( 22 , Unit.EM );
        personUuid.setValue( UUID.randomUUID().toString() );
        personUuid.setReadOnly( true );

        Button webPageButton = new Button( "Generate Person report" );
        webPageButton.setWidthUndefined();
        webPageButton.addClickListener( e -> {
            System.out.println( "Button clicked. " + ZonedDateTime.now() );
        } );

        // Configure web page opener object. Must be done *before* user clicks on button, not after.
        String servletPath = VaadinServlet.getCurrent().getServletContext().getContextPath(); // URL for this web app at runtime.
        Resource resource = new ExternalResource( servletPath + "/person.html" );  // Defining an external resource as a URL that is not really so external -- will call back into this same web app.
        BrowserWindowOpener webPageOpener = new BrowserWindowOpener( resource );
        webPageOpener.setWindowName( "Person ID: " + personUuid.getValue() );  // Set title of the new window to be opened.
        String param = "person_id";
        webPageOpener.setParameter( param , personUuid.getValue() );
        String windowFeaturesString = String.format( "width=%d,height=%d,resizable" , Page.getCurrent().getBrowserWindowWidth() , Page.getCurrent().getBrowserWindowHeight() ); // Same size as original window.
        webPageOpener.setFeatures( windowFeaturesString );  // Example: "width=800,height=600,resizable".
        webPageOpener.extend( webPageButton ); // Connect opener with button.
        System.out.println( "TRACE BrowserWindowOpener URL: " + webPageOpener.getUrl() );

        layout.addComponents( personUuid , webPageButton );
        setContent( layout );

        // A request handler for generating some content
        VaadinSession.getCurrent().addRequestHandler(
                new RequestHandler() {
                    @Override
                    public boolean handleRequest ( VaadinSession session ,
                                                   VaadinRequest request ,
                                                   VaadinResponse response )
                            throws IOException {
                        if ( "/person.html".equals( request.getPathInfo() ) ) {
                            // Retrieve the hex-string of the UUID from the URL’s query string parameter.
                            String uuidString = request.getParameter( "person_id" );  // In real-work, validate the results here.
                            UUID uuid = UUID.fromString( uuidString ); // Reconstitute a `UUID` object from that hex-string. In real-work, validate the results here.
                            System.out.println( "UUID object reconstituted from string passed as parameter in query string of URL opened in new window: " + uuid );
                            // Build HTML.
                            String html = renderHtml( uuid );
                            // Send out the generated text as HTML, in UTF-8 character encoding.
                            response.setContentType( "text/html; charset=utf-8" );
                            response.getWriter().append( html );
                            return true; // We wrote a response
                        } else
                            return false; // No response was written
                    }
                } );
    }

    // Generate the HTML to report on the details of a `person` from the database, given the UUID of that database row.
    private String renderHtml ( UUID uuid ) {
        String eol = "\n"; // End-of-line character(s) to use in the HTML.
        StringBuilder html = new StringBuilder();
        html.append( "<!DOCTYPE html>" ).append( eol );
        html.append( "<html>" ).append( eol );
        html.append( "<head>" ).append( eol );
        html.append( "<title>Person</title>" ).append( eol );
        html.append( "</head>" ).append( eol );
        html.append( "<body style='color:DarkSlateGray' >" ).append( eol );
        html.append( "<h1>Demo</h1>" ).append( eol );
        html.append( "<p>This is a drill. This is only a drill.</p>" ).append( eol );
        html.append( "<p>If this had been a real application, you would have seen some data.</p>" ).append( eol );
        html.append( "<p>Person ID: " ).append( uuid.toString() ).append( ".</p>" ).append( eol );
        html.append( "<p style='color:DimGray ; font-family: Pragmata , Hack , Menlo , monospace' >Report generated " ).append( Instant.now() ).append( ".</p>" ).append( eol );
        html.append( "</body>" ).append( eol );
        html.append( "</html>" ).append( eol );
        String s = html.toString();
        System.out.println( "\n\n" + s + "\n\n" );
        return s;
    }

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

 类似资料:
  • 问题内容: 如何在JavaScript中打开一个新窗口并插入HTML数据,而不仅仅是链接到HTML文件? 问题答案: 您可以使用window.open在javascript中打开一个新的窗口/选项卡(根据浏览器设置)。 通过使用document.write,您可以将HTML内容写入打开的窗口。

  • 问题内容: 我通过window.open打开了一个弹出窗口。使用JavaScript打开,我想在关闭此弹出窗口时刷新父页面。(onclose事件?)我该怎么办? 问题答案: 您可以使用“ window.opener”访问父窗口,因此,在子窗口中编写如下内容:

  • 问题内容: 当用户单击它时,如何在新窗口中将其设置为一定的宽度和高度?在firefox中,当前代码只会打开一个新标签页(而不是一个新窗口) 问题答案: 要在包含尺寸和所有内容的新窗口中打开,您将需要调用JavaScript函数,因为target =“ _ blank”不允许您调整尺寸。一个例子是: 希望这对您有所帮助。

  • 编辑4: 编辑2 上面的代码为父窗口或子窗口提供了相同的标题。

  • 问题内容: 是否可以在新标签页而不是同一标签页中打开链接? 问题答案: 您应该在锚标记中添加和。 例如: 添加不是强制性的,但这是建议的安全措施。可以在下面的链接中找到更多信息。

  • 本文向大家介绍在ASP中不用模板生成HTML静态页直接生成.html页面,包括了在ASP中不用模板生成HTML静态页直接生成.html页面的使用技巧和注意事项,需要的朋友参考一下 我们一般生成HTML静态页时,常常会事先做好一个模板,然后生成时调用模板文件。那么有没有办法不用模板,如一个正常的htmer.asp页面,直接生成为htmer.html页面呢?当然是可以的,而且非常简单,今天就教大家在A