New add-on - JSP/Struts2 integration

Hello everyone,

I’ve just uploaded a new Vaadin add-on:
JSP Integration
. It’s basically a tag library for JSP views that allows you to easily render a VaadinUI in a JSP file:

[code]
<%@taglib prefix=“vaadin” uri=“/vaadin” %>

<vaadin:ui url=“/myui”/>
[/code]I have developed two examples using Struts2 with JSP-based views:
struts2-vaadin-example
and
appfuse-vaadin-example
.

We’ll have a
webinar
related to this, in case you are interested.

Hope you find it usefull. Feedback is welcome!

Hi Alejandro,
very nice. With your addon you get rid of rather ugly javascript includes as described within the vaadin-book.
There is however one minor point with your pom: the versions of the servlet-api and jsp-api artifacts must be upgraded in order to avoid jsp-compilation error: “The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory” see:
https://stackoverflow.com/questions/7064269/the-method-getjspapplicationcontextservletcontext-is-undefined-for-the-type-js

Kind regards El Goog

Hi El Goog,

Thanks for the feedback! I wanted to use early versions for this kind of dependencies so that it’s compatible with existing JSP applications that may be using old versions of these libraries. But you made a good point. I forgot to use
provided
scope for those dependencies. I just uploaded a new version of the add-on (1.1). Thanks again!

Hi Alejandro,
Thanks for your fast reply! I combined your addon with the ExternalLayout addon. This is most valuable in cases where you have multiple places in the jsp, where you want to insert Vaadin components. In the end my UI contains a CssLayout, which itself contains only the Vaadin components to be inserted in the JSP. Very nice!
Again many thanks, El Goog

Hi Alejandro,
i have extended your tag by a further optional parameter ‘parameters’. When used, the value should contain an ampersand separated sequence of name=value pairs. The tag handler puts corresponding attributes into the HtmlSession. The started UI can fetch these attributes from the WrappedSession. This works fine.
My question: is there a better solution for passing parameters to the embedded UI? I want to replace applets in JSPs by a Vaadin UI and pass the applet parameters to the UI.

Hi,

I think your solution is good. Would you like to contribute it to the add-on?

Hi,

i have extended your tag with a further optional parameter ‘parmns’. If this parameter is given, it serves as a namespace for the attribute names given in the parameter ‘parameters’. Moreover it may be used to pass different sets of parameters in multiple calls of the same UI.

For example:

<vaadin:ui url="/vaadindialogs" theme="vaadindialogs" parmns="vaadin.dialogs.abc." parameters="x=y&z=1" /> will result in:

setAttribute("vaadin.dialogs.abc.x", "y"); setAttribute("vaadin.dialogs.abc.z", "1"); The tag description in the tld file is:

[code]

ui
org.vaadin.jsp.VaadinTagHandler
empty
Renders a Vaadin UI

<attribute>
    <name>url</name>
    <required>true</required>
    <rtexprvalue>false</rtexprvalue>
    <description>URL mapped to the Vaadin Servlet</description>
</attribute>

<attribute>
    <name>theme</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    <description>Vaadin theme name</description>
</attribute>

<attribute>
    <name>widgetset</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    <description>Widgetset name</description>
</attribute>

<attribute>
    <name>vaadindir</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    <description>Widgetset name</description>
</attribute>

<attribute>
    <name>parmns</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    <description>Namespace for the names within parameters, i.e. the Session-Attribute will be: parmns+name</description>
</attribute>

<attribute>
    <name>parameters</name>
    <required>false</required>
    <rtexprvalue>false</rtexprvalue>
    <description>name=value-Pairs separated by ampersand; each pair will be saved in HttpSession</description>
</attribute>
[/code]The VaadinTagHandler.java is changed to:

[code]
package org.vaadin.jsp;

import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.Version;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

/**

  • JSP tag handler implementation that constructs the HTML required to render a Vaadin UI.

  • @author Alejandro Duarte
    */
    public class VaadinTagHandler extends SimpleTagSupport {

    public static final String TEMPLATE_FILE_NAME = “template.html”;

    private String url;

    private String theme;

    private String widgetset;

    private String vaadindir;

    private String parameters;

    private String parmns;

    @Override
    public void doTag() {
    try {
    String template = getTemplate();
    String html = setVariables(template);
    passParametersIntoSession();
    getJspContext().getOut().write(html);

     } catch (IOException e) {
         throw new RuntimeException(e);
     }
    

    }

    private String getTemplate() {
    final InputStream inputStream = getClass().getClassLoader().getResourceAsStream(TEMPLATE_FILE_NAME);
    Scanner scanner = new Scanner(inputStream);
    StringBuilder stringBuilder = new StringBuilder();

     while (scanner.hasNextLine()) {
         String line = scanner.nextLine();
         stringBuilder.append(line).append("\n");
     }
    
     scanner.close();
    
     return stringBuilder.toString();
    

    }

    private String setVariables(String template) {
    PageContext pageContext = (PageContext) getJspContext();
    HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();

     String divId = url.substring(1).replaceAll("/", "-");
     String vaadinVersion = Version.getFullVersion();
     String context = request.getContextPath();
    
     return template
             .replace("${divId}", divId)
             .replace("${theme}", theme != null ? theme : "valo")
             .replace("${vaadinVersion}", vaadinVersion)
             .replace("${widgetset}", widgetset != null ? widgetset : VaadinServlet.DEFAULT_WIDGETSET)
             .replace("${vaadinDir}", vaadindir != null ? vaadindir : context + "/VAADIN/")
             .replace("${browserDetailsUrl}", context + url)
             .replace("${serviceUrl}", context + url);
    

    }

    public void setUrl(String url) {
    this.url = url;
    }

    public void setTheme(String theme) {
    this.theme = theme;
    }

    public void setWidgetset(String widgetset) {
    this.widgetset = widgetset;
    }

    public void setVaadindir(String vaadindir) {
    this.vaadindir = vaadindir;
    }

    public void setParameters(String parameters) {
    this.parameters = parameters;
    }

    public void setParmns(String parmns) {
    this.parmns = parmns;
    }

    private void passParametersIntoSession() {
    if (parameters != null && parameters.length() > 0) {
    PageContext pageContext = (PageContext) getJspContext();
    HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
    String params = parameters.split(“&”);
    if (params != null && params.length > 0) {
    // The callee should know the used value of parmns,
    // hence not passed to the HttpSession.
    // if (parmns != null && parmns.length() > 0) {
    // request.getSession().setAttribute(“parmns”, parmns);
    // }
    for (String param : params) {
    if (param != null && param.length() > 0) {
    String nameValuePair = param.split(“=”);
    if (nameValuePair != null && nameValuePair.length == 2 && nameValuePair[0]
    != null && nameValuePair[0]
    .length() > 0) {
    request.getSession().setAttribute((parmns != null ? parmns : “”) + nameValuePair[0]
    , nameValuePair[1]
    );
    }
    }

             }
         }
     }
    

    }
    }
    [/code]If you like, you may use this in future version of the Jsp-integration addon.
    Kind regards

Awesome, can you do a pull request on GitHub so that you get the credit for your contribution? :slight_smile: