Embedded servlet containers abstraction
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Paweł Płazieński 52ba9f4248 Bump version to snapshot 2.0.1 11 months ago
webable-api Bump version to snapshot 2.0.1 11 months ago
webable-handler Bump version to snapshot 2.0.1 11 months ago
webable-jetty Bump version to snapshot 2.0.1 11 months ago
webable-tomcat Bump version to snapshot 2.0.1 11 months ago
webable-undertow Bump version to snapshot 2.0.1 11 months ago
.gitignore Add gitignore 4 years ago
LICENSE.md Add license 4 years ago
README.md Add readme 2 years ago
pom.xml Bump version to snapshot 2.0.1 11 months ago

README.md

Webable

Abstraction over embedding servlet containers.

Introduction

Webable offers easy programmatic creation of embedded servlet containers, such as Tomcat or Jetty, with unified, builder-like API.

Webable also offers optional “handler” configuration, which is its own API on top of servlets/filters, which allows easier and more functional approach to HTTP request handling.

Supported containers:

Including as dependency

Add dependencies in your pom.xml:

<dependency>
    <groupId>org.perfectable</groupId>
    <artifactId>webable-api</artifactId>
    <version>${webable.version}</version>
</dependency>
<dependency>
    <groupId>org.perfectable</groupId>
    <artifactId>webable-tomcat</artifactId>
    <version>${webable.version}</version>
    <scope>runtime</scope>
</dependency>

Replace webable-tomcat with webable-jetty or webable-undertow if you need other container.

Note: you need to have actual container library in runtime scope only.

If you want to use functional request handlers, add also:

<dependency>
    <groupId>org.perfectable</groupId>
    <artifactId>webable-handler</artifactId>
    <version>${webable.version}</version>
</dependency>

Use example

Plain servlet-based webapplication:

WebApplication.begin()
    .withPort(8000)
    .withContextParameter("applicationUrl", "http://example.org/")
    .withForcedSessionCreation()
    .withHttpSessionListener(InjectContextListener.INSTANCE)
    .withWebsocketEndpoint(ServerEndpointConfig.Builder.create(WebsocketEndpoint.class, "/ws").build())
    .withFilter(BasicAuthenticationFilter.create(userNameResolver))
        .named("basicAuth")
        .mappedTo("/*")
        .endFilter()
    .withServlet(EntryServlet.class)
        .initialParameter("performer", userName)
        .mappedTo("/")
        .loadedInitially()
        .endServlet()
    .serveBlocking();

Functional request-handlers:

ResourceResolver scriptsResolver = path ->
    StreamResourceLoader.classpathFromPath(path).as(MediaType.JAVASCRIPT_UTF_8);
RequestHandler rootHandler = request -> HttpResponse.status(HttpStatus.FOUND)
        .withHeader("Location", "/").withPlainTextContent("Hello " + request.completePath())
WebApplication.begin()
    .withPort("10.0.0.1", 80)
    .extend(HandlerServerConfigurationExtension.INSTANCE.adjustType())
    .withGlobalChannel(BasicAuthenticationRequestChannel.of(authenticator))
    .withResources("/scripts/*", scriptsResolver)
    .withResponse("", HttpResponse.OK.withResourceContent(MediaType.XHTML_UTF_8, "index.html"))
    .withRootHandler(rootHandler)
    .serveBlocking();