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

Я разработал 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", идентификатор и пароль установлены в null, Почему я не получаю значения в этом случае?

Еще я хотел бы знать, как использовать данные, сгенерированные или проверенные сервлетом. Например, если сервлет, показанный выше, аутентифицирует пользователя, я хотел бы напечатать идентификатор пользователя на моей HTML-странице. Я должен быть в состоянии отправить строку "id" в качестве ответа и использовать эту информацию на моей HTML-странице. Является ли это возможным?

5 ответов

Решение

Вступление

Вы должны использовать doGet() когда вы хотите перехватить запросы HTTP GET. Вы должны использовать doPost() когда вы хотите перехватить запросы HTTP POST. Это все. Не переносите одно на другое или наоборот (например, в неудачно сгенерированном Netbeans processRequest() метод). Это не имеет никакого смысла.

ПОЛУЧИТЬ

Обычно запросы 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() и копаться в именах параметров вместо того, чтобы просто использовать 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?

И GET, и POST используются браузером для запроса одного ресурса с сервера. Каждый ресурс требует отдельного запроса GET или POST.

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

Метод GET используется одним из двух способов: если метод не указан, то есть когда вы или браузер запрашиваете простой ресурс, такой как HTML-страница, изображение и т. Д. Когда форма отправляется, и вы выбираете метод = Получить на 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: нельзя добавить в закладки его данные

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

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

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

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

.........
.........
Другие вопросы по тегам