doGet và doPost trong Servlets


105

Tôi đã phát triển một trang HTML gửi thông tin đến Servlet. Trong Servlet, tôi đang sử dụng các phương thức 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");
}

Trong mã trang html gọi Servlet là:

<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> 

Khi tôi sử dụng method = "get"trong Servlet, tôi nhận được giá trị của id và mật khẩu, tuy nhiên khi sử dụng method = "post", id và mật khẩu được đặt thành null. Tại sao tôi không nhận được các giá trị trong trường hợp này?

Một điều khác tôi muốn biết là cách sử dụng dữ liệu được tạo hoặc xác thực bởi Servlet. Ví dụ: nếu Servlet được hiển thị ở trên xác thực người dùng, tôi muốn in id người dùng trong trang HTML của mình. Tôi có thể gửi chuỗi 'id' dưới dạng phản hồi và sử dụng thông tin này trong trang HTML của mình. Nó có khả thi không?


Bạn đang sử dụng phương pháp đăng bài tại html như thế nào?
Igor Artamonov

Và ngoài ra, điều gì đối với bạn cần vòng lặp lạ lùng trên các tên tham số?
Igor Artamonov

1
Bạn đã thử xóa `enctype = Multiart / form-data` chưa? Tôi nghi ngờ đó là vấn đề của bạn.
Jack Leow

Điều đó là vậy đó. Tại sao không đăng công việc khi điều này hiện tại? Cảm ơn bạn đã giúp đỡ!
debalo

Câu trả lời:


197

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 Usertì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 đó Usersẽ đượ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.jsptrong /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()idpassworddườ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-urlencodedgử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-databấ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?


2

Cả GET và POST đều được trình duyệt sử dụng để yêu cầu một tài nguyên duy nhất từ ​​máy chủ. Mỗi tài nguyên yêu cầu một yêu cầu GET hoặc POST riêng biệt.

  1. Phương thức GET phổ biến nhất (và là phương thức mặc định) được các trình duyệt sử dụng để lấy thông tin từ máy chủ. Khi sử dụng phương thức GET, phần thứ 3 của gói yêu cầu, là phần thân của yêu cầu, vẫn trống.

Phương thức GET được sử dụng theo một trong hai cách: Khi không có phương pháp nào được chỉ định, đó là khi bạn hoặc trình duyệt đang yêu cầu một tài nguyên đơn giản như trang HTML, hình ảnh, v.v. Khi một biểu mẫu được gửi và bạn chọn phương thức = NHẬN trên thẻ HTML. Nếu phương thức GET được sử dụng với biểu mẫu HTML, thì dữ liệu được thu thập thông qua biểu mẫu sẽ được gửi đến máy chủ bằng cách thêm dấu "?" vào cuối URL, sau đó thêm tất cả các cặp name = value (tên của trường biểu mẫu html và giá trị được nhập vào trường đó) được phân tách bằng dấu "&" Ví dụ: GET /sultans/shop//form1.jsp?name= Sam% 20Sultan & iceCream = vani HTTP / 1.0 tiêu đề tùy chọn theo tiêu đề << dòng trống >>>

Dữ liệu dạng name = value sẽ được lưu trữ trong một biến môi trường có tên QUERY_STRING. Biến này sẽ được gửi đến một chương trình xử lý (chẳng hạn như JSP, Java servlet, PHP, v.v.)

  1. Phương thức POST được sử dụng khi bạn tạo biểu mẫu HTML và yêu cầu phương thức = POST như một phần của thẻ. Phương thức POST cho phép máy khách gửi dữ liệu biểu mẫu đến máy chủ trong phần nội dung yêu cầu của yêu cầu (như đã thảo luận trước đó). Dữ liệu được mã hóa và được định dạng tương tự như phương pháp GET, ngoại trừ việc dữ liệu được gửi đến chương trình thông qua đầu vào chuẩn.

Ví dụ: POST /sultans/shop//form1.jsp HTTP / 1.0 tiêu đề tùy chọn theo tiêu đề << dòng trống >>> name = Sam% 20Sultan & iceCream = vani

Khi sử dụng phương pháp đăng, biến môi trường QUERY_STRING sẽ trống. Ưu điểm / Nhược điểm của GET so với POST

Ưu điểm của phương pháp GET: Nhanh hơn một chút Các thông số có thể được nhập qua biểu mẫu hoặc bằng cách thêm chúng sau khi Trang URL có thể được đánh dấu bằng các tham số của nó

Nhược điểm của phương pháp GET: Chỉ có thể gửi dữ liệu có giá trị 4K. (Bạn không nên sử dụng nó khi sử dụng trường textarea) Các thông số hiển thị ở cuối URL

Ưu điểm của phương pháp POST: Các tham số không hiển thị ở cuối URL. (Sử dụng cho dữ liệu nhạy cảm) Có thể gửi nhiều dữ liệu có giá trị 4K đến máy chủ

Nhược điểm của phương pháp POST: Không thể được đánh dấu bằng dữ liệu của nó


0

Việc triển khai phương thức HttpServlet.service () của vùng chứa servlet sẽ tự động chuyển tiếp đến doGet () hoặc doPost () khi cần thiết, vì vậy bạn không cần phải ghi đè phương thức dịch vụ.


0

Có thể là bạn đang chuyển dữ liệu thông qua get chứ không phải post?

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

0

Nếu bạn làm <form action="identification" >cho biểu mẫu html của mình, dữ liệu sẽ được chuyển bằng cách sử dụng 'Get' theo mặc định và do đó bạn có thể nắm bắt điều này bằng cách sử dụng hàm doGet trong mã servlet java của bạn. Theo cách này, dữ liệu sẽ được chuyển dưới tiêu đề HTML và do đó sẽ hiển thị trong URL khi được gửi. Mặt khác, nếu bạn muốn truyền dữ liệu trong nội dung HTML, hãy sử dụng Bài viết: <form action="identification" method="post">và bắt dữ liệu này trong hàm doPost. Điều này là, dữ liệu sẽ được chuyển dưới nội dung html chứ không phải tiêu đề html và bạn sẽ không thấy dữ liệu trong URL sau khi gửi biểu mẫu.

Ví dụ từ html của tôi:

<body>  
<form action="StartProcessUrl" method="post">
.....
.....

Ví dụ từ mã java servlet của tôi:

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");

.........
.........
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.