doGet dan doPost di Servlets

105

Saya telah mengembangkan halaman HTML yang mengirimkan informasi ke Servlet. Di Servlet, saya menggunakan metode doGet()dan 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");
}

Pada kode halaman html yang memanggil Servlet adalah:

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

Ketika saya menggunakan method = "get"di Servlet, saya mendapatkan nilai id dan kata sandi, namun saat menggunakan method = "post", id dan kata sandi diatur ke null. Mengapa saya tidak mendapatkan nilai dalam kasus ini?

Hal lain yang ingin saya ketahui adalah bagaimana menggunakan data yang dihasilkan atau divalidasi oleh Servlet. Misalnya, jika Servlet yang ditunjukkan di atas mengautentikasi pengguna, saya ingin mencetak id pengguna di halaman HTML saya. Saya harus dapat mengirim string 'id' sebagai tanggapan dan menggunakan info ini di halaman HTML saya. Apa itu mungkin?

dedalo
sumber
Bagaimana Anda menggunakan metode posting di html?
Igor Artamonov
Dan juga, untuk apa Anda membutuhkan loop aneh atas nama parameter?
Igor Artamonov
1
Sudahkah Anda mencoba menghapus `enctype = multipart / form-data`? Saya curiga itu masalah Anda.
Jack Leow
Itu dia. Mengapa posting tidak berfungsi saat ini ada? Terima kasih atas bantuan Anda!
dedalo

Jawaban:

197

pengantar

Anda harus menggunakan doGet()saat Anda ingin mencegat permintaan HTTP GET . Anda harus menggunakan doPost()saat Anda ingin mencegat permintaan HTTP POST . Itu saja. Jangan porting yang satu ke yang lain atau sebaliknya (seperti dalam processRequest()metode auto-generated Netbeans yang malang ). Ini tidak masuk akal.

DAPATKAN

Biasanya, permintaan HTTP GET bersifat idempoten . Misalnya, Anda mendapatkan hasil yang persis sama setiap kali menjalankan permintaan (meninggalkan otorisasi / otentikasi dan sifat halaman yang sensitif terhadap waktu — hasil penelusuran, berita terakhir, dll — di luar pertimbangan). Kita dapat berbicara tentang permintaan yang dapat di-bookmark. Mengklik link, mengklik bookmark, memasukkan URL mentah di bilah alamat browser, dan lain-lain semua akan mengaktifkan permintaan HTTP GET. Jika Servlet mendengarkan pada URL yang dimaksud, maka doGet()metodenya akan dipanggil. Ini biasanya digunakan untuk preprocess permintaan. Yaitu melakukan beberapa hal bisnis sebelum menampilkan output HTML dari JSP, seperti mengumpulkan data untuk ditampilkan dalam tabel.

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

Juga lihat / edit link detail seperti yang ditunjukkan pada kolom terakhir di atas biasanya idempoten.

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

POS

Permintaan HTTP POST tidak idempoten. Jika pengguna akhir telah mengirimkan formulir POST pada URL sebelumnya, yang belum melakukan pengalihan, maka URL tersebut belum tentu dapat di-bookmark. Data formulir yang dikirimkan tidak tercermin dalam URL. Menyalin URL ke dalam jendela / tab browser baru mungkin tidak selalu memberikan hasil yang sama persis seperti setelah formulir dikirim. URL seperti itu tidak dapat di-bookmark. Jika Servlet mendengarkan di URL yang dimaksud, maka itu doPost()akan dipanggil. Biasanya digunakan untuk memproses permintaan. Yaitu mengumpulkan data dari formulir HTML yang dikirimkan dan melakukan beberapa hal bisnis dengannya (konversi, validasi, menyimpan di DB, dan sebagainya). Akhirnya biasanya hasilnya disajikan sebagai HTML dari halaman JSP yang diteruskan.

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

... yang dapat digunakan dalam kombinasi dengan bagian Servlet ini:

@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);
        }
    }

}

