doGet і doPost в сервлетах


105

Я розробив 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"сервлет, я отримую значення id та пароля, однак при використанні method = "post"id та password встановлюються null. Чому я не отримую значення в цьому випадку?

Ще одна річ, яку я хотів би знати, - це використовувати дані, створені або перевірені сервлетом. Наприклад, якщо сервлет, показаний вище, автентифікує користувача, я хотів би роздрукувати ідентифікатор користувача на моїй HTML-сторінці. Я повинен мати можливість надіслати рядок 'id' як відповідь і використовувати цю інформацію на моїй HTML-сторінці. Це можливо?


Як ви використовуєте метод публікації в html?
Ігор Артамонов

А також, для чого вам потрібен такий дивний цикл над назвами параметрів?
Ігор Артамонов

1
Ви спробували видалити `enctype = multipart / form-data`? Я підозрюю, що це ваша проблема.
Джек Лев

Це було все. Чому не з'являється робота, якщо така є? Спасибі за вашу допомогу!
дедало

Відповіді:


197

Вступ

Ви повинні використовувати, 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?


2

І GET, і POST використовуються браузером для запиту одного ресурсу від сервера. Кожен ресурс вимагає окремого GET або POST-запиту.

  1. Метод GET найчастіше (і це метод за замовчуванням), який використовується браузерами для отримання інформації з серверів. При використанні методу GET 3-й розділ пакету запитів, який є органом запиту, залишається порожнім.

Метод GET використовується одним із двох способів: коли не вказано жодного методу, тобто коли ви або веб-переглядач запитуєте простий ресурс, такий як сторінка HTML, зображення тощо. Коли форма подається, ви вибираєте метод = GET на тезі HTML. Якщо метод GET використовується з формою HTML, то дані, зібрані через форму, надсилаються на сервер, додаючи "?" до кінця URL-адреси, а потім додайте всі пари = пара значень = значення (ім'я поля форми HTML і значення, введене в цьому полі), розділених прикладом "&": GET /sultans/shop//form1.jsp?name= Sam% 20Sultan & iceCream = ванільний HTTP / 1.0 необов'язковий головний убір головки << порожній рядок >>>

Дані форми = значення = значення зберігатимуться в змінній середовища, що називається QUERY_STRING. Ця змінна буде надіслана програмі обробки (наприклад, JSP, сервлет Java, PHP тощо)

  1. Метод POST використовується при створенні форми HTML, а метод запиту = POST як частина тегу. Метод POST дозволяє клієнту надсилати дані форми на сервер у розділі запиту (як обговорювалося раніше). Дані кодуються та форматуються аналогічно методу GET, за винятком того, що дані надсилаються програмі через стандартний вхід.

Приклад: POST /sultans/shop//form1.jsp HTTP / 1.0 необов'язковий головний уголовок << порожній рядок >>> ім'я = Sam% 20Sultan & iceCream = ваніль

При використанні методу публікації змінна середовища QUERY_STRING буде порожньою. Переваги / недоліки GET проти POST

Переваги методу GET: Трохи швидше Параметри можна вводити через форму або додаючи їх після того, як URL-адресу сторінки можна буде розміщувати в закладках за її параметрами

Недоліки методу GET: Може надсилати дані лише 4К. (Не слід використовувати його під час використання поля текстової області) Параметри відображаються в кінці URL-адреси

Переваги методу POST: Параметри не відображаються в кінці URL-адреси. (Використовуйте для конфіденційних даних) Може надіслати більше ніж 4K даних на сервер

Недоліки методу POST: Неможливо позначити закладки своїми даними


0

Реалізація методу HttpServlet.service () контейнера сервлетів автоматично пересилає до doGet () або doPost () у міру необхідності, тому вам не потрібно буде перекривати метод обслуговування.


0

Можливо, ви передаєте дані через get, а не публікацію?

<form method="get" ..>
..
</form>

0

Якщо ви <form action="identification" >користуєтеся формою html, дані передаватимуться за допомогою програми "Get" за замовчуванням, отже, ви можете зафіксувати це за допомогою функції doGet у вашому коді сервлета Java. Таким чином дані передаватимуться під заголовком HTML, а отже, вони будуть видно в URL-адресі при надходженні. З іншого боку, якщо ви хочете передати дані в HTML-тілі, тоді USE Post: <form action="identification" method="post">і зафіксуйте ці дані у функції doPost. Це було, дані будуть передані під html-тілом, а не заголовком html, і ви не побачите даних у URL-адресі після надсилання форми.

Приклади з мого html:

<body>  
<form action="StartProcessUrl" method="post">
.....
.....

Приклади з мого коду сервлета Java:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        PrintWriter out = response.getWriter();
         String surname = request.getParameter("txtSurname");
         String firstname = request.getParameter("txtForename");
         String rqNo = request.getParameter("txtRQ6");
         String nhsNo = request.getParameter("txtNHSNo");

         String attachment1 = request.getParameter("base64textarea1");
         String attachment2 = request.getParameter("base64textarea2");

.........
.........
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.