Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I generate html from Java object?

Tags:

java

html

I have a rest resource with a method that should return some data as html. We're talking about a list of Reports, which is a simple class consisting of 6 string member variables.

I am asking because the prospect of appending elements and values to a string seems slow and error prone, and I would really prefer to do it in an object oriented way.

like image 625
Marmoy Avatar asked Dec 20 '11 13:12

Marmoy


2 Answers

For simple HTML, generate it directly as text. The other suggestions of serializing, XML, and transformations are all overkill.

There are Java libraries to help with generating HTML, such as these:

  • jwebutils
    A library for creating HTML 5 markup using Java. It also contains support for creating JSON and CSS 3 markup.
  • Jakarta Element Construction Set (ECS)
    A Java API for generating elements for various markup languages it directly supports HTML 4.0 and XML. Now retired, but some folks really like it.

But if you learn the basics of valid HTML, you can write your own routines.

As for speed, the StringBuilder class was added for the purpose of faster string manipulation. The tradeoff is no synchronization. That means not thread-safe. Depending on how your program is structured, you might use synchronization around the outside of the code doing the HTML rendering.

Here is an example class I just cooked up in Java 6, and a little app to run it. This code is just a proof of concept, not ready for prime time production.

package com.example;

/**
 * @author Basil Bourque
 *         © 2012 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
 */
public class ListToHtmlTransformer {

    /**
     * @param collection
     *            of report titles.
     * @return string containing source code for HTML5.
     */
    public String render( java.util.Collection< String > reports ) {
        // This source code is not yet tested or made bullet-proof. Only meant for demonstrating concepts.
        // Warning: This code is not thread-safe. Changes must be made before serious use.
        // Warning: This code should be modified to produce proper HTML, such as escaping certain characters.
        // This code generates minimal HTML5 as suggested here: http://www.brucelawson.co.uk/2010/a-minimal-html5-document/
        // Big tip: Note that HTML allows the use of apostrophe (single-quote) in place of double-quote. Mixes better with Java source code.
        // The backslash + 'n' is an escape sequence in Java to generate a linefeed (Ascii/Unicode 10) for use here as a NewLine.
        // In real life, you woud test your rendered HTML with an HTML validator such as:
        // • http://html5.validator.nu/
        // • http://validator.w3.org/
        StringBuilder html = new StringBuilder();
        html.append( "<!doctype html>\n" );
        html.append( "<html lang='en'>\n" );

        html.append( "<head>\n" );
        html.append( "<meta charset='utf-8'>\n" );
        html.append( "<title>Report of Reports</title>\n" );
        html.append( "</head>\n\n" );

        html.append( "<body>\n" );
        html.append( "<h1>List of Reports</h1>\n" );
        // Make a list in HTML
        html.append( "<ul>\n" );
        // Loop the list of reports passed as argument.
        for ( String report : reports ) {
            html.append( "<li>" + report + "</li>\n" );
        }
        html.append( "</ul>\n" );
        html.append( "</body>\n\n" );

        html.append( "</html>" );

        return html.toString();
    }

}

And an app to run it.

package com.example;

import java.util.ArrayList;

/**
 * 
 * @author Basil Bourque
 *         © 2012 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
 */
public class App {

    /**
     * @param args
     */
    public static void main( String[] args ) {
        ArrayList< String > listOfReports = new ArrayList< String >();
        listOfReports.add( "Some report #1" );
        listOfReports.add( "Some report #2" );
        listOfReports.add( "Some report #3" );
        listOfReports.add( "Some report #4" );
        listOfReports.add( "Some report #5" );
        listOfReports.add( "Some report #6" );

        ListToHtmlTransformer renderer = new ListToHtmlTransformer();
        String renderedHtml = renderer.render( listOfReports );

        System.out.println( "The following HTML was rendered: " + new java.util.Date().toString() );
        System.out.println( renderedHtml );
        System.out.println( "*** End of HTML ***" );
    }

}

I tried to post the rendered HTML here, but StackOverflow tried to interpret it as HTML rather than display it.

Bonus tip: You can use single-quote (APOSTROPHE Unicode 39) rather than double-quote (QUOTATION MARK Unicode 34) in your HTML & CSS for delimiting attribute values and such. Browsers handle both well. The single-quote makes coding so much easier in your Java code, eliminating the need to escape the double-quote marks. Notice my usage in code above, such as the 'en' and 'utf-8'.

like image 170
Basil Bourque Avatar answered Sep 18 '22 18:09

Basil Bourque


The normal way of generating HTML for a web response is to use a JSP or a Java templating engine like Velocity or FreeMarker.

If you are currently returning responses as XML, another approach would be to use XSLT to transform the XML to HTML. The XSLT processing can be done on the client side (in the browser) if you include an appropriate "processing" instruction in the XML that links to the XSLT resource.


I used to think that bashing strings together was a reasonable solution, but then I came to realize that that results in you hard-wiring your HTML layout into your Java code. The JSP, templating and transformation approaches all avoid this, allowing you to adjust the generated HTML later in the development cycle; e.g. at system integration time, or even post deployment.

like image 38
Stephen C Avatar answered Sep 20 '22 18:09

Stephen C