Введение
Вы должны использовать doGet()
, если хотите перехватить HTTP GET-запросы . Вы должны использовать doPost()
, если хотите перехватить HTTP POST-запросы . Это все. Не переносите одно на другое или наоборот (например, в неудачном автоматически генерируемом методе processRequest()
Netbeans). Это не имеет никакого смысла.
GET
Обычно HTTP GET-запросы идемпотентны . То есть Вы получаете точно такой же результат каждый раз, когда выполняете запрос (оставляя вне рассмотрения авторизацию / аутентификацию и чувствительный ко времени характер страницы - результаты поиска, последние новости и т. д.). Мы можем поговорить о закладке запроса. Если щелкнуть ссылку, щелкнуть закладку, ввести необработанный URL-адрес в адресную строку браузера, etcetera выполнит 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>
POST
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
будет помещен в область действия сеанса (т. Е. "Вошел в систему"), а сервлет перенаправит на какой-то главный page (в этом примере показано 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()
и копание в именах параметров вместо использования getParameter()
и id
и password
, кажется, объявлены как переменные экземпляра сервлета & mdash; это НЕ threadsafe ). Поэтому я настоятельно рекомендую немного больше узнать о базовом API Java SE с помощью обучающих программ Oracle (см. Главу "Изучение основ") и о том, как правильно использовать JSP / Servlets с помощью эти уроки .
Смотри также:
Обновление : в соответствии с обновлением вашего вопроса (который является довольно важным, вы не должны удалять части своего исходного вопроса, это сделает ответы бесполезными .. скорее добавьте информация в новом блоке), оказывается, что вы излишне устанавливаете тип кодировки формы на 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?