package org.activityinfo.server.endpoint.jsonrpc; import com.extjs.gxt.ui.client.data.RpcMap; import com.google.common.io.ByteStreams; import com.google.inject.Inject; import com.google.inject.Singleton; import org.activityinfo.legacy.shared.command.Command; import org.activityinfo.legacy.shared.command.result.CommandResult; import org.activityinfo.server.command.DispatcherSync; import org.codehaus.jackson.Version; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; import org.codehaus.jackson.map.module.SimpleModule; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; @Singleton public class JsonRpcServlet extends HttpServlet { private static final Logger LOGGER = Logger.getLogger(JsonRpcServlet.class.getName()); private final DispatcherSync dispatcher; private final ObjectMapper objectMapper; @Inject public JsonRpcServlet(DispatcherSync dispatcher) { this.dispatcher = dispatcher; SimpleModule module = new SimpleModule("Command", new Version(1, 0, 0, null)); module.addDeserializer(Command.class, new CommandDeserializer()); module.addDeserializer(RpcMap.class, new RpcMapDeserializer()); objectMapper = new ObjectMapper(); objectMapper.registerModule(module); // to ensure that VoidResult is handled without error objectMapper.disable(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Command command; try { String json = new String(ByteStreams.toByteArray(req.getInputStream())); command = objectMapper.readValue(json, Command.class); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Failed to deserialize command", e); resp.sendError(HttpServletResponse.SC_BAD_REQUEST); return; } CommandResult result = dispatcher.execute(command); resp.setStatus(HttpServletResponse.SC_OK); resp.setContentType("application/json"); objectMapper.writeValue(resp.getOutputStream(), result); } }