Development Shack Technology Understood

Allowing Cross-Domain AJAX with a Java Servlet  

Bottom Line: Make sure to include these response headers on every request:

private void fixHeaders(HttpServletResponse response) {
    response.addHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Access-Control-Allow-Methods", "GET, PUT, POST, OPTIONS, DELETE");
    response.addHeader("Access-Control-Allow-Headers", "Content-Type");
    response.addHeader("Access-Control-Max-Age", "86400");
}

If you know the specific domain(s) you want to allow access to the Servlet, make sure "Access-Control-Allow-Origin" is as restrictive as possible for security reasons.

Make sure to include a doOPTIONS() method in your servlet:

protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    fixHeaders(response);
}

Make sure to catch all Exceptions AND Throwables (If we don't catch all exceptions, the headers that allow cross-domain access won' be included in the response- thus the client won't know what went wrong):

try {
    fixHeaders(response);
    // Your code here...
} catch (Exception e) {
    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    response.setContentType("text/plain");
    response.getWriter().println(buildErrorMessage(e));
} catch (Throwable e) {
    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    response.setContentType("text/plain");
    response.getWriter().println(buildErrorMessage(e));
}

Example buildErrorMessage Code:

private static String buildErrorMessage(Exception e) {
    String msg = e.toString() + "\r\n";

    for (StackTraceElement stackTraceElement : e.getStackTrace()) {
        msg += "\t" + stackTraceElement.toString() + "\r\n";
    }

     return msg;
}

private static String buildErrorMessage(Throwable e) {
    String msg = e.toString() + "\r\n";

    for (StackTraceElement stackTraceElement : e.getStackTrace()) {
        msg += "\t" + stackTraceElement.toString() + "\r\n";
    }

    return msg;
}