Anda lihat, jika Userditemukan di DB (yaitu nama pengguna dan kata sandi valid), maka Userakan dimasukkan ke dalam ruang lingkup sesi (yaitu "masuk") dan servlet akan mengarahkan ke beberapa halaman utama (contoh ini pergi ke http://example.com/contextname/home), jika tidak itu akan menetapkan pesan kesalahan dan meneruskan permintaan kembali ke halaman JSP yang sama sehingga pesan tersebut ditampilkan ${error}.

Anda dapat jika perlu juga "menyembunyikan" login.jspin /WEB-INF/login.jspsehingga pengguna hanya dapat mengaksesnya dengan servlet. Ini membuat URL tetap bersih http://example.com/contextname/login. Yang perlu Anda lakukan adalah menambahkan a doGet()ke servlet seperti ini:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}

(dan perbarui baris yang sama doPost())

Meskipun demikian, saya tidak yakin apakah itu hanya bermain-main dan memotret dalam kegelapan, tetapi kode yang Anda posting tidak terlihat bagus (seperti menggunakan compareTo()alih-alih equals()dan menggali nama parameter alih-alih hanya menggunakan getParameter()dan iddan passwordtampaknya dideklarasikan sebagai variabel instance servlet - yang BUKAN threadsafe ). Jadi saya sangat menyarankan untuk mempelajari lebih lanjut tentang Java SE API dasar menggunakan tutorial Oracle (periksa bab "Trails Covering the Basics") dan bagaimana menggunakan JSP / Servlets dengan cara yang benar menggunakan tutorial tersebut .

Lihat juga:


Pembaruan : sesuai pembaruan pertanyaan Anda (yang cukup besar, Anda tidak boleh menghapus sebagian dari pertanyaan asli Anda, ini akan membuat jawaban tidak berharga .. melainkan tambahkan informasi di blok baru), ternyata Anda tidak perlu menyetel jenis pengkodean formulir ke multipart/form-data. Ini akan mengirimkan parameter permintaan dalam komposisi yang berbeda dari (default) application/x-www-form-urlencodedyang mengirimkan parameter permintaan sebagai string kueri (misalnya name1=value1&name2=value2&name3=value3). Anda hanya perlu multipart/form-datajika Anda memiliki file<input type="file">elemen berupa file untuk mengupload yang mungkin berupa data non-karakter (data biner). Ini tidak terjadi dalam kasus Anda, jadi hapus saja dan itu akan berfungsi seperti yang diharapkan. Jika Anda perlu mengunggah file, Anda harus menyetel jenis pengkodean dan mengurai sendiri isi permintaan. Biasanya Anda menggunakan Apache Commons FileUpload di sana, tetapi jika Anda sudah menggunakan Servlet 3.0 API baru, maka Anda bisa menggunakan fasilitas bawaan yang dimulai dengan HttpServletRequest#getPart(). Lihat juga jawaban ini untuk contoh nyata: Bagaimana cara mengupload file ke server menggunakan JSP / Servlet?

BalusC
sumber
2

Baik GET dan POST digunakan oleh browser untuk meminta satu sumber daya dari server. Setiap sumber daya membutuhkan permintaan GET atau POST terpisah.

  1. Metode GET paling umum (dan merupakan metode default) digunakan oleh browser untuk mengambil informasi dari server. Saat menggunakan metode GET, bagian ke-3 dari paket permintaan, yaitu badan permintaan, tetap kosong.

Metode GET digunakan dalam salah satu dari dua cara: Jika tidak ada metode yang ditentukan, saat itulah Anda atau browser meminta sumber daya sederhana seperti halaman HTML, gambar, dll. Saat formulir dikirimkan, dan Anda memilih metode = DAPATKAN di tag HTML. Jika metode GET digunakan dengan formulir HTML, maka data yang dikumpulkan melalui formulir dikirim ke server dengan menambahkan "?" di akhir URL, lalu menambahkan semua pasangan nama = nilai (nama bidang formulir html dan nilai yang dimasukkan di bidang itu) dipisahkan oleh tanda "&" Contoh: GET /sultans/shop//form1.jsp?name= Sam% 20Sultan & iceCream = vanilla HTTP / 1.0 header opsional header opsional << baris kosong >>>

Data formulir nama = nilai akan disimpan dalam variabel lingkungan yang disebut QUERY_STRING. Variabel ini akan dikirim ke program pemrosesan (seperti JSP, Java servlet, PHP, dll.)

  1. Metode POST digunakan saat Anda membuat formulir HTML, dan metode permintaan = POST sebagai bagian dari tag. Metode POST memungkinkan klien untuk mengirim data formulir ke server di bagian isi permintaan (seperti yang dibahas sebelumnya). Data dikodekan dan diformat mirip dengan metode GET, kecuali bahwa data dikirim ke program melalui input standar.

Contoh: POST /sultans/shop//form1.jsp HTTP / 1.0 header opsional header opsional << baris kosong >>> name = Sam% 20Sultan & iceCream = vanilla

Saat menggunakan metode posting, variabel lingkungan QUERY_STRING akan kosong. Keuntungan / Kerugian GET vs. POST

Keuntungan metode GET: Sedikit lebih cepat Parameter dapat dimasukkan melalui formulir atau dengan menambahkannya setelah Halaman URL dapat ditandai dengan parameternya

Kekurangan metode GET: Hanya dapat mengirim data senilai 4K. (Anda tidak boleh menggunakannya saat menggunakan bidang textarea) Parameter terlihat di akhir URL

Keuntungan metode POST: Parameter tidak terlihat di akhir URL. (Gunakan untuk data sensitif) Dapat mengirim lebih dari data senilai 4K ke server

Kekurangan metode POST: Tidak dapat ditandai dengan datanya

S. Mayol
sumber
0

Implementasi metode HttpServlet.service () penampung servlet akan secara otomatis meneruskan ke doGet () atau doPost () jika diperlukan, jadi Anda tidak perlu mengganti metode layanan.

Jay Jackson
sumber
0

Mungkinkah Anda meneruskan data melalui get, bukan post?

<form method="get" ..>
..
</form>
Tom
sumber
0

Jika Anda melakukannya <form action="identification" >untuk formulir html Anda, data akan diteruskan menggunakan 'Get' secara default dan karenanya Anda dapat menangkapnya menggunakan fungsi doGet di kode servlet java Anda. Dengan cara ini data akan diteruskan di bawah tajuk HTML dan karenanya akan terlihat di URL saat dikirimkan. Di sisi lain, jika Anda ingin meneruskan data dalam HTML body, maka GUNAKAN Postingan: <form action="identification" method="post">dan tangkap data ini dalam fungsi doPost. Ini sebelumnya, data akan dikirimkan di bawah badan html dan bukan header html, dan Anda tidak akan melihat data di URL setelah mengirimkan formulir.

Contoh dari html saya:

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

Contoh dari kode servlet java saya:

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

.........
.........
Uzair Zaman Sheikh
sumber