Я разработал страницу HTML, которая отправляет информацию в Сервлет. В Сервлете я использую методы doGet()
и doPost()
:
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String id = req.getParameter("realname");
String password = req.getParameter("mypassword");
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String id = req.getParameter("realname");
String password = req.getParameter("mypassword");
}
В коде страницы HTML, который называет Сервлет:
<form action="identification" method="post" enctype="multipart/form-data">
User Name: <input type="text" name="realname">
Password: <input type="password" name="mypassword">
<input type="submit" value="Identification">
</form>
Когда я использую method = "get"
в Сервлете я получаю значение идентификатора и пароля, однако при использовании method = "post"
, идентификатор и пароль установлены на null
. Почему я не получаю значения в этом случае?
Другая вещь, которую я хотел бы знать, состоит в том, как использовать данные, сгенерированные или проверенные Сервлетом. Например, если бы Сервлет, показанный выше, аутентифицирует пользователя, я хотел бы распечатать идентификатор пользователя в своей странице HTML. Я должен смочь отправить строке 'идентификатор' как ответ и использовать эту информацию в моей странице HTML. Действительно ли это возможно?
Вы должны использовать doGet ()
, если хотите перехватывать HTTP-запросы GET . Вы должны использовать doPost ()
, если хотите перехватывать HTTP-запросы POST . Это все. Не переносите одно на другое или наоборот (например, в неудачном автоматически сгенерированном методе Netbeans processRequest ()
). В этом нет полного смысла.
Обычно запросы 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);
}
}
}
Видите ли, если Пользователь
найден в БД (т.е. имя пользователя и пароль действительны), то Пользователь
будет помещен в область действия сеанса (т.е. «вошел в систему»), и сервлет будет перенаправлять на какую-то главную страницу (этот пример идет на 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
и пароль
, похоже, объявлены как переменные экземпляра сервлета, что НЕ потокобезопасный ). Поэтому я настоятельно рекомендую узнать немного больше о базовом API Java SE с помощью руководств Oracle (см. Главу «Следы, охватывающие основы») и о том, как правильно использовать JSP / сервлеты с помощью те учебники .
Обновление : согласно обновлению вашего вопроса (что довольно важно, вы не должны удалять части исходного вопроса, это сделает ответы бесполезными ... скорее добавит информацию в новый блок), оказывается, что вы без необходимости устанавливаете тип кодировки формы на multipart / form-data
.Это отправит параметры запроса в другом составе, чем (по умолчанию) application / x-www-form-urlencoded
, который отправляет параметры запроса в виде строки запроса (например, name1 = value1 & name2 = value2 & name3 = значение3
). Вам понадобится только multipart / form-data
всякий раз, когда у вас есть элемент
в форме для загрузки файлов, которые могут быть несимвольными данными (двоичными данными) . В вашем случае это не так,так что просто удалите его, и он будет работать должным образом. Если вам когда-либо понадобится загрузить файлы, вам придется установить тип кодировки и самостоятельно проанализировать тело запроса. Обычно для этого используется Apache Commons FileUpload , но если вы уже пользуетесь новым API сервлета 3.0, то можете просто использовать встроенные средства, начиная с HttpServletRequest # getPart ()
. См. Также этот ответ для конкретного примера: Как загрузить файлы на сервер с помощью JSP / сервлета?
Реализация метода HttpServlet.service () в контейнере сервлета будет автоматически перенаправляться на doGet () или doPost () по мере необходимости, поэтому вам не нужно переопределить метод обслуживания.
Может быть, вы передаете данные через get, а не post?
<form method="get" ..>
..
</form>