Это происходит из-за того, что неявный фид строки, также известный как символ новой строки \n
, добавляется ко всем пользовательским вводам терминала, поскольку он сообщает потоку начать новую строку. Вы можете смело учитывать это, используя std::getline
при проверке нескольких строк ввода пользователя. Поведение по умолчанию std::getline
будет читать все до и включая символ новой строки \n
из объекта входного потока, который в этом случае является std::cin
.
#include
#include
int main()
{
std::string name;
std::string state;
if (std::getline(std::cin, name) && std::getline(std::cin, state))
{
std::cout << "Your name is " << name << " and you live in " << state;
}
return 0;
}
blockquote >Input: "John" "New Hampshire" Output: "Your name is John and you live in New Hampshire"
Обычно вы не должны закрывать поток. Контейнер сервлета автоматически закрывает поток после завершения сервлета как часть жизненного цикла запроса сервлета.
Например, если вы закрыли поток, он не будет доступен, если вы внедрили Фильтр .
Сказав все это, если вы его закрываете ничего плохого не произойдет, если вы не пытаетесь использовать его снова.
EDIT: другая ссылка фильтра
EDIT2: adrian.tarau is correct в том случае, если вы хотите изменить ответ после того, как сервлет выполнил свою задачу, вы должны создать оболочку, расширяющую HttpServletResponseWrapper, и буферизировать вывод. Это необходимо для того, чтобы выход выводился непосредственно клиенту, но также позволяет защитить, если сервлет закрывает поток, согласно этой выдержке (выделение мое):
Фильтр, который изменяет ответ должен обычно захватывать ответ до того, как он будет возвращен клиенту. Способ сделать это - передать сервлет, который генерирует ответ на резервный поток. Резервный поток не позволяет сервлету закрывать исходный поток ответа при его завершении и позволяет фильтру изменять ответ сервлета.
blockquote>Из этой официальной статьи Sun можно сделать вывод, что закрытие выходного потока сервлета является нормальным явлением, но не является обязательным.
Вы должны закрыть поток, код становится более чистым, так как вы вызываете getOutputStream (), и поток не передается вам в качестве параметра, когда обычно вы просто используете его и не пытаетесь его закрыть. API-интерфейс Servlet не утверждает, что, если выходной поток может быть закрыт или не должен быть закрыт, в этом случае вы можете безопасно закрыть поток, любой контейнер там позаботится о закрытии потока, если он не был закрыт сервлетом.
Вот метод close () в Jetty, они закрывают поток, если он не закрыт.
public void close() throws IOException
{
if (_closed)
return;
if (!isIncluding() && !_generator.isCommitted())
commitResponse(HttpGenerator.LAST);
else
flushResponse();
super.close();
}
Также как разработчик фильтра вы не должны предполагать, что OutputStream не закрывается, вы всегда должны передавать другой OutputStream, если хотите изменить содержимое после того, как сервлет выполнил свою работу.
EDIT: я всегда закрываю поток, и у меня не было никаких проблем с Tomcat / Jetty. Я не думаю, что у вас возникнут проблемы с контейнером, старым или новым.
Общее правило заключается в следующем: если вы открыли поток, вы должны закрыть его. Если вы этого не сделали, вы не должны. Убедитесь, что код симметричен.
В случае HttpServletResponse
он немного менее четкий, так как это не очевидно, если вызов getOutputStream()
- это операция, которая открывает поток. Джавадок просто говорит, что это «Returns a ServletOutputStream
»; аналогично для getWriter()
. В любом случае, ясно, что HttpServletResponse
«владеет» потоком / писателем, и он (или контейнер) отвечает за его закрытие снова.
Итак, чтобы ответить на ваш вопрос - нет, вы должны не закрывайте поток в этом случае. Контейнер должен это сделать, и если вы доберетесь до него, вы рискуете ввести тонкие ошибки в своем приложении.
close()
, когда он выполняется с потоком, клиент возвращается немедленно, а остальная часть сервлета продолжает выполнение. Разве это не делает ответ немного более относительным? в отличие от окончательного да или нет
– BiGGZ
15 January 2017 в 00:09
Если есть вероятность, что фильтр может быть вызван на «включенном» ресурсе, вы обязательно должны not закрыть поток. Это приведет к сбою включенного ресурса с исключением «stream closed».
Другой аргумент против закрытия OutputStream
. Посмотрите на этот сервлет. Это исключает. Исключение отображается в файле web.xml с ошибкой JSP:
package ser;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet(name = "Erroneous", urlPatterns = {"/Erroneous"})
public class Erroneous extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
try {
throw new IOException("An error");
} finally {
// out.close();
}
}
}
Файл web.xml содержит:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<error-page>
<exception-type>java.io.IOException</exception-type>
<location>/error.jsp</location>
</error-page>
</web-app>
И error.jsp:
<%@page contentType="text/html" pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error Page</title>
</head>
<body>
<h1><%= exception.getMessage()%></h1>
</body>
</html>
Когда вы загружаете /Erroneous
в браузере, вы видите страницу с ошибкой, отображающую «Ошибка». Но если вы прокомментируете строку out.close()
в указанном выше сервлете, повторно разверните приложение и перезагрузите /Erroneous
, вы ничего не увидите в браузере. Я не знаю, что на самом деле происходит, но я предполагаю, что out.close()
предотвращает обработку ошибок.
Протестировано с Tomcat 7.0.50, Java EE 6 с использованием Netbeans 7.4.