package org.peerbox.server.servlets; import java.io.IOException; import java.nio.file.Path; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.MimeTypes; import org.peerbox.server.servlets.messages.ServerReturnCode; import org.peerbox.server.servlets.messages.ServerReturnMessage; import org.peerbox.server.utils.PathDeserializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; abstract class BaseServlet<T> extends HttpServlet { private static final long serialVersionUID = 1L; private static final Logger logger = LoggerFactory.getLogger(BaseServlet.class); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { if (!checkContentTypeJSON(req, resp)) { logger.error("Received request with wrong ContentType: {}", req.getContentType()); sendErrorMessage(resp, new ServerReturnMessage(ServerReturnCode.WRONG_CONTENT_TYPE)); return; } String content = readContentAsString(req); if (content == null || content.isEmpty()) { sendErrorMessage(resp, new ServerReturnMessage(ServerReturnCode.EMPTY_REQUEST)); return; } T msg = deserializeMessage(content); if (msg == null) { throw new Exception("Message is null. Cannot interpret request message."); } handleRequest(msg); sendEmptyOK(resp); } catch (JsonSyntaxException e) { sendErrorMessage(resp, new ServerReturnMessage(ServerReturnCode.DESERIALIZE_ERROR)); logger.error("Could not deserialize json.", e); } catch (Exception e) { sendErrorMessage(resp, new ServerReturnMessage(ServerReturnCode.REQUEST_EXCEPTION)); logger.error("Unexpected exception. ", e); } } protected abstract void handleRequest(T msg) throws Exception; protected abstract T deserializeMessage(String jsonContent); protected Gson createGsonInstance() { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Path.class, new PathDeserializer()); return gsonBuilder.create(); } protected String readContentAsString(HttpServletRequest req) throws IOException { // read content char[] buffer = new char[req.getContentLength()]; req.getReader().read(buffer); return new String(buffer); } protected boolean checkContentTypeJSON(HttpServletRequest req, HttpServletResponse resp) throws IOException { // check content type: json if (req.getContentType() == null || !req.getContentType().contains(MimeTypes.Type.APPLICATION_JSON.asString())) { return false; } return true; } protected void sendErrorMessage(HttpServletResponse resp, ServerReturnMessage msg) throws IOException { resp.setContentType(MimeTypes.Type.APPLICATION_JSON.asString()); resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); Gson gson = new Gson(); String response = gson.toJson(msg); resp.getWriter().println(response); logger.error("Request failed: {} (Code {})", msg.getMessage(), msg.getCode()); } protected void sendEmptyOK(HttpServletResponse resp) { resp.setContentType(MimeTypes.Type.APPLICATION_JSON.asString()); resp.setStatus(HttpServletResponse.SC_OK); } }