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

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

105
задан drognisep 11 August 2016 в 17:42
поделиться

3 ответа

Введение

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

GET

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

}

Видите ли, если Пользователь найден в БД (т.е. имя пользователя и пароль действительны), то Пользователь будет помещен в область действия сеанса (т.е. «вошел в систему»), и сервлет будет перенаправлять на какую-то главную страницу (этот пример идет на 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 и пароль , похоже, объявлены как переменные экземпляра сервлета, что НЕ потокобезопасный ). Поэтому я настоятельно рекомендую узнать немного больше о базовом API Java SE с помощью руководств Oracle (см. Главу «Следы, охватывающие основы») и о том, как правильно использовать JSP / сервлеты с помощью те учебники .

См. Также:


Обновление : согласно обновлению вашего вопроса (что довольно важно, вы не должны удалять части исходного вопроса, это сделает ответы бесполезными ... скорее добавит информацию в новый блок), оказывается, что вы без необходимости устанавливаете тип кодировки формы на multipart / form-data .Это отправит параметры запроса в другом составе, чем (по умолчанию) application / x-www-form-urlencoded , который отправляет параметры запроса в виде строки запроса (например, name1 = value1 & name2 = value2 & name3 = значение3 ). Вам понадобится только multipart / form-data всякий раз, когда у вас есть элемент в форме для загрузки файлов, которые могут быть несимвольными данными (двоичными данными) . В вашем случае это не так,так что просто удалите его, и он будет работать должным образом. Если вам когда-либо понадобится загрузить файлы, вам придется установить тип кодировки и самостоятельно проанализировать тело запроса. Обычно для этого используется Apache Commons FileUpload , но если вы уже пользуетесь новым API сервлета 3.0, то можете просто использовать встроенные средства, начиная с HttpServletRequest # getPart () . См. Также этот ответ для конкретного примера: Как загрузить файлы на сервер с помощью JSP / сервлета?

191
ответ дан 24 November 2019 в 03:59
поделиться

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

0
ответ дан 24 November 2019 в 03:59
поделиться

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

<form method="get" ..>
..
</form>
0
ответ дан 24 November 2019 в 03:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: