Вступ
Ви повинні використовувати, doGet()
коли ви хочете перехоплювати HTTP GET-запити . Ви повинні використовувати, doPost()
коли ви хочете перехоплювати HTTP POST-запити . Це все. Не портуйте один на інший або навпаки (наприклад, у нещасному автоматично створеному processRequest()
методі Netbeans ). Це не має жодного сенсу.
ЗАРАЗ
Зазвичай 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>
ПОШТА
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 / 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?