HomeCode Reference › Servlet snippets

Servlet snippets

Purpose: GET and POST servlet skeletons with the correct registration, JSON handling and status codes.

Who this page is for

AudienceWhy it matters to you
Backend engineersEndpoint builders

GET JSON endpoint (resourceType-bound)

@Component(service = Servlet.class)
@SlingServletResourceTypes(
    resourceTypes = "phi-academy/components/planpage",
    selectors = "premium", extensions = "json",
    methods = HttpConstants.METHOD_GET)
public class PremiumServlet extends SlingSafeMethodsServlet {

    @Reference private PremiumService premiumService;

    @Override
    protected void doGet(SlingHttpServletRequest req, SlingHttpServletResponse resp)
            throws IOException {
        resp.setContentType("application/json");
        resp.setCharacterEncoding("UTF-8");
        Optional<Premium> premium = premiumService.forPage(req.getResource());
        if (premium.isEmpty()) {
            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
            resp.getWriter().write("{\"error\":\"no premium data\"}");
            return;
        }
        new ObjectMapper().writeValue(resp.getWriter(), premium.get());
    }
}

Call: GET /content/phi/plans/gold-hospital.premium.json

POST endpoint (CSRF-aware, write via the request session)

@Component(service = Servlet.class)
@SlingServletResourceTypes(
    resourceTypes = "phi-academy/components/quoteform",
    extensions = "json", methods = HttpConstants.METHOD_POST)
public class QuoteSubmitServlet extends SlingAllMethodsServlet {

    @Reference private JobManager jobManager;

    @Override
    protected void doPost(SlingHttpServletRequest req, SlingHttpServletResponse resp)
            throws IOException {
        String planId = req.getParameter("planId");
        if (planId == null || !planId.matches("[a-z0-9-]{1,64}")) {   // validate ALL input
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "invalid planId");
            return;
        }
        jobManager.addJob("phi/quotes/submit", Map.of("planId", planId)); // async, durable
        resp.setStatus(HttpServletResponse.SC_ACCEPTED);
    }
}

Frontend POSTs need the CSRF token (granite.csrf.standalone clientlib adds it to XHR; manual fetch: read /libs/granite/csrf/token.json and send CSRF-Token header).

Registration reminders

Quick navigation