vaadin 7 URL parameter

zappee picture zappee · May 11, 2013 · Viewed 15.6k times · Source

I am not too familiar with vaadin 7 and I can not figure out this. I tried to use google but no useful result.

My question is very simple. How can I get the request url parameters in my UI class?

My url has a parameter: host/myvaadinapp/?code=erefdvdfgftf...

The url parameter comes from facebook after user logged in (OAuth) and I need to handle the value of code url parameter in my code.

I tried to do these:

    @PreserveOnRefresh
    public class AdminUi extends UI
    {
        @Override
        protected void init(VaadinRequest request)
        {
            ...
            System.out.println( request.getPathInfo());
            System.out.println( request.getRemoteHost());
            System.out.println( request.getParameterMap().size());
            System.out.println( request.getAttribute("code") );
            System.out.println( request.getParameter("code") );
            ...
        }
    }

Result: request.getAttribute("code"): null request.getParameter("code"): null

I realized that getParameterMap() has a "v-loc" parameter. But if I use it variable I have to write some code to get url parameter from this variable:

v-loc: host/myvaadinapp/?code=erefdvdfgftf... theme: reindeer v-rtzo: -600 v-dston: false ...

I think, it is not too nice solution.

Could you help me how can I get the original url parameters in vaadin?

Thank you.


My comment are:

I tried to use request.getParameter("code") but it was not working. I do not know why.

My original url was: host/demoVaadinApp/?name=zzz

I used this code:

    public class Xxxx extends UI
    {
        /**
     * Main UI
     */
    @Override
    protected void init(VaadinRequest request)
    {
        String name = request.getParameter("name");
        if (name == null)
            {
            name = "Unknown";
        }

        setContent(new Label("Hello " + name));
        }
    }

I start my vaadin application in Embedding UI mode.

Content of my web.xml file:

<!-- ******************************************************************* -->
<!-- context parameters                                                  -->
<!-- ******************************************************************* -->
<context-param>
    <description>Vaadin production mode</description>
    <param-name>productionMode</param-name>
    <param-value>false</param-value>
</context-param>

<!-- ******************************************************************* -->
<!-- servlet definition                                                  -->
<!-- ******************************************************************* -->
<!-- +++++ Vaadin  servlet +++++++++++++++++++++++++++++++++++++++++++++ -->
<servlet>
    <servlet-name>VaadinServlet</servlet-name>
    <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
    <init-param>
        <description>Vaadin UI class</description>
        <param-name>UI</param-name>
        <param-value>com.coupoholics.ui.admin.AdminUi</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>VaadinServlet</servlet-name>
    <url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>

<!-- ******************************************************************* -->
<!-- welcome file list definition                                        -->
<!-- ******************************************************************* -->
<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

index.html:

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>
    <script type="text/javascript" src="./VAADIN/vaadinBootstrap.js"></script>
    <iframe tabindex="-1" id="__gwt_historyFrame" style="position: absolute; width: 0; height: 0; border: 0; overflow: hidden" src="javascript:false"></iframe>

                 <div id="content-body">
                    <!-- Optional placeholder for the loading indicator -->
                    <div class=" v-app-loading"></div>
                    <!-- Alternative fallback text -->
                    <noscript>You have to enable javascript in your browser to use this application.</noscript>
                </div>

    <!--  Initializing the UI -->
    <script type="text/javascript">
        //<![CDATA[
            if (!window.vaadin)
                alert("Failed to load the bootstrap JavaScript:" + "VAADIN/vaadinBootstrap.js");

            /* The UI Configuration */
            vaadin.initApplication("content-body", {
              "browserDetailsUrl": "VAADIN",
              "serviceUrl": "VAADIN",
              "widgetset": "com.vaadin.DefaultWidgetSet",
              "theme": "reindeer",
              "versionInfo": {"vaadinVersion": "7.0.5"},
              "vaadinDir": "VAADIN/",
              "heartbeatInterval": 300,
              "debug": true,
              "standalone": false,
              "authErrMsg": {
                  "message": "Take note of any unsaved data, "+
                             "and <u>click here<\/u> to continue.",
                  "caption": "Authentication problem"
              },
              "comErrMsg": {
                  "message": "Take note of any unsaved data, "+
                             "and <u>click here<\/u> to continue.",
                  "caption": "Communication problem"
              },
              "sessExpMsg": {
                  "message": "Take note of any unsaved data, "+
                             "and <u>click here<\/u> to continue.",
                  "caption": "Session Expired"
              }
         });//]]>
        </script>

</body>

My result is: Hello Unknown.

If I do not use Embedding UI mode than everything is working very well.

Where is the problem?


The solution (thank you for Leif Åstrand):

var urlParts = window.location.href.split("?");

var queryString = (urlParts.length == 1) ? "" : "?" + urlParts[1];

queryString = (urlParts.length == 0) ? "" : queryString.split("#")[0];

and

"browserDetailsUrl": "VAADIN" + queryString,

Full source code:

    <!--  Initializing the UI -->
    <script type="text/javascript">
        var urlParts = window.location.href.split("?");
        var queryString = (urlParts.length == 1) ? "" : "?" + urlParts[1];
        queryString = (urlParts.length == 0) ? "" : queryString.split("#")[0];

        //<![CDATA[
            if (!window.vaadin)
                alert("Failed to load the bootstrap JavaScript:" + "VAADIN/vaadinBootstrap.js");

            /* The UI Configuration */
            vaadin.initApplication("content-body", {
              "browserDetailsUrl": "VAADIN" + queryString,
              "serviceUrl": "VAADIN",
                          ...

Answer

Leif &#197;strand picture Leif Åstrand · May 13, 2013

The reason for this behavior is that UI.init is invoked from a request that is not always made to the same URL that was used to load the application. This is especially the case when embedding the UI instead of serving it as a standalone application.

The UI init request (named "browser details request" in some parts of the code) is by default sent to the same URL that was used to load the page. This does obviously not work when embedding as there is not Vaadin servlet mapped to that URL, so instead you have to define a browserDetailsUrl to to tell where the request should be sent.

v-loc that you observe is internally used to initialize the value returned by Page.getLocation().

To solve your particular problem, I would suggest one of these options:

  1. Dyncamically generate browserDetailsUrl to include the desired parameter as a query parameter, e.g. "browserDetailsUrl": "VAADIN?code=erefdvdfgftf".
  2. Extract the value from Page.getLocation().getQuery(). This is slightly less ugly than using the v-loc that you discovered as it doesn't rely on any implementation details.