Giới thiệu
Bạn nên sử dụng doGet()
khi muốn chặn các yêu cầu HTTP GET . Bạn nên sử dụng doPost()
khi muốn chặn các yêu cầu HTTP POST . Đó là tất cả. Không chuyển cái này sang cái kia hoặc ngược lại (chẳng hạn như trong processRequest()
phương pháp tự động tạo không may của Netbeans ). Điều này không có ý nghĩa hoàn toàn.
ĐƯỢC
Thông thường, các yêu cầu HTTP GET là không quan trọng . Tức là bạn nhận được chính xác cùng một kết quả mỗi khi bạn thực hiện yêu cầu (để lại ủy quyền / xác thực và tính chất nhạy cảm về thời gian của trang — kết quả tìm kiếm, tin tức cuối cùng, v.v. — được xem xét bên ngoài). Chúng ta có thể nói về một yêu cầu có thể đánh dấu trang. Nhấp vào liên kết, nhấp vào dấu trang, nhập URL thô vào thanh địa chỉ của trình duyệt, tất cả sẽ kích hoạt yêu cầu HTTP GET. Nếu một Servlet đang lắng nghe URL được đề cập, thì doGet()
phương thức của nó sẽ được gọi. Nó thường được sử dụng để xử lý trước một yêu cầu. Tức là thực hiện một số công việc kinh doanh trước khi trình bày đầu ra HTML từ JSP, chẳng hạn như thu thập dữ liệu để hiển thị trong bảng.
@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>
Ngoài ra, các liên kết xem / chỉnh sửa chi tiết như được hiển thị trong cột cuối cùng ở trên thường không quan trọng.
@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>
BÀI ĐĂNG
Yêu cầu HTTP POST không phải là đơn vị quan trọng. Nếu người dùng cuối đã gửi biểu mẫu ĐĂNG trên một URL trước đó mà chưa thực hiện chuyển hướng, thì URL đó không nhất thiết phải có thể đánh dấu trang. Dữ liệu biểu mẫu đã gửi không được phản ánh trong URL. Việc sao chép URL vào một cửa sổ / tab trình duyệt mới có thể không nhất thiết phải mang lại kết quả chính xác như sau khi gửi biểu mẫu. Một URL như vậy không thể đánh dấu được. Nếu một Servlet đang lắng nghe URL được đề cập, thì nó doPost()
sẽ được gọi. Nó thường được sử dụng để xử lý một yêu cầu. Tức là thu thập dữ liệu từ một biểu mẫu HTML đã gửi và thực hiện một số công việc kinh doanh với nó (chuyển đổi, xác thực, lưu trong DB, etcetera). Cuối cùng, kết quả thường được trình bày dưới dạng HTML từ trang JSP được chuyển tiếp.
<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>
... có thể được sử dụng kết hợp với mảnh Servlet này:
@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);
}
}
}
Bạn thấy đấy, nếu User
tìm thấy trong DB (nghĩa là tên người dùng và mật khẩu hợp lệ), thì cái đó User
sẽ được đặt trong phạm vi phiên (tức là "đã đăng nhập") và servlet sẽ chuyển hướng đến một số trang chính (ví dụ này chuyển đến http://example.com/contextname/home
), khác nó sẽ thiết lập một thông báo lỗi và chuyển tiếp yêu cầu trở lại cùng một trang JSP để thông báo được hiển thị ${error}
.
Nếu cần, bạn cũng có thể "ẩn" phần login.jsp
trong /WEB-INF/login.jsp
đó để người dùng chỉ có thể truy cập nó bằng servlet. Điều này giữ cho URL sạch sẽ http://example.com/contextname/login
. Tất cả những gì bạn cần làm là thêm a doGet()
vào servlet như sau:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(và cập nhật cùng một dòng cho phù doPost()
hợp)
Điều đó nói rằng, tôi không chắc liệu nó có chỉ chơi xung quanh và chụp trong bóng tối hay không, nhưng mã mà bạn đăng có vẻ không đẹp (chẳng hạn như sử dụng compareTo()
thay vì equals()
và đào các tên tham số thay vì chỉ sử dụng getParameter()
và id
và password
dường như được khai báo dưới dạng các biến cá thể của servlet - KHÔNG phải là luồng an toàn ). Vì vậy, tôi thực sự khuyên bạn nên tìm hiểu thêm một chút về Java SE API cơ bản bằng cách sử dụng các hướng dẫn của Oracle (xem chương "Kiến thức cơ bản về đường dẫn") và cách sử dụng JSP / Servlet đúng cách bằng các hướng dẫn đó .
Xem thêm:
Cập nhật : theo cập nhật câu hỏi của bạn (điều này khá quan trọng, bạn không nên xóa các phần của câu hỏi ban đầu của mình, điều này sẽ làm cho các câu trả lời trở nên vô giá trị .. thay vì thêm thông tin vào một khối mới), hóa ra là bạn không cần thiết đặt kiểu mã hóa của biểu mẫu thành multipart/form-data
. Điều này sẽ gửi các tham số yêu cầu trong một thành phần khác với (mặc định) application/x-www-form-urlencoded
gửi tham số yêu cầu dưới dạng một chuỗi truy vấn (ví dụ name1=value1&name2=value2&name3=value3
:). Bạn chỉ cần multipart/form-data
bất cứ khi nào bạn có<input type="file">
phần tử trong biểu mẫu để tải lên tệp có thể là dữ liệu không phải ký tự (dữ liệu nhị phân). Đây không phải là trường hợp của bạn, vì vậy chỉ cần gỡ bỏ nó và nó sẽ hoạt động như mong đợi. Nếu bạn cần tải lên tệp, thì bạn sẽ phải đặt kiểu mã hóa như vậy và tự phân tích cú pháp nội dung yêu cầu. Thông thường, bạn sử dụng Apache Commons FileUpload ở đó, nhưng nếu bạn đã sử dụng API Servlet 3.0 mới, thì bạn chỉ có thể sử dụng các tiện ích nội trang bắt đầu với HttpServletRequest#getPart()
. Xem thêm câu trả lời này để biết ví dụ cụ thể: Làm thế nào để tải tệp lên máy chủ bằng JSP / Servlet?