doGet и doPost в сервлетах - PullRequest
       49

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

103 голосов
/ 28 февраля 2010

Я разработал 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-странице.Я должен быть в состоянии отправить строку «id» в качестве ответа и использовать эту информацию на моей HTML-странице.Возможно ли это?

Ответы [ 5 ]

188 голосов
/ 28 февраля 2010

Введение

Вы должны использовать 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?

2 голосов
/ 18 июня 2015

И 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=vanilla HTTP / 1.0 необязательный заголовок headeroptional << пустая строка >>>

Данные формы имя = значение будут храниться в переменной среды с именем QUERY_STRING. Эта переменная будет отправлена ​​в обрабатывающую программу (например, JSP, сервлет Java, PHP и т. Д.)

  1. Метод POST используется, когда вы создаете HTML-форму, а метод request = POST является частью тега. Метод POST позволяет клиенту отправлять данные формы на сервер в разделе тела запроса (как обсуждалось ранее). Данные кодируются и форматируются аналогично методу GET, за исключением того, что данные отправляются в программу через стандартный ввод.

Пример: POST /sultans/shop//form1.jsp HTTP / 1.0 необязательный заголовок headeroptional << пустая строка >>> name = Sam% 20Sultan & iceCream = vanilla

При использовании метода post переменная окружения QUERY_STRING будет пустой. Преимущества / недостатки GET против POST

Преимущества метода GET: Немного быстрее Параметры можно вводить через форму или добавляя их после URL Страница может быть добавлена ​​в закладки с ее параметрами

Недостатки метода GET: Можно отправлять только 4K данных. (Вы не должны использовать его при использовании поля textarea) Параметры видны в конце URL

Преимущества метода POST: Параметры не видны в конце URL. (Используйте для конфиденциальных данных) Может отправлять данные более 4K на сервер

Недостатки метода POST: Невозможно добавить в закладки свои данные

0 голосов
/ 11 июня 2016

Если вы введете <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");

.........
.........
0 голосов
/ 28 февраля 2010

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

0 голосов
/ 28 февраля 2010

Может быть, вы передаете данные через get, а не по почте?

<form method="get" ..>
..
</form>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...