Wprowadzenie
Powinieneś użyć doGet()
gdy chcesz przechwytywać żądania HTTP GET . Powinieneś używać, doPost()
gdy chcesz przechwytywać żądania HTTP POST . To wszystko. Nie przenoś jednego do drugiego ani odwrotnie (na przykład w niefortunnej, automatycznie generowanej processRequest()
metodzie Netbeans ). To nie ma sensu.
DOSTAĆ
Zwykle żądania HTTP GET są idempotentne . Oznacza to, że otrzymujesz dokładnie ten sam wynik za każdym razem, gdy wykonujesz żądanie (pozostawiając autoryzację / uwierzytelnienie i wrażliwość na czas strony - wyniki wyszukiwania, ostatnie wiadomości itp. - poza rozważeniem). Możemy porozmawiać o żądaniu bukmacherskim. Kliknięcie łącza, kliknięcie zakładki, wprowadzenie surowego adresu URL w pasku adresu przeglądarki itp. Spowoduje uruchomienie żądania HTTP GET. Jeśli serwlet nasłuchuje podanego adresu URL, doGet()
zostanie wywołana jego metoda. Zwykle służy do wstępnego przetwarzania żądania. To znaczy robię pewne rzeczy biznesowe przed prezentacją wyjścia HTML ze strony JSP, na przykład zbieranie danych do wyświetlenia w tabeli.
@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>
Również linki do przeglądania / edycji szczegółów, jak pokazano w ostatniej kolumnie powyżej, są zwykle idempotentne.
@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>
POCZTA
Żądania HTTP POST nie są idempotentne. Jeśli użytkownik końcowy przesłał wcześniej formularz POST na adres URL, który nie wykonał przekierowania, to adres URL niekoniecznie musi mieć zakładkę. Przesłane dane formularza nie są odzwierciedlane w adresie URL. Kopiowanie adresu URL do nowego okna / karty przeglądarki niekoniecznie musi dać dokładnie taki sam wynik, jak po przesłaniu formularza. Taki adres URL nie podlega wówczas zakładaniu. Jeśli serwlet nasłuchuje podanego adresu URL, to jegodoPost()
zostanie wywołany. Zwykle jest używany do postprocesowania żądania. To znaczy zbieranie danych z przesłanego formularza HTML i robienie z nim pewnych rzeczy biznesowych (konwersja, walidacja, zapisywanie w DB itp.). Ostatecznie zwykle wynik jest przedstawiany jako HTML z przesłanej strony 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>
... które mogą być używane w połączeniu z tym fragmentem serwletu:
@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);
}
}
}
Widzisz, jeśli User
zostanie znaleziony w DB (tj. Nazwa użytkownika i hasło są prawidłowe), to User
zostanie umieszczony w zakresie sesji (tj. "Zalogowany"), a serwlet przekieruje na jakąś stronę główną (ten przykład idzie do http://example.com/contextname/home
), w przeciwnym razie ustawi komunikat o błędzie i przekieruje żądanie z powrotem do tej samej strony JSP, aby komunikat został wyświetlony przez ${error}
.
W razie potrzeby możesz także „ukryć” login.jsp
in, /WEB-INF/login.jsp
aby użytkownicy mieli do niego dostęp tylko przez serwlet. Dzięki temu adres URL jest czysty http://example.com/contextname/login
. Wszystko, co musisz zrobić, to dodać plikdoGet()
do serwletu w następujący sposób:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(i odpowiednio zaktualizuj ten sam wiersz doPost()
)
To powiedziawszy, nie jestem pewien, czy to jest po prostu grając i filmowania w ciemności, ale kod której pisał nie wygląda dobrze (takich jak używanie compareTo()
zamiast equals()
i kopanie w parameternames zamiast tylko za pomocą getParameter()
a id
i password
wydaje się być zadeklarowane jako zmienne instancji serwletu - które NIE są bezpieczne dla wątków ). Dlatego zdecydowanie polecam, aby dowiedzieć się więcej na temat podstawowego interfejsu API Java SE, korzystając z samouczków Oracle (zobacz rozdział „Szlaki dotyczące podstaw”) i jak prawidłowo korzystać z JSP / Servletów za pomocą tych samouczków .
Zobacz też:
Aktualizacja : zgodnie z aktualizacją twojego pytania (co jest dość duże, nie powinieneś usuwać części swojego pierwotnego pytania, to uczyniłoby odpowiedzi bezwartościowymi ... raczej dodaj informacje w nowym bloku), okazuje się, że jesteś niepotrzebne ustawianie typu kodowania formularza na multipart/form-data
. Spowoduje to wysłanie parametrów żądania w innym składzie niż (domyślny)application/x-www-form-urlencoded
który wysyła parametry żądania jako ciąg zapytania (np name1=value1&name2=value2&name3=value3
.). Potrzebujesz tylko wtedy, multipart/form-data
gdy masz<input type="file">
element w formularzu do przesłania plików, które mogą być danymi niebędącymi znakami (dane binarne). Tak nie jest w twoim przypadku, więc po prostu go usuń, a będzie działać zgodnie z oczekiwaniami. Jeśli kiedykolwiek będziesz musiał przesłać pliki, będziesz musiał ustawić typ kodowania i samodzielnie przeanalizować treść żądania. Zwykle używasz tam Apache Commons FileUploadale jeśli już korzystasz z nowego interfejsu API Servlet 3.0, możesz po prostu użyć wbudowanych funkcji zaczynających się od HttpServletRequest#getPart()
. Zobacz również tę odpowiedź, aby zapoznać się z konkretnym przykładem: Jak przesłać pliki na serwer przy użyciu JSP / Servlet?