Servlet snippets
Purpose: GET and POST servlet skeletons with the correct registration, JSON handling and status codes.
Who this page is for
| Audience | Why it matters to you |
|---|---|
| Backend engineers | Endpoint 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
- Path-bound servlets (
@SlingServletPaths("/bin/…")) only for genuinely content-free endpoints — and they need dispatcher allows + their own access control (servlets trade-offs). - New endpoints = dispatcher filter + cache rules review (checklist).