Введение
Вы должны использовать, doGet()
когда хотите перехватить HTTP-запросы GET . Вы должны использовать, doPost()
когда хотите перехватывать запросы HTTP POST . Вот и все. Не переносите одно на другое или наоборот (например, в неудачном автогенерированном processRequest()
методе Netbeans ). В этом нет полного смысла.
ПОЛУЧИТЬ
Обычно запросы HTTP GET идемпотентны . Т.е. вы получаете точно такой же результат каждый раз, когда выполняете запрос (оставляя без внимания авторизацию / аутентификацию и временный характер страницы - результаты поиска, последние новости и т. Д.). Мы можем поговорить о запросе на закладку. Щелчок по ссылке, щелчок по закладке, ввод необработанного URL-адреса в адресной строке браузера и т. Д. Запускают HTTP-запрос GET. Если сервлет прослушивает рассматриваемый URL-адрес, doGet()
будет вызван его метод. Обычно он используется для предварительной обработки запроса. Т.е. выполнение некоторых бизнес-задач перед представлением вывода HTML из JSP, например сбор данных для отображения в таблице.
@WebServlet("/products")
public class ProductsServlet extends HttpServlet {
@EJB
private ProductService productService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = productService.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}
}
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td><a href="product?id=${product.id}">detail</a></td>
</tr>
</c:forEach>
</table>
Кроме того, ссылки просмотра / редактирования деталей, как показано в последнем столбце выше, обычно являются идемпотентными.
@WebServlet("/product")
public class ProductServlet extends HttpServlet {
@EJB
private ProductService productService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Product product = productService.find(request.getParameter("id"));
request.setAttribute("product", product); // Will be available as ${product} in JSP
request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response);
}
}
<dl>
<dt>ID</dt>
<dd>${product.id}</dd>
<dt>Name</dt>
<dd>${product.name}</dd>
<dt>Description</dt>
<dd>${product.description}</dd>
<dt>Price</dt>
<dd>${product.price}</dd>
<dt>Image</dt>
<dd><img src="productImage?id=${product.id}" /></dd>
</dl>
ПОЧТА
Запросы HTTP POST не идемпотентны. Если конечный пользователь заранее отправил форму POST для URL-адреса, который не выполнил перенаправление, то этот URL-адрес не обязательно может быть добавлен в закладки. Отправленные данные формы не отражаются в URL-адресе. Копирование URL-адреса в новое окно / вкладку браузера не обязательно приведет к тому же результату, что и после отправки формы. Такой URL-адрес не может быть добавлен в закладки. Если сервлет прослушивает рассматриваемый URL-адрес, он doPost()
будет вызван. Обычно он используется для постобработки запроса. То есть сбор данных из представленной HTML-формы и выполнение с ней некоторых бизнес-задач (преобразование, проверка, сохранение в БД и т. Д.). Наконец, обычно результат представляется в виде HTML с перенаправленной страницы JSP.
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="login">
<span class="error">${error}</span>
</form>
... который можно использовать в сочетании с этой частью сервлета:
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@EJB
private UserService userService;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect("home");
}
else {
request.setAttribute("error", "Unknown user, please try again");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}
Видите ли, если он User
находится в БД (т.е. имя пользователя и пароль действительны), то User
он будет помещен в область сеанса (т.е. "вошел в систему"), и сервлет перенаправит на какую-то главную страницу (этот пример идет http://example.com/contextname/home
), иначе он установит сообщение об ошибке и перенаправит запрос обратно на ту же страницу JSP, чтобы сообщение отображалось ${error}
.
Вы можете при необходимости также «скрыть» login.jsp
в /WEB-INF/login.jsp
так что пользователи могут получить доступ только к его сервлета. Это сохраняет URL-адрес в чистоте http://example.com/contextname/login
. Все, что вам нужно сделать, это добавить doGet()
к сервлету следующим образом:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(и соответственно обновите ту же строку doPost()
)
Тем не менее, я не уверен , если он просто играл и съемки в темноте, но код , который вы вывесили не выглядит хорошо (например, используя compareTo()
вместо того , чтобы equals()
и копаясь в parameternames вместо использования getParameter()
и id
и , password
кажется, быть объявленными как переменные экземпляра сервлета - что НЕ является потокобезопасным ). Поэтому я настоятельно рекомендую узнать немного больше о базовом API Java SE, используя учебные пособия Oracle (см. Главу «Следы, охватывающие основы») и о том, как правильно использовать JSP / сервлеты с помощью этих руководств .
Смотрите также:
Обновление : в соответствии с обновлением вашего вопроса (что довольно важно, вы не должны удалять части вашего исходного вопроса, это сделало бы ответы бесполезными ... лучше добавьте информацию в новый блок), оказывается, что вы без необходимости установка типа кодировки формы на multipart/form-data
. Это отправит параметры запроса в другом составе, чем (по умолчанию), application/x-www-form-urlencoded
который отправляет параметры запроса в виде строки запроса (например name1=value1&name2=value2&name3=value3
). Вам нужен только элемент в форме для загрузки файлов, которые могут быть несимвольными данными (двоичными данными). В вашем случае это не так, поэтому просто удалите его, и он будет работать должным образом. Если вам когда-нибудь понадобится загрузить файлы, вам придется установить тип кодировки и самостоятельно проанализировать тело запроса. Обычно вы используетеmultipart/form-data
когда у вас есть<input type="file">
Apache Commons FileUpload существует для, но если вы уже используете новый API Servlet 3.0, вы можете просто использовать встроенные средства, начиная с HttpServletRequest#getPart()
. См. Также этот ответ для конкретного примера: Как загружать файлы на сервер с помощью JSP / Servlet?