Skip to content

Instantly share code, notes, and snippets.

@jcfrank
Last active February 26, 2021 13:14
Show Gist options
  • Save jcfrank/9a65add958b46d8e53aa to your computer and use it in GitHub Desktop.
Save jcfrank/9a65add958b46d8e53aa to your computer and use it in GitHub Desktop.
A basic Jersey 2 mvc sample with Mustache.

Jersey 2 MVC

Jersey 2 also supports server-side template rendering.
This is a simple mustache sample.

Gradle

build.gradle
Add jerset mvc dependencies.

...
dependencies {
    compile 'org.slf4j:slf4j-api:1.7.7',
            'ch.qos.logback:logback-classic:1.1.2',
            'ch.qos.logback:logback-core:1.1.2',
            'javax.ws.rs:javax.ws.rs-api:2.0.1',
            'org.glassfish.jersey.core:jersey-common:2.13',
            'org.glassfish.jersey.core:jersey-server:2.13',
            'org.glassfish.jersey.containers:jersey-container-servlet:2.13',
            'org.glassfish.jersey.ext:jersey-mvc:2.13',
            'org.glassfish.jersey.ext:jersey-mvc-mustache:2.13',
            'org.glassfish.jersey.media:jersey-media-json-jackson:2.13',
            'org.glassfish.jersey.media:jersey-media-json-processing:2.13'
}
...

ResourceConfig

Here we setup template path, absolute path like /templates means ${CLASSPATH}/templates.
Relative path like templates/view means it would look in the path relative to package path, ex. ${CLASSPATH}/my/app/resource/templates/view.

package my.app.config;

...

public class ViewApplication extends ResourceConfig {
  public ViewApplication() {
    property(MustacheMvcFeature.TEMPLATE_BASE_PATH, "/templates");
    register(MustacheMvcFeature.class);
    packages("my.app.resource");
  }
}

web.xml

Nothing special here.

...
    <servlet>
        <servlet-name>my.app.config.ViewApplication</servlet-name>
    </servlet>
    <servlet-mapping>
        <servlet-name>my.app.config.ViewApplication</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
...

View

src/main/resources/templates/view.mustache

<!DOCTYPE html>
<html>
<head>
    <title>View Page</title>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <div class="page-header">
            <h1>{{title}}</h1>
        </div>
        <div class="well">
            <ol class="list-group">
                {{#os}}
                    <li class="list-group-item">{{name}}</li>
                    <p><small>vendor:  {{vendor}}, version: {{version}}</small></p>
                {{/os}}
            </ol>
        </div>
    </div>
</body>
</html>

Resources

For sample purpose, return some static data.

@Path("/view")
public class ViewResource {

  @GET
  @Produces(MediaType.TEXT_HTML)
  @Template(name = "/view")
  public Map<String, Object> getView() {
    Map<String, Object> model = new HashMap<String, Object>();
    model.put("title", "OS");
    Set<OsInfo> oses = new HashSet<OsInfo>();
    OsInfo i = new OsInfo();
    i.name = "iOS";
    i.vendor = "Apple";
    i.version = 8;
    oses.add(i);
    i = new OsInfo();
    i.name = "Android";
    i.vendor = "Google";
    i.version = 5;
    oses.add(i);
    i = new OsInfo();
    i.name = "WindowsPhone";
    i.vendor = "MicroSoft";
    i.version = 9;
    oses.add(i);
    model.put("os", oses);
    return model;
  }
}

Where OsInfo defined like:

@XmlRootElement
public class OsInfo {
  public String name, vendor;
  public Integer version;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment