Search code examples
javahtmlcsstwitter-bootstraprestlet

Can use xml/css/json in Restlet Java SE?


I am completely newbie for java & restlet. I am using eclipse LUNA Java SE. I try to use html/css/xml/bootstrap etc. in my web application. I searched around and all examples which I can find is based on Java EE. so I am wondering that I should use Java EE instead of Java SE if I want to use html(files)/css/xml/bootstrap/json etc.. to contain more rich contexts in my web service. I did read Restlet user guide/tutorials in their homepage, even go through the book, Restlet in Action. but I can't find any answers myself. Maybe there is answers in those materials but I haven't figured it out. so, In java SE restlet, for now, I am doing hardcoding html in my java code... but that is not enough.

This is probably very basic to the others. but please understand, this also can be confused to the beginners. Examples will be very helpful. thx.


Solution

  • Don't worry! There is no silly question ;-)

    Sure, you can use Restlet with only JavaSE for the server side. You can define a Restlet server within a standalone Java application. This can be done using the class Component. After having instantiated it, you can add a server to it. Following code describes this:

    public static void main(String[] args) {
        Component component = new Component();
        component.getServers().add(Protocol.HTTP, 8080);
        (...)
        component.start();
    }
    

    Before starting the component, you can attach your Restlet application on it, as described below:

    component.getDefaultHost().attach(new SampleApplication());
    

    A Restlet application corresponds to à class that extends the class Application. The next step consists in overriding the method createInboundRoot. This method defines the REST routes of your application. Following code describes the skelekon of a Restlet application:

    public class SampleApplication extends Application {
        @Override
        public Restlet createInboundRoot() {
            Router router = new Router(getContext());
    
            router.attach("/myresource", MyServerResource.class);
    
            (...)
    
            return router;
        }
    }
    

    Since you want to serve static files (JS, CSS, ...), you can leverage the class Directory. It allows to attach automatically and recursively all folders and files within a root folder to a path. This can be configured as described below:

    String rootUri = "file:///(...)/static-content";
    Directory directory = new Directory(getContext(), rootUri);
    directory.setListingAllowed(true);
    router.attach("/static/", directory);
    

    Let's focus now on the server resources. We can distinguish two kinds for your case:

    • the ones that exchange structured data and use POJOs wwith their annotation methods (Get, Post, ...)
    • the ones that manage representations directly or based on Restlet extensions

    For the first ones, you can refer this answer on stackoverflow.

    The second ones allow to use template engines to generate content to send back to the client. This is something similar to JSPs in JavaEE. We can take the sample of Freemarker (http://freemarker.org/) and its corresponding Restlet extension.

    First we need to configure the Freemarker engine within the Restlet application, mainly the root directory where to find out the templates, as described below:

    public class SampleApplication extends Application {
        (...)
        private Configuration configuration;
    
        public static Configuration configureFreeMarker(Context context) {
            Configuration configuration = new Configuration();
            ClassTemplateLoader loader = new ClassTemplateLoader(
                SampleAppApplication.class,
                "/org/myapp/sample/server/templates/");
            configuration.setTemplateLoader(loader);
            // configuration.setCacheStorage(new StrongCacheStorage());
            return configuration;
        }
    
        public Configuration getConfiguration() {
            return configuration;
        }
    }
    

    You can then create Freemarker representations to leverage such templates to generate the output content (dynamic content generated on the server side), as described below:

    private SampleApplication getSampleApplication() {
        return (SampleApplication)getApplication();
    }
    
    private Representation toRepresentation(Map<String, Object> map,
        String templateName, MediaType mediaType) {
        return new TemplateRepresentation(templateName,
            getSampleApplication().getConfiguration(), map, mediaType);
    }
    
    @Get("html")
    public Representation getHtml() {
        Map<String, Object> model = new HashMap<String, Object>();
    
        model.put("titre", "my title");
        model.put("users", getUsers());
    
        return toRepresentation(model,
            "myTemplate", MediaType.TEXT_HTML);
    }
    

    Here is the content of the template myTemplate.

    <html>
        <head>
            <title>${title}</title>
        </head>
        <body>
        Users:<br/><br/>
        <ul>
            <#list users as user>
            <li>${user.lastName} ${user.firstName}</li>
            </#list>
        </ul>
        </body>
    </html>
    

    Hope it helps. Thierry