HttpServletResponse # sendError Как изменить ContentType

Я создаю простой сервлет для ответа на отправку формы. Этот сервлет получает запрос POST и должен отвечать на данные Application / JSON. Это хорошо работает. Теперь я хочу добавить в свой сервлет управление ошибками: если сервлет получает неверные параметры запроса, я хочу, чтобы он отвечал клиенту на ответ 400 - Bad Request простым ответом {"error":"ERROR MESSAGE"} JSON.

Я использую HttpServletResponse#sendError(int,String) для правильной отправки ошибки, но ContentType ответа всегда устанавливается на text/html, хотя раньше я использовал HttpServletResponse#setContentType("application/json").

Это хороший способ отправить ошибку с помощью Servets? Как я могу заставить ContentType ответа на application/json?

Пример кода метода doPost () моего тестового сервлета:

public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.print("{\"error\":1}");
        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}

person pdegand59    schedule 22.01.2013    source источник


Ответы (3)


Это работает как указано:

Отправляет клиенту ответ об ошибке с указанным статусом и очищает буфер. По умолчанию сервер создает ответ, который выглядит как страница ошибки сервера в формате HTML, содержащая указанное сообщение, и задает тип содержимого «text / html».

HttpServletResponse.sendError(int)

с другой стороны, не имеет этого ограничения / функции.

Отправляет клиенту ответ об ошибке, используя указанный код состояния и очищая буфер.

Это означает: установить тип содержимого, записать в буфер, вызвать sendError(400).

person Marcel Stör    schedule 22.01.2013
comment
Спасибо за быстрый ответ! Я пробовал то, что вы объяснили. Не уверен, что все идет хорошо, потому что это работает не так, как ожидалось. :( Не уверен насчет записи в буферную часть. Я отредактировал первое сообщение с образцом кода, который использую для целей тестирования. - person pdegand59; 22.01.2013
comment
У меня это не сработало. sendError проигнорирует все, что я написал ранее. - person Jason Winnebeck; 26.09.2014
comment
Это не работает, потому что к JavaDocs добавлен следующий оператор: HttpServletResponse.sendError (int) эквивалентен вызову HttpServletResponse.sendError (int, String) с тем же кодом состояния и нулевым значением для сообщения. - person tom_mai78101; 24.06.2021

Недавно у меня возникла эта проблема, когда я хотел отправлять сообщения об ошибках внутри приложения JAX-RS. sendError всегда будет возвращать text / html в соответствии со спецификацией. Я должен был сделать следующее, учитывая HttpServletResponse response:

response.resetBuffer();
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setHeader("Content-Type", "application/json");
response.getOutputStream().print("{\"errorMessage\":\"You can't use this!\"}");
response.flushBuffer(); // marks response as committed -- if we don't do this the request will go through normally!

flushBuffer критически важен для того, чтобы пометить ответ как подтвержденный, как это делает sendError. Сначала я попытался просто вызвать close в потоке вывода, но что произойдет, если мой фильтр будет работать, тогда ресурс JAX-RS продолжит нормально работать, тогда я получу сообщение об ошибке И нормальный ответ, объединенный вместе со статусом 200 код!

resetBuffer существует на тот случай, если что-то еще установило заголовки или записало некоторый контент перед этим фильтром.

person Jason Winnebeck    schedule 26.09.2014
comment
Также интересно, в какой степени это конкретное поведение зависит от конкретной платформы JavaEE. - person dbreaux; 20.04.2018

Вместо вызова response.sendError (int) используйте response.setStatus (int).

person Yunwen    schedule 17.07.2013
comment
Это не вызовет конфигурирование страницы с ошибкой в ​​JBoss / WildFly. - person agilob; 07.07.2017