JavaRush /Blog Java /Random-MS /Mencipta aplikasi web mudah menggunakan servlets dan jsp ...

Mencipta aplikasi web mudah menggunakan servlets dan jsp (bahagian 1)

Diterbitkan dalam kumpulan
Tahap pengetahuan yang diperlukan untuk memahami artikel: anda sudah lebih kurang memahami Java Core dan ingin melihat teknologi JavaEE dan pengaturcaraan web. Ia paling masuk akal jika anda sedang mengkaji pencarian Java Collections, yang merangkumi topik yang hampir dengan artikel. Mencipta aplikasi web mudah menggunakan servlets dan jsp (bahagian 1) - 1Bahan ini adalah kesinambungan logik artikel saya Mencipta projek web mudah dalam IntelliJ Idea Enterprise . Di dalamnya saya menunjukkan cara membuat templat projek web yang berfungsi. Kali ini saya akan menunjukkan kepada anda cara membuat aplikasi web yang ringkas tetapi cantik menggunakan Java Servlet API dan teknologi JavaServer Pages API. Permohonan kami akan mempunyai halaman utama dengan dua pautan:
  • ke halaman penambahan pengguna;
  • ke halaman paparan senarai pengguna.
Saya masih akan menggunakan IntelliJ Idea Enterprise Edition, Apache Maven (hanya sertakan beberapa kebergantungan) dan Apache Tomcat. Pada akhirnya, kami akan "menghias" aplikasi kami menggunakan rangka kerja W3.CSS . Kami akan menganggap bahawa pada masa ini anda sudah mempunyai projek kosong, yang akan kami bangunkan di sini. Jika tidak, baca artikel pertama dan buat. Ia akan mengambil masa beberapa minit sahaja :)

Sedikit tentang struktur aplikasi masa hadapan

Halaman utama kami ( / ) akan menjadi halaman html statik yang paling biasa dengan pengepala dan dua pautan/butang:
  • tambah pengguna baharu (akan dihantar ke /add );
  • lihat senarai pengguna (hantar ke /list ).
Tomcat akan menangkap permintaan ke alamat ini dan menghantarnya ke salah satu daripada dua servlet yang akan kami buat (kami akan menerangkan pemetaan dalam fail web.xml ). Dan servlet, seterusnya, akan memproses permintaan, menyediakan data (atau menyimpannya jika pengguna ditambah), dan memindahkan kawalan ke fail jsp yang sepadan, yang akan "memberikan" hasilnya. Kami akan menyimpan data dalam senarai paling biasa (Senarai).

Mari buat halaman utama statik

Jika anda mempunyai index.jsp dalam folder web anda , padamkannya. Sebaliknya, dalam folder ini kami akan mencipta fail html ringkas yang dipanggil index.html :
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My super project!</title>
</head>
<body>
    <!-- header -->
    <div>
        <h1>Super app!<//h1>
    </div>

    <div>       <!-- content -->
        <div>    <!-- buttons holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
Tidak ada yang rumit di sini. Dalam tajuk kami menunjukkan tajuk halaman kami. Dalam badan halaman kita mempunyai dua div utama: pengepala (header) dan kandungan (kandungan). Dalam kandungan kami mempunyai pemegang untuk butang kami, dan sebenarnya dua butang yang, apabila diklik, dihantar ke alamat yang sesuai. Anda boleh menjalankan projek dan melihat rupanya sekarang. Jika anda mengklik pada butang, halaman dengan ralat 404 dibuka kerana kami belum mempunyainya lagi. Tetapi ini menunjukkan bahawa butang berfungsi. Biar saya ambil perhatian bahawa ini bukan pilihan yang paling universal, kerana jika anda tiba-tiba mempunyai JavaScript dilumpuhkan, butang ini tidak akan berguna dalam penyemak imbas. Tetapi kami akan menganggap bahawa tiada siapa yang melumpuhkan JavaScript :). Sudah jelas bahawa pautan mudah boleh digunakan, tetapi saya lebih suka butang. Awak buat apa yang awak suka. Dan jangan lihat fakta bahawa dalam contoh saya akan ada banyak div . Kemudian kami akan mengisi mereka dengan gaya, dan semuanya akan kelihatan lebih cantik :).

Buat fail jsp untuk memaparkan hasilnya

