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

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

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

Ответы

Ответ 1

Введение

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

GET

Обычно HTTP GET-запросы idempotent. То есть вы получаете точно такой же результат каждый раз, когда выполняете запрос (оставляя авторизацию/аутентификацию и чувствительный к времени характер результатов поиска страницы, последних новостей и т.д.). Мы можем поговорить о запросе на закладку. Нажав на ссылку, щелкнув закладку, введя необработанный URL-адрес в адресной строке браузера, и т.д. Все будут запускать HTTP-запрос GET. Если сервлет прослушивает соответствующий URL-адрес, будет вызываться его метод doGet(). Обычно он используется для запроса preprocess. То есть делая некоторые деловые вещи перед представлением вывода 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(). Обычно он используется для запроса postprocess. То есть сбор данных из представленной формы 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);
        }
    }

}

Вы видите, что если t211 > находится в БД (то есть имя пользователя и пароль действительны), то 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, как представляется, объявлены как переменные экземпляра сервлета &mdash, что НЕ threadsafe). Поэтому я настоятельно рекомендую немного узнать о базовом Java SE API, используя учебники Oracle (см. Главу "Trails Covering the Basics" ) и как правильно использовать 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.

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

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

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

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

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

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

Если вы используете <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");

.........
.........