Package net.morimekta.providence.server
Class ProvidenceHttpServlet<RQ extends net.morimekta.providence.PMessage<RQ,RQF>,RQF extends net.morimekta.providence.descriptor.PField,RS extends net.morimekta.providence.PMessage<RS,RSF>,RSF extends net.morimekta.providence.descriptor.PField>
- java.lang.Object
-
- javax.servlet.GenericServlet
-
- javax.servlet.http.HttpServlet
-
- net.morimekta.providence.server.ProvidenceHttpServlet<RQ,RQF,RS,RSF>
-
- Type Parameters:
RQ- The request type.RQF- The request field type.RS- The response type.RSF- The response field type.
- All Implemented Interfaces:
java.io.Serializable,javax.servlet.Servlet,javax.servlet.ServletConfig
public abstract class ProvidenceHttpServlet<RQ extends net.morimekta.providence.PMessage<RQ,RQF>,RQF extends net.morimekta.providence.descriptor.PField,RS extends net.morimekta.providence.PMessage<RS,RSF>,RSF extends net.morimekta.providence.descriptor.PField> extends javax.servlet.http.HttpServletA simple HTTP POST servlet wrapper that deserializes the POST body as a providence message, and serializes the response message using the requested content type or accept type.Note that the
ProvidenceHttpServletis NOT usable for thrift services, but is meant to be used to make simple POST based HTTP servlets.
This will result in a simple HTTP servlet that can be queries with CURL e.g. like this:public class MyServlet extends ProvidenceHttpServlet< MyRequest, MyRequest._Field, MyResponse, MyResponse._Field> { {@literal@}Override protected MyResponse handle(HttpServletRequest httpRequest, MyRequest request) throws MyException, InternalFailureException { // ... do stuff with request, or throw MyException or IFE. return MyResponse.builder() .setFieldOut("yes") .build(); } {@literal@}Override protected int statusCodeForException({@literal@}Nonnull Throwable exception) { if (exception instanceof MyException) { return HttpStatus.BAD_REQUEST_400; } return super.statusCodeForException(ex); } }
Alternatively you can hijack the whole exception / error response handling, which might be needed where custom headers etc are needed, e.g. with# Simple success $ curl -sS -X POST -d "{\"field_in\": \"value\"}" \ > -H "Content-Type: application/json" \ > localhost:8080/my/servlet {\"field_out\":\"yes\"} # Simple Error $ curl -sSv -X POST -d "{\"field_in\": \"not valid\"}" \ > -H "Content-Type: application/json" \ > localhost:8080/my/servlet ... > Content-Type: application/json > Accept: *{@literal/}* ... < HTTP/1.1 400 Bad Request < Content-Type: application/json ... {\"text\":\"not valid value\"}Unauthorized (401):public class MyServlet extends ProvidenceHttpServlet< MyRequest, MyRequest._Field, MyResponse, MyResponse._Field> { {@literal@}Override protected MyResponse handle(HttpServletRequest httpRequest, MyRequest request) throws MyException, InternalFailureException { // ... do stuff with request, or throw MyException or IFE. return MyResponse.builder() .setFieldOut("yes") .build(); } {@literal@}Override protected void handleException({@literal@}Nonnull Throwable exception, {@literal@}Nonnull Serializer responseSerializer, {@literal@}Nonnull HttpServletRequest httpRequest, {@literal@}Nonnull HttpServletResponse httpResponse) throws IOException { if (exception instanceof MyException) { httpResponse.setStatus(HttpStatus.UNAUTHORIZED_401); httpResponse.setHeader(HttpHeaders.WWW_AUTHENTICATE, "www.my-domain.com"); responseSerializer.serialize(httpResponse.getOutputStream(), (MyException) exception); return; } super.handleException(exception); } }Overridable Methods
-
: The main handle method. This must be implemented.handle(HttpServletRequest, PMessage) -
: Complete handling of exceptions thrown by thehandleException(Throwable, Serializer, HttpServletRequest, HttpServletResponse)handle(HttpServletRequest, PMessage)method. Calling super on this will fall back to default exception handling, using the methods below. This will per default serialize PMessage exceptions normally, and just callHttpServletResponse.sendError(int,String)for all the others using theThrowable.getMessage()message. -
: Get the response exception given the specific thrown exception. This method can be used to unwrap wrapped exceptions, or transform non-getResponseException(Throwable) -
: Get the HTTP status code to be used for the error response. Override to specialize, and call super to get default behavior. The default will handlestatusCodeForException(Throwable)PApplicationExceptionerrors, and otherwise return500 Internal Server Error.
- Since:
- 1.6.0
- See Also:
- Serialized Form
-
-
Constructor Summary
Constructors Constructor Description ProvidenceHttpServlet(net.morimekta.providence.descriptor.PMessageDescriptor<RQ,RQF> requestDescriptor)ProvidenceHttpServlet(net.morimekta.providence.descriptor.PMessageDescriptor<RQ,RQF> requestDescriptor, net.morimekta.providence.serializer.SerializerProvider serializerProvider)
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected voiddoPost(javax.servlet.http.HttpServletRequest httpRequest, javax.servlet.http.HttpServletResponse httpResponse)protected java.lang.ThrowablegetResponseException(java.lang.Throwable e)Get the exception to ge handled on failed requests.protected abstract <T extends java.lang.Throwable>
RShandle(javax.servlet.http.HttpServletRequest httpRequest, RQ request)Handle the request itself as a simple called method.protected voidhandleException(java.lang.Throwable rex, net.morimekta.providence.serializer.Serializer responseSerializer, javax.servlet.http.HttpServletRequest httpRequest, javax.servlet.http.HttpServletResponse httpResponse)Handle exceptions from the handle method.protected intstatusCodeForException(java.lang.Throwable exception)With default exception handling, this can simply change the status code used for the response.-
Methods inherited from class javax.servlet.GenericServlet
destroy, getInitParameter, getInitParameterNames, getServletConfig, getServletContext, getServletInfo, getServletName, init, init, log, log
-
-
-
-
Method Detail
-
handle
@Nonnull protected abstract <T extends java.lang.Throwable> RS handle(@Nonnull javax.servlet.http.HttpServletRequest httpRequest, @Nonnull RQ request) throws T extends java.lang.Throwable
Handle the request itself as a simple called method.- Type Parameters:
T- Thrown exception type.- Parameters:
httpRequest- The HTTP request.request- The parsed providence request.- Returns:
- The response object.
- Throws:
T- Any exception thrown.T extends java.lang.Throwable
-
handleException
protected void handleException(@Nonnull java.lang.Throwable rex, @Nonnull net.morimekta.providence.serializer.Serializer responseSerializer, @Nonnull javax.servlet.http.HttpServletRequest httpRequest, @Nonnull javax.servlet.http.HttpServletResponse httpResponse) throws java.io.IOExceptionHandle exceptions from the handle method.- Parameters:
rex- The response exception, which is the thrown exception or one of it's causes. SeegetResponseException(Throwable).responseSerializer- The serializer to use to serialize message output.httpRequest- The HTTP request.httpResponse- The HTTP response.- Throws:
java.io.IOException- If writing the response failed.
-
getResponseException
@Nonnull protected java.lang.Throwable getResponseException(java.lang.Throwable e)
Get the exception to ge handled on failed requests.- Parameters:
e- The exception seen.- Returns:
- The exception to use as response base.
-
statusCodeForException
protected int statusCodeForException(@Nonnull java.lang.Throwable exception)With default exception handling, this can simply change the status code used for the response.- Parameters:
exception- The exception seen.- Returns:
- The status code to be used.
-
doPost
protected final void doPost(javax.servlet.http.HttpServletRequest httpRequest, javax.servlet.http.HttpServletResponse httpResponse) throws java.io.IOException- Overrides:
doPostin classjavax.servlet.http.HttpServlet- Throws:
java.io.IOException
-
-