Dalam direktori web yang sama , kami akan mencipta folder di mana kami akan meletakkan fail jsp kami . Saya memanggilnya sebagai pandangan, dan sekali lagi, anda boleh membuat improvisasi. Dalam folder ini kami akan membuat dua fail jsp:
  • add.jsp — halaman untuk menambah pengguna;
  • list.jsp - halaman untuk memaparkan senarai pengguna.
Mari beri mereka tajuk halaman yang sesuai. Sesuatu seperti "Tambah pengguna baharu" dan "senarai pengguna", dan kami akan membiarkannya begitu buat masa ini.

Mari buat dua servlet

Servlets akan menerima dan memproses permintaan yang Tomcat akan berikan kepada mereka. Dalam folder src/main/java kami akan mencipta pakej aplikasi , yang akan mengandungi sumber kami. Di sana kita akan mempunyai lebih banyak pakej yang berbeza. Oleh itu, supaya pakej ini tidak dicipta di dalam satu sama lain, mari buat beberapa kelas dalam pakej aplikasi (kemudian padamkannya). Sekarang mari kita buat tiga pakej berbeza dalam pakej aplikasi :
  • entiti - di sinilah entiti kami akan terletak (kelas itu sendiri, yang akan menerangkan objek pengguna);
  • model - model kami akan berada di sini (lebih lanjut mengenai ini sedikit kemudian);
  • servlets - baiklah, inilah servlets kami.
Selepas ini, anda boleh mengalih keluar kelas itu dengan selamat daripada pakej apl (jika anda menciptanya, sudah tentu). Dalam pakej servlets kami akan mencipta dua kelas:
  • AddServlet - akan memproses permintaan yang diterima di /add ;
  • ListServlet - akan memproses permintaan yang diterima di /list .

Menyambung kebergantungan dalam Maven

Tomcat versi 9.* melaksanakan spesifikasi Servlet versi 4.0 dan JavaServer Pages versi 2.3. Ini ditulis dalam dokumentasi rasmi Tomcat 9 dalam perenggan pertama dalam baris kedua. Ini bermakna jika anda, seperti saya, menggunakan versi Tomcat ini, maka kod yang kami tulis dan hantar untuk dijalankan akan menggunakan versi yang ditentukan. Tetapi kami ingin mempunyai spesifikasi ini dalam projek kami, supaya kod kami yang menggunakannya sekurang-kurangnya berjaya disusun. Dan untuk ini kami perlu memuatkannya ke dalam projek kami. Di sinilah Maven datang untuk menyelamatkan.

Peraturan umum adalah ini: jika anda perlu menyambungkan sesuatu ke projek anda menggunakan Maven:

  • pergi ke laman web repositori Maven;
  • cari di sana untuk perpustakaan yang anda perlukan dan versi yang anda perlukan;
  • anda mendapat kod pergantungan yang perlu dimasukkan ke dalam pom.xml anda;
  • masukkan! :)
Jadi mari kita mulakan. Mula-mula, mari sediakan fail pom . Di suatu tempat selepas /version tetapi sebelum /project , masukkan yang berikut:
<dependencies>

</dependencies>
Oleh itu, kami menunjukkan bahawa di dalam tag ini kami akan menyenaraikan kebergantungan yang kami perlukan. Sekarang pergi ke mvnrepository.com , akan ada medan carian di bahagian atas. Pertama, masukkan servlet ke dalam carian. Hasil pertama, di mana terdapat lebih daripada tujuh ribu kegunaan, sesuai dengan kami. Kami ingat bahawa kami memerlukan versi 4.0 (untuk Tomcat 9; untuk versi lain, pelaksanaan yang lebih lama mungkin sesuai). Ini adalah versi yang agak baru-baru ini, jadi tidak banyak kegunaan, tetapi ia adalah yang kami perlukan. Halaman akan dibuka di mana anda boleh mendapatkan kod untuk pergantungan ini untuk pelbagai pengurus pakej dan anda juga boleh memuat turunnya sahaja. Tetapi kerana kami ingin menyambungkannya menggunakan Maven, kami memilih kod pada tab Maven. Kami menyalin dan menampal ke dalam fail pom kami di dalam bahagian dependencies. Jika pemberitahuan muncul di penjuru kanan sebelah bawah IDEA yang bertanya sama ada kami mahu mendayakan autoimport, kami bersetuju. Jika anda menolak secara tidak sengaja, pergi ke "Tetapan" dan dayakan auto-import secara manual: Tetapan (Ctrl + Alt + S) -> Bina, Pelaksanaan, Deployment -> Maven -> Import Ini akan menyimpan fail pom dan fail konfigurasi IDEA untuk ini projek secara serentak. Sekarang, menggunakan prinsip yang sama, kami akan mencari dan menyambungkan JavaServer Pages versi 2.3 (masukkan jsp dalam carian). Dan memandangkan kami telah pun menggunakan Maven, mari kita beritahu dengan segera bahawa sumber kami mematuhi sintaks Java 8, dan ia perlu dikompilasi ke dalam bytecode versi yang sama. Selepas semua manipulasi ini, pom.xml kami akan kelihatan seperti ini:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ru.javarush.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compile.source>
        <maven.compiler.target>1.8</maven.compile.target>
    </properties>

    <dependencies>
        <!-- Servlet API 4.0 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JavaServer Pages API 2.3 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

Menjadikan servlet kami sebagai servlet sebenar

Pada ketika ini, beberapa servlet yang kami cipta sebenarnya hanyalah kelas biasa. Mereka tidak mempunyai sebarang fungsi. Tetapi sekarang kami telah menyambungkan API Servlet kepada projek kami, dan, jika ya, kami boleh menggunakan kelas dari sana. Untuk menjadikan servlet kami "sebenar" servlet, kami hanya perlu mewarisinya daripada kelas HttpServlet .

Pemetaan atau pembahagian

Sekarang adalah baik untuk memberitahu Tomcat supaya permintaan daripada /add dikendalikan oleh AddServlet servlet kami , dan oleh itu permintaan daripada /list dikendalikan oleh ListServlet servlet . Proses ini dipanggil pemetaan . Ini dilakukan dalam fail web.xml mengikut prinsip ini:
  • mula-mula kita menerangkan servlet (kami memberikan beberapa nama dan menunjukkan laluan ke kelas itu sendiri);
  • kemudian kami mengikat servlet ini ke alamat tertentu (kami menunjukkan nama servlet yang baru kami berikan dan menunjukkan alamat dari mana permintaan harus dihantar ke servlet ini).
Mari kita terangkan servlet:
<servlet>
    <servlet-name>add</servlet-name>
    <servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
Sekarang kita mengikatnya ke alamat:
<servlet-mapping>
    <servlet-name>add</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
Seperti yang anda lihat, nama servlet adalah sama dalam kedua-dua kes. Terima kasih kepada ini, Tomcat tahu bahawa jika permintaan datang ke /add address , ia perlu dihantar ke app.servlets.AddServlet servlet . Kami melakukan perkara yang sama dengan servlet kedua. Akibatnya, web.xml kami mempunyai lebih kurang kandungan berikut:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- add servlet -->
    <servlet>
        <servlet-name>add</servlet-name>
        <servlet-class>app.servlets.AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>add</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>

    <!-- list servlet -->
    <servlet>
        <servlet-name>list</servlet-name>
        <servlet-class>app.servlets.ListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>list</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>
</web-app>
Ngomong-ngomong, kami tidak membuat penanda untuk halaman utama di sini (di / ). Hakikatnya ialah dalam kes ini kita tidak memerlukannya. Halaman utama kami ialah fail html ringkas yang hanya memaparkan dua butang. Tiada kandungan dinamik, jadi tidak masuk akal untuk kami membuat servlet berasingan untuknya, yang mana permintaan daripada alamat / akan dihantar , dan yang tidak akan melakukan apa-apa kecuali memindahkan pelaksanaan ke beberapa jsp (yang juga perlu dicipta), yang akan menarik Sekiranya kita mempunyai dua butang. Kami tidak memerlukan ini; kami gembira dengan sumber statik. Apabila Tomcat menerima permintaan, ia akan menyemak bahawa tidak ada satu servlet yang boleh memproses permintaan pada alamat sedemikian, dan kemudian ia akan melihat bahawa pada alamat ini sebenarnya terdapat fail html siap sedia , yang akan berjaya dihantar . Kami boleh menjalankan aplikasi kami sekali lagi (mulakan semula pelayan atau gunakan semula, seperti yang anda mahu) dan pastikan halaman utama dipaparkan, tiada apa-apa yang rosak, apabila kami mengklik pada butang, peralihan berlaku, tetapi buat masa ini ralat juga berlaku bertulis. Ngomong-ngomong, jika sebelum ini kami mempunyai ralat 404, kini kami mempunyai 405. Ini bermakna pemetaan berfungsi, servlet telah ditemui, tetapi mereka tidak mempunyai sebarang kaedah yang sesuai untuk memproses permintaan. Jika pada peringkat ini anda masih mendapat ralat 404, walaupun semuanya telah dilakukan dengan betul, mungkin anda perlu membetulkan konfigurasi penggunaan dalam idea tersebut. Untuk melakukan ini, anda perlu pergi ke Edit konfigurasi (di bahagian atas berhampiran butang mula), pergi ke tab Deployment di sebelah kanan tetingkap dan pastikan bahawa dalam konteks Aplikasi ia hanya ditunjukkan /

Penyimpangan lirik pendek: apa yang berlaku "di bawah tudung"?

Anda mungkin sudah tertanya-tanya bagaimana aplikasi kami berfungsi dalam Tomcat? Apa yang berlaku di sana? Dan di manakah kaedah main() ? Sebaik sahaja anda menaip localhost:8080 ke dalam penyemak imbas anda dan pergi ke alamat ini, penyemak imbas menghantar permintaan ke alamat ini melalui protokol http . Saya harap anda sudah sedia maklum bahawa permintaan boleh terdiri daripada "jenis" yang berbeza, yang paling popular ialah GET dan POST . Setiap permintaan pasti ada jawapan. Permintaan GET menjangkakan bahawa sebagai tindak balas ia akan diberikan kod html siap pakai , yang akan dikembalikan kepada penyemak imbas, dan penyemak imbas akan menggantikan kod ini dengan pelbagai jenis huruf, butang dan borang. Permintaan POST adalah sedikit lebih menarik, kerana ia juga membawa beberapa maklumat bersamanya. Sebagai contoh, dalam borang pendaftaran atau kebenaran pengguna, anda memasukkan data anda dan mengklik "hantar". Pada masa ini, permintaan POST telah dihantar ke pelayan dengan maklumat peribadi anda di dalamnya. Pelayan menerima maklumat ini, memprosesnya dan mengembalikan beberapa jenis respons (contohnya, halaman html dengan profil anda). Perbezaan asas di antara mereka ialah permintaan GET hanya bertujuan untuk menerima data daripada pelayan, manakala permintaan POST membawa beberapa maklumat bersamanya, dan data pada pelayan mungkin berubah (contohnya, apabila anda memuat naik foto anda ke pelayan, ia akan terbang dalam permintaan POST dan pelayan akan menambahnya ke pangkalan data, iaitu, beberapa perubahan akan berlaku. Sekarang mari kita kembali ke Tomcat. Apabila ia menerima beberapa permintaan daripada klien, ia melihat alamat. Mencari datanya ke lihat jika terdapat servlet yang sesuai, yang akan memproses permintaan ke alamat sedemikian (atau sumber siap sedia yang boleh dikembalikan dengan segera). Jika ia tidak menemui apa-apa untuk dikembalikan, ia tidak bertindak balas dengan halaman html, tetapi dengan respons 404. Jika ia menemui servlet yang sesuai, yang "duduk" pada alamat ini, ia melihat jenis permintaan yang diterima (GET, POST, atau yang lain), dan kemudian bertanya servlet jika ia mempunyai kaedah yang boleh mengendalikan permintaan jenis ini. Jika servlet mengatakan, bahawa ia tidak boleh memproses jenis ini, Tomcat bertindak balas kepada pelanggan dengan kod 405. Inilah yang baru berlaku kepada kami. Tetapi jika servlet yang sesuai ditemui, dan ia mempunyai kaedah yang sesuai, Tomcat mencipta objek servlet ini, menjalankannya dalam thread baru ( thread ), yang membolehkan servlet berfungsi dalam thread yang berasingan, dan Tomcat terus bekerja lebih jauh sendiri, menerima dan menghantar permintaan. Selain itu, Tomcat mencipta dua lagi objek: satu daripada jenis HttpServletRequest (saya akan memanggilnya secara ringkas sebagai permintaan pada masa hadapan), dan yang kedua jenis HttpServletResponse(Saya akan memanggilnya sebagai jawapan). Dalam objek pertama ia meletakkan semua data yang diterima dalam permintaan daripada klien, jadi semua data itu boleh ditarik keluar dari objek ini. Nah, selepas semua ini, ia menghantar kedua-dua objek ini kepada kaedah servlet yang sesuai yang berjalan dalam benang berasingan. Sebaik sahaja servlet menyelesaikan kerjanya dan mempunyai respons yang sedia untuk dihantar kepada pelanggan, ia menaikkan bendera kepada Tomcat, berkata, "Saya sudah selesai, semuanya sudah sedia." Tomcat menerima respons dan menghantarnya kepada pelanggan. Ini membolehkan Tomcat menerima permintaan dan menghantar respons tanpa gangguan, manakala semua kerja dilakukan oleh servlet yang berjalan dalam benang berasingan. Sehubungan itu, apabila kita menulis kod servlet, kita menentukan kerja yang akan dilakukan. Dan ya, anda boleh memikirkan kaedah main() sebagai dalam Tomcat sendiri (ya, ia ditulis dalam Java), dan apabila kita "memulakan" Tomcat, main().

Kami menangkap kaedah GET dengan servlet dan menghantar respons mudah

Pada masa ini, servlet kami tidak mempunyai kaedah yang sesuai (GET), jadi Tomcat mengembalikan ralat 405 kepada kami. Mari kita buat! Kelas HttpServlet , dari mana kami mewarisi servlet kami, mentakrifkan kaedah yang berbeza. Untuk menetapkan beberapa kod untuk kaedah, kami hanya mengatasinya. Dalam kes ini, kita perlu mengatasi kaedah doGet() dalam kedua-dua servlet.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
Seperti yang anda lihat, kaedah ini menerima dua objek: req (permintaan) dan resp (tindak balas). Ini adalah objek yang akan dibuat dan diisi oleh Tomcat untuk kita apabila ia memanggil kaedah yang sesuai dalam servlet ini. Pertama, mari kita lakukan jawapan yang paling mudah. Untuk melakukan ini, ambil objek resp dan dapatkan daripadanya objek PrintWriter , yang boleh digunakan untuk mengarang respons. Nah, menggunakannya kami akan mencetak beberapa rentetan mudah.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("Method GET from AddServlet");
}
Kami akan melakukan sesuatu yang serupa dalam servlet ListServlet , selepas itu kami akan memulakan pelayan kami semula. Seperti yang anda lihat, semuanya berfungsi! Apabila anda mengklik pada butang, halaman dibuka dengan teks yang kami "rakam" dengan PrintWriter . Cuma jsp kami yang kami sediakan untuk menjana halaman dengan jawapan tidak digunakan dalam apa jua cara. Ini kerana pelaksanaan itu tidak sampai kepada mereka. Serverlet itu sendiri kini menjana respons dan menyelesaikan kerjanya, menandakan Tomcat bahawa ia mempunyai respons sedia untuk pelanggan. Tomcat hanya mengambil respons ini dan menghantarnya kembali kepada pelanggan. Kami memindahkan kawalan daripada servlet ke jsp. Mari tukar kod kaedah kami dengan cara ini:
  • kami mendapat daripada objek permintaan objek pengurus permintaan, di mana kami menghantar alamat jsp halaman yang kami ingin pindahkan kawalan;
  • menggunakan objek yang diterima, kami memindahkan kawalan ke halaman jsp yang ditentukan , dan jangan lupa untuk melampirkan di sana objek permintaan dan respons yang kami terima daripada Tomcat.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
Dalam badan halaman jsp (di dalam teg badan) kita boleh menulis sesuatu supaya kita dapat melihat dengan jelas halaman mana yang dipaparkan. Selepas itu, kami mulakan semula pelayan dan semak. Butang pada halaman utama ditekan, halaman dibuka, yang bermaksud permintaan dihantar ke servlet, selepas itu kawalan dipindahkan ke halaman jsp, yang telah diberikan. Itu sahaja. Dalam bahagian seterusnya artikel kami akan berurusan dengan fungsi aplikasi kami.

Apa lagi yang perlu dibaca:

Mencipta projek web mudah dalam IntelliJ Idea Enterprise. Langkah demi langkah, dengan gambar


Sembang saya
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION