Note: if you are happy with JAX-RS (JSR311) you probably don't need this library
Thin library over servlet API, eases request dispatching with regular expressions. Uses extended regular expression library with named groups support (for JDK6) to create clean URLs.
Library depends on named-regexp.
Javadocs for the latest release are available here.
Maven dependency (available in central repository):
<dependency>
<groupId>com.alexkasko.rest</groupId>
<artifactId>rest-handlers</artifactId>
<version>1.1</version>
</dependency>
Request processing is split between transport-level (TransportHandler
) and application level (RestHandler
) classes.
Transport handlers may be singletones, one for each transport type. They take all input parameters from servlet, additional
parameters from URL matching (e.g. id
for GET
requests) and RestHandler
class. Rest handler instance
may be instantiated or obtained from some kind of DI.
JSON TransportHandler
example:
public class JsonTransportHandler implements TransportHandler<JsonHandler> {
// may be preconfigured
private static final Gson gson = new Gson();
public void handle(Class<? extends JsonHandler> handlerClass, HttpServletRequest request,
HttpServletResponse response, Map<String, String> urlParams) throws Exception {
// set proper content-type
response.setContentType("application/json");
// obtain handler instance, may be singleton, from DI etc
JsonHandler ha = handlerClass.newInstance();
// parse input object from request body
Object in = gson.fromJson(request.getReader(), ha.inputClass());
// fire handler
Object out = ha.handle(in);
// write results to client
gson.toJson(out, response.getWriter());
}
}
Application RestHandler
example (may have any methods definition, only called from its TransportHandler
):
public class JsonHandler implements RestHandler {
// sends text message back untouched (any application logic here)
public OutputMessage handle(InputMessage input) {
return new OutputMessage(input.getText());
}
// inpup message class to be instantiated by transport handler
public Class<InputMessage> inputClass() {
return InputMessage.class;
}
}
Setup example (web.xml):
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>com.alexkasko.rest.handlers.HandlersDispatcherServlet</servlet-class>
<init-param>
<param-name>dispatcherKeyInServletContext</param-name>
<param-value>dispatcher</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>com.myapp.InitListener</listener-class>
</listener>
Dispather init from servlet listener:
// create dispatcher instance with some handlers
HandlersDispatcher dispatcher = HandlersDispatcher.builder()
.addGet("^/status/jobid/(?<jobid>\\d+)$", new MyTransportHandler(), JobStatusHandler.class)
.addPost("^/echo$", new JsonTransportHandler(), EchoHandler.class)
.build();
// add dispatcher to servlet context so dispatcherServlet will be able to access it
sce.getServletContext().setAttribute("dispatcher", dispatcher);
Call with curl:
curl http://127.0.0.1:8080/rest/status/jobid/42
Url parameter matched with (?<jobid>\\d+)
will be provided to handler as Map<String, String>
- jobid:42
Working example with JSON may be found here, example javadocs.
HandlersDispatcher
- regexp-based dispatcher,GET
,POST
andPUT
requests are registered separatelyHandlersDispatcherServlet
- servlet, delegate all work to dispatcher (gets it fromServletContext
bydispatcherKeyInServletContext
key)TransportHandler
- transport part of request handler, implementation should get nessessary parameters from requests and delegates processing to application level handler (with clean method definitions, from DI with decalarative transactions etc)RestHandler
- application level marker-interface for calling fromTransportHandler
NotFoundHandler
- will be called if no other handlers matchedDefaultNotFoundHandler
- default implementation, returns404
with available handlers listExceptionHandler
- will be called on exception during requst processingDefaultExceptionHandler
- default implementation, returns500
with stacktrace
This project is released under the Apache License 2.0
1.2.1 (2015-04-01)
- HEAD support
1.2 (2015-03-30)
- DELETE support
1.1 (2013-11-20)
- sub-dispatchers (submappings) support
1.0.2 (2013-07-14)
- dispatcher building composition support
1.0.1 (2013-05-22)
- formatting of list of all available handlers on missed request
1.0 (2012-11-13)
- initial version