Ответ 1
Из HttpServletResponse#sendError()
javadoc:
По умолчанию сервер создает ответ, чтобы он выглядел как страница с ошибкой сервера HTML, содержащая указанное сообщение, устанавливая тип содержимого в текст /html, оставляя файлы cookie и другие заголовки неизмененными. Если для веб-приложения, соответствующего переданному коду состояния, было сделано объявление страницы с ошибкой, оно будет возвращено в предпочтение предлагаемому параметру msg.
Таким образом, при таком подходе у вас нет другого выбора, кроме как извлечь сообщение из ответа HTML самостоятельно. JSoup может быть полезным в этом.
Чтобы достичь желаемого, вам необходимо установить код ошибки и написать ответ самостоятельно, например.
response.setStatus(code);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
Вместо code
вы можете, кстати, также использовать одну из HttpServletResponse.SC_XXX
константы для этого.