07-May-2013 0.4.12
ReXSL, Quick Start Guide
For a super quick start use rexsl-maven-archetype and create your first project just like this:
mvn archetype:generate \ -DarchetypeGroupId=com.rexsl \ -DarchetypeArtifactId=rexsl-maven-archetype \ -DarchetypeVersion=0.4.12
To get better understanding of key components let's spend 5 minutes and create a project manually, step by step. Start with a new Maven project with the following directory structure (you can checkout a simple project):
/foo
pom.xml
/src
/main
/java
/foo
Home.java
FrontEnd.java
/webapp
/WEB-INF
web.xml
/xsl
layout.xsl
Home.xsl
/test
/java
/foo
HomeTest.java
/rexsl
/xhtml
index.groovy
/xml
index.xml
/scripts
RendersHomePage.groovy
/xsd
foo.Home.xsdMaven pom.xml should look like this:
<project>
[...]
<dependencies>
<dependency>
<!-- JAX-RS API -->
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<!-- JAXB 2.0 API -->
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<!-- ReXSL runtime library -->
<groupId>com.rexsl</groupId>
<artifactId>rexsl-core</artifactId>
<version>0.4.12</version>
<scope>runtime</scope>
</dependency>
<dependency>
<!-- ReXSL test harness -->
<groupId>com.rexsl</groupId>
<artifactId>rexsl-test</artifactId>
<version>0.4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<!-- Matchers for JUnit from http://code.google.com/p/hamcrest/ -->
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<!-- Unit testing framework from http://www.junit.org/ -->
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
[...]
<build>
<plugins>
<plugin>
<groupId>com.rexsl</groupId>
<artifactId>rexsl-maven-plugin</artifactId>
<version>0.4.12</version>
<executions>
<execution>
<goals>
<goal>check</goal>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>web.xml should be simple and include one servlet and one filter from ReXSL (it's Servlet API 3.0):
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/css/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/xsl/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>XsltFilter</filter-name>
<filter-class>com.rexsl.core.XsltFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XsltFilter</filter-name>
<servlet-name>RestfulServlet</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>RestfulServlet</servlet-name>
<servlet-class>com.rexsl.core.RestfulServlet</servlet-class>
<init-param>
<param-name>com.rexsl.PACKAGES</param-name>
<param-value>foo</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>RestfulServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<mime-mapping>
<extension>xsl</extension>
<mime-type>text/xsl</mime-type>
</mime-mapping>
</web-app>Now let's create JAX-RS front end (FrontEnd.java):
package foo;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/")
public class FrontEnd {
@GET
@Produces(MediaType.APPLICATION_XML)
public Home home() {
return new Home();
}
}And JAXB-annotated data class Home.java:
package foo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "page")
@XmlAccessorType(XmlAccessType.NONE)
public class Home {
@XmlElement
public String getText() {
return "Hello, world!";
}
}Now let's unit-test our data class in src/test/java/foo/HomeTest.java:
package foo;
import com.rexsl.test.JaxbConverter;
import com.rexsl.test.XhtmlMatchers;
import org.junit.Test;
public class HomeTest {
@Test
public void testXmlContents() {
Home home = new Home();
Assert.assertThat(
JaxbConverter.the(home),
XhtmlMatchers.hasXPath("/page/text[contains(.,'world')]")
);
}
}And now let's create a test XML document (src/test/rexsl/xml/index.xml):
<?xml version="1.0"?> <?xml-stylesheet href='/xsl/Home.xsl' type='text/xsl' ?> <page> <text>let's say hello!</text> </page>
This document will be XSL-transformed by rexsl-maven-plugin:check Maven goal and validated by src/test/rexsl/xhtml/index.groovy:
import com.rexsl.test.XhtmlMatchers
import org.hamcrest.Matchers
import org.junit.Assert
Assert.assertThat(rexsl.document, Matchers.containsString('say hello'))
Assert.assertThat(
rexsl.document,
XhtmlMatchers.hasXPath("//xhtml:div[contains(.,'say hello')]")
)And now the most interesting part, a test script in src/test/rexsl/scripts/RendersHomePage.groovy (rexsl.home is provided by rexsl-maven-plugin executor):
package foo
import com.rexsl.test.RestTester
import javax.ws.rs.core.HttpHeaders
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.UriBuilder
RestTester.start(rexsl.home)
.header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML)
.header(HttpHeaders.USER_AGENT, 'Safari')
.get('loading home page')
.assertStatus(HttpURLConnection.HTTP_OK)
.assertXPath("//xhtml:div[contains(.,'world')]")
RestTester.start(UriBuilder.fromUri(rexsl.home).path('/strange-address'))
.get('loading non-existing URL')
.assertStatus(HttpURLConnection.HTTP_NOT_FOUND)Now let's create src/main/webapp/xsl/layout.xsl:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
version="2.0" exclude-result-prefixes="xs xsl xhtml">
<xsl:output method="xhtml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" />
<xsl:template match="/">
<html xml:lang="en">
<body>
<div id="content">
<xsl:call-template name="content" />
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>And main page XSL at src/main/webapp/xsl/Home.xsl:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
version="2.0" exclude-result-prefixes="xs xsl xhtml">
<xsl:output method="xhtml"/>
<xsl:include href="/xsl/layout.xsl"/>
<xsl:template name="content">
<xsl:value-of select="/page/text" />
</xsl:template>
</xsl:stylesheet>The last step is to create src/test/rexsl/xsd/foo.Home.xsd in order to validate XML output on fly:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="page">
<xs:complexType>
<xs:all>
<xs:element name="text" type="xs:string" minOccurs="1" maxOccurs="1" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>That's it. All you have to do now is to run mvn package and deploy your WAR to production server.
To test the system on your local machine run mvn package rexsl:run -Drexsl.port=9099 and open http://localhost:9099 with your favorite browser.
What's especially cool is that you can can make changes to your webapp/* files and they will become available on-fly in web (without restart of the application). Just refresh the page in browser.
Copyright © 2011-2013 ReXSL.com, All Rights Reserved. Privacy Policy.