public static String postLaunchHTML(
            final Map<String, String> cleanProperties, String endpoint, boolean debug) {
        if (cleanProperties == null || cleanProperties.isEmpty()) {
            throw new IllegalArgumentException(
                    "cleanProperties == null || cleanProperties.isEmpty()");
        }
        if (endpoint == null) {
            throw new IllegalArgumentException("endpoint == null");
        }
        Map<String, String> newMap = null;
        if (debug) {
            // sort the properties for readability
            newMap = new TreeMap<String, String>(cleanProperties);
        } else {
            newMap = cleanProperties;
        }
        StringBuilder text = new StringBuilder();
        // paint form
        text.append("<div id=\"ltiLaunchFormSubmitArea\">\n");
        text.append("<form action=\"");
        text.append(endpoint);
        text.append("\" name=\"ltiLaunchForm\" id=\"ltiLaunchForm\" method=\"post\" ");
        text.append(" encType=\"application/x-www-form-urlencoded\" accept-charset=\"utf-8\">\n");
        for (Entry<String, String> entry : newMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (value == null) {
                continue;
            }
            // This will escape the contents pretty much - at least
            // we will be safe and not generate dangerous HTML
            key = htmlspecialchars(key);
            value = htmlspecialchars(value);
            if (key.equals(BASICLTI_SUBMIT)) {
                text.append("<input type=\"submit\" name=\"");
            } else {
                text.append("<input type=\"hidden\" name=\"");
            }
            text.append(key);
            text.append("\" value=\"");
            text.append(value);
            text.append("\"/>\n");
        }
        text.append("</form>\n");
        text.append("</div>\n");

        // Paint the auto-pop up if we are transitioning from https: to http:
        // and are not already the top frame...
        text.append("<script type=\"text/javascript\">\n");
        text.append("if (window.top!=window.self) {\n");
        text.append("  theform = document.getElementById('ltiLaunchForm');\n");
        text.append("  if ( theform && theform.action ) {\n");
        text.append("   formAction = theform.action;\n");
        text.append("   ourUrl = window.location.href;\n");
        text.append("   if ( formAction.indexOf('http://') == 0 && ourUrl.indexOf('https://') == 0 ) {\n");
        text.append("      theform.target = '_blank';\n");
        text.append("      window.console && console.log('Launching http from https in new window!');\n");
        text.append("    }\n");
        text.append("  }\n");
        text.append("}\n");
        text.append("</script>\n");

        // paint debug output
        if (debug) {
            text.append("<pre>\n");
            text.append("<b>BasicLTI Endpoint</b>\n");
            text.append(endpoint);
            text.append("\n\n");
            text.append("<b>BasicLTI Parameters:</b>\n");
            for (Entry<String, String> entry : newMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (value == null) {
                    continue;
                }
                text.append(htmlspecialchars(key));
                text.append("=");
                text.append(htmlspecialchars(value));
                text.append("\n");
            }
            text.append("</pre>\n");
        } else {
            // paint auto submit script
            text
                    .append(" <script language=\"javascript\"> \n"
                            + "	document.getElementById(\"ltiLaunchFormSubmitArea\").style.display = \"none\";\n"
                            + "	nei = document.createElement('input');\n"
                            + "	nei.setAttribute('type', 'hidden');\n"
                            + "	nei.setAttribute('name', '"
                            + BASICLTI_SUBMIT
                            + "');\n"
                            + "	nei.setAttribute('value', '"
                            + newMap.get(BASICLTI_SUBMIT)
                            + "');\n"
                            + "	document.getElementById(\"ltiLaunchForm\").appendChild(nei);\n"
                            + "	document.ltiLaunchForm.submit(); \n" + " </script> \n");
        }

        String htmltext = text.toString();
        return htmltext;
    }
public static String postLaunchHTML(
            final Map<String, String> cleanProperties, String endpoint, boolean debug) {
        if (cleanProperties == null || cleanProperties.isEmpty()) {
            throw new IllegalArgumentException(
                    "cleanProperties == null || cleanProperties.isEmpty()");
        }
        if (endpoint == null) {
            throw new IllegalArgumentException("endpoint == null");
        }
        Map<String, String> newMap = null;
        if (debug) {
            
            newMap = new TreeMap<String, String>(cleanProperties);
        } else {
            newMap = cleanProperties;
        }
        StringBuilder text = new StringBuilder();
        
        text.append("<div id=\"ltiLaunchFormSubmitArea\">\n");
        text.append("<form action=\"");
        text.append(endpoint);
        text.append("\" name=\"ltiLaunchForm\" id=\"ltiLaunchForm\" method=\"post\" ");
        text.append(" encType=\"application/x-www-form-urlencoded\" accept-charset=\"utf-8\">\n");
        for (Entry<String, String> entry : newMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (value == null) {
                continue;
            }
            
            
            key = htmlspecialchars(key);
            value = htmlspecialchars(value);
            if (key.equals(BASICLTI_SUBMIT)) {
                text.append("<input type=\"submit\" name=\"");
            } else {
                text.append("<input type=\"hidden\" name=\"");
            }
            text.append(key);
            text.append("\" value=\"");
            text.append(value);
            text.append("\"/>\n");
        }
        text.append("</form>\n");
        text.append("</div>\n");

        
        
        text.append("<script type=\"text/javascript\">\n");
        text.append("if (window.top!=window.self) {\n");
        text.append("  theform = document.getElementById('ltiLaunchForm');\n");
        text.append("  if ( theform && theform.action ) {\n");
        text.append("   formAction = theform.action;\n");
        text.append("   ourUrl = window.location.href;\n");
        text.append("   if ( formAction.indexOf('http:
        text.append("      theform.target = '_blank';\n");
        text.append("      window.console && console.log('Launching http from https in new window!');\n");
        text.append("    }\n");
        text.append("  }\n");
        text.append("}\n");
        text.append("</script>\n");

        
        if (debug) {
            text.append("<pre>\n");
            text.append("<b>BasicLTI Endpoint</b>\n");
            text.append(endpoint);
            text.append("\n\n");
            text.append("<b>BasicLTI Parameters:</b>\n");
            for (Entry<String, String> entry : newMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (value == null) {
                    continue;
                }
                text.append(htmlspecialchars(key));
                text.append("=");
                text.append(htmlspecialchars(value));
                text.append("\n");
            }
            text.append("</pre>\n");
        } else {
            
            text
                    .append(" <script language=\"javascript\"> \n"
                            + "	document.getElementById(\"ltiLaunchFormSubmitArea\").style.display = \"none\";\n"
                            + "	nei = document.createElement('input');\n"
                            + "	nei.setAttribute('type', 'hidden');\n"
                            + "	nei.setAttribute('name', '"
                            + BASICLTI_SUBMIT
                            + "');\n"
                            + "	nei.setAttribute('value', '"
                            + newMap.get(BASICLTI_SUBMIT)
                            + "');\n"
                            + "	document.getElementById(\"ltiLaunchForm\").appendChild(nei);\n"
                            + "	document.ltiLaunchForm.submit(); \n" + " </script> \n");
        }

        String htmltext = text.toString();
        return htmltext;
    }
public static String postLaunchHTML ( final Map < String , String > cleanProperties , String endpoint , boolean debug ) { if ( cleanProperties == null || cleanProperties . isEmpty ( ) ) { throw new IllegalArgumentException ( "cleanProperties == null || cleanProperties.isEmpty()" ) ; } if ( endpoint == null ) { throw new IllegalArgumentException ( "endpoint == null" ) ; } Map < String , String > newMap = null ; if ( debug ) { // sort the properties for readability newMap = new TreeMap < String , String > ( cleanProperties ) ; } else { newMap = cleanProperties ; } StringBuilder text = new StringBuilder ( ) ; // paint form text . append ( "<div id=\"ltiLaunchFormSubmitArea\">\n" ) ; text . append ( "<form action=\"" ) ; text . append ( endpoint ) ; text . append ( "\" name=\"ltiLaunchForm\" id=\"ltiLaunchForm\" method=\"post\" " ) ; text . append ( " encType=\"application/x-www-form-urlencoded\" accept-charset=\"utf-8\">\n" ) ; for ( Entry < String , String > entry : newMap . entrySet ( ) ) { String key = entry . getKey ( ) ; String value = entry . getValue ( ) ; if ( value == null ) { continue ; } // This will escape the contents pretty much - at least // we will be safe and not generate dangerous HTML key = htmlspecialchars ( key ) ; value = htmlspecialchars ( value ) ; if ( key . equals ( BASICLTI_SUBMIT ) ) { text . append ( "<input type=\"submit\" name=\"" ) ; } else { text . append ( "<input type=\"hidden\" name=\"" ) ; } text . append ( key ) ; text . append ( "\" value=\"" ) ; text . append ( value ) ; text . append ( "\"/>\n" ) ; } text . append ( "</form>\n" ) ; text . append ( "</div>\n" ) ; // Paint the auto-pop up if we are transitioning from https: to http: // and are not already the top frame... text . append ( "<script type=\"text/javascript\">\n" ) ; text . append ( "if (window.top!=window.self) {\n" ) ; text . append ( "  theform = document.getElementById('ltiLaunchForm');\n" ) ; text . append ( "  if ( theform && theform.action ) {\n" ) ; text . append ( "   formAction = theform.action;\n" ) ; text . append ( "   ourUrl = window.location.href;\n" ) ; text . append ( "   if ( formAction.indexOf('http://') == 0 && ourUrl.indexOf('https://') == 0 ) {\n" ) ; text . append ( "      theform.target = '_blank';\n" ) ; text . append ( "      window.console && console.log('Launching http from https in new window!');\n" ) ; text . append ( "    }\n" ) ; text . append ( "  }\n" ) ; text . append ( "}\n" ) ; text . append ( "</script>\n" ) ; // paint debug output if ( debug ) { text . append ( "<pre>\n" ) ; text . append ( "<b>BasicLTI Endpoint</b>\n" ) ; text . append ( endpoint ) ; text . append ( "\n\n" ) ; text . append ( "<b>BasicLTI Parameters:</b>\n" ) ; for ( Entry < String , String > entry : newMap . entrySet ( ) ) { String key = entry . getKey ( ) ; String value = entry . getValue ( ) ; if ( value == null ) { continue ; } text . append ( htmlspecialchars ( key ) ) ; text . append ( "=" ) ; text . append ( htmlspecialchars ( value ) ) ; text . append ( "\n" ) ; } text . append ( "</pre>\n" ) ; } else { // paint auto submit script text . append ( " <script language=\"javascript\"> \n" + "	document.getElementById(\"ltiLaunchFormSubmitArea\").style.display = \"none\";\n" + "	nei = document.createElement('input');\n" + "	nei.setAttribute('type', 'hidden');\n" + "	nei.setAttribute('name', '" + BASICLTI_SUBMIT + "');\n" + "	nei.setAttribute('value', '" + newMap . get ( BASICLTI_SUBMIT ) + "');\n" + "	document.getElementById(\"ltiLaunchForm\").appendChild(nei);\n" + "	document.ltiLaunchForm.submit(); \n" + " </script> \n" ) ; } String htmltext = text . toString ( ) ; return htmltext ; }
Create the HTML to render a POST form and then automatically submit it.
Make sure to call {@link #cleanupProperties(Properties)} before signing.

@param cleanProperties Assumes you have called
{@link #cleanupProperties(Properties)} beforehand.
@param endpoint The LTI launch url.
@param debug Useful for viewing the HTML before posting to end point.
@return the HTML ready for IFRAME src = inclusion.
Create the HTML to render a POST form and then automatically submit it . Make sure to call { @link #cleanupProperties ( Properties ) } before signing .