Isi:
- Perkenalan
- Membuat Proyek
- Koneksi pegas MVC
- Membuat Halaman dan Pengontrol
- Konfigurasi
- Model
- Pengontrol Tampilan Model
Perkenalan
Saya mulai mengenal teknologi dan kerangka kerja yang baru bagi saya dengan mempelajari berbagai contoh penggunaannya, karena biasanya saya memahami sesuatu dengan baik ketika saya melihatnya beraksi menggunakan contoh aplikasi yang lengkap. Biasanya, contoh seperti itu adalah aplikasi CRUD ( C reate, Read , U pdate, D elete), Internet penuh dengan contoh-contoh dengan tingkat kerumitan yang berbeda-beda. Masalahnya adalah mereka biasanya tidak menjelaskan secara rinci bagaimana, apa dan mengapa dilakukan di sana, mengapa ketergantungan ini dan itu ditambahkan, mengapa kelas ini dan itu diperlukan, dll. Dalam kebanyakan kasus, mereka mengambil aplikasi yang sudah selesai, dengan file POM final, dengan versi final kelas, dan hanya menjalankan masing-masing aplikasi, tanpa berfokus pada hal-hal kecil yang mungkin tampak jelas bagi orang yang berpengalaman. Saya telah melihat banyak contoh seperti itu dan biasanya jelas bagaimana semuanya bekerja, namun bagaimana mereka sampai pada hal ini tidak sepenuhnya jelas. Oleh karena itu, saya memutuskan bahwa contoh seperti itu akan berguna, bukan dari sudut pandang pengembang berpengalaman, tetapi dari sudut pandang seorang pemula yang belum pernah berurusan dengan Spring, Hibernate, dan hal lainnya.Membuat Proyek
Jadi, karena saya seorang pemula, kami tidak akan menggunakan arketipe yang tidak jelas. Inisialisasi pegas masih terdengar terlalu menakutkan. Oleh karena itu, kami akan membuat proyek Maven sederhana yang paling biasa. Saya tidak punya nama domain, jadi di groupid saya tulis sajatestgroup
, dan di artifakid saya tulis namanya, misalnya filmography
(ini akan menjadi daftar film). Kami membuat proyek dan memilih Enable auto-import
kapan ide tersebut menyarankannya. Berkat ini, setiap kali kita melakukan perubahan apa pun pada file POM (Project Object Model, file ini menjelaskan keseluruhan struktur proyek Maven), semuanya akan segera diterapkan secara otomatis ke proyek tersebut. Perpustakaan akan diambil dari repositori lokal kita jika kita sudah memilikinya, atau jika kita menggunakan beberapa dependensi baru yang belum pernah kita tangani sebelumnya, Maven hanya akan mendownloadnya melalui Internet dari repositori pusat. Maven juga memiliki fungsi untuk mengunduh sumber dan dokumentasi (Download Sources and/or Documentation). Ini juga sangat nyaman, jika ada sesuatu yang tidak jelas dengan beberapa kelas atau metode, Anda dapat membuka kode sumber dan melihat cara kerjanya di dalamnya. Mari tambahkan beberapa detail. Ini akan menjadi aplikasi web dan kami akan menggunakan Tomcat . Untuk menyebarkan aplikasi ke Tomcat, Anda perlu mentransfernya ke sana dalam bentuk arsip perang (Sumber Daya Aplikasi Web, format khusus untuk aplikasi web). Untuk melakukannya, tambahkan baris berikut ke file POM sehingga aplikasi dikompilasi menjadi arsip perang:
<packaging>war</packaging>
Nah, Anda juga memerlukan direktori khusus untuk sumber web, dalam kasus kami akan ada halaman jsp dan beberapa sumber web. Mari buat main
direktori webapp
. Ini harus disebut persis seperti itu dan ditempatkan dengan main
cara yang persis sama seperti java
, resources
karena ini adalah struktur direktori standar Maven. Setelah kami menginstal paket war
dan menentukan bahwa ini adalah proyek web, direktori webapp
akan secara otomatis ditandai sebagai sumber aplikasi Web (akan ada titik biru di atasnya) dan segala sesuatu yang berhubungan dengan web akan dicari di folder ini. Dan suatu saat. Secara default, Maven menggunakan bahasa versi 1.5, tetapi saya ingin menggunakan, misalnya, versi 1.8 - Java 8 (Bisa ambil 10, atau 11, tapi masih belum ada rencana untuk menggunakan fitur apa pun dari sana, jadi biarlah 8 ). Ini dapat diselesaikan dengan sangat sederhana, kita menulis sesuatu seperti "Maven java 8" di Google dan melihat apa yang perlu ditambahkan ke file POM agar Maven mengkompilasi kelas kita untuk versi yang diperlukan. Hasilnya, kami mendapatkan yang berikut:
Koneksi pegas MVC
Anda harus memulai dari suatu tempat. Menurut rencana, kami akan menghubungkan database dan menggunakan Hibernate, tapi ini semua terdengar terlalu menakutkan untuk saat ini. Kita perlu melakukan sesuatu yang lebih sederhana terlebih dahulu. Spring MVC, ini sudah lebih baik, kita sudah familiar dengan pola MVC sejak lama, ini digunakan di setengah dari tugas besar kursus. Dari sini kita akan mulai menari. Untuk membuat aplikasi web dengan Spring MVC, kita juga memerlukan Servlet-API, yaitu. hal yang dengannya interaksi permintaan-respons akan terjadi. Mari kita coba menghubungkan ini. Kami pergi ke Google, mencari dependensi yang diperlukan di repositori Maven dan menambahkannya ke filepom.xml
. Di bagian Perpustakaan Eksternal Anda dapat melihat bahwa tidak hanya spring-webmvc yang dimuat , tetapi juga banyak hal lainnya. Itu. kita tidak perlu menyertakan dependensi tambahan untuk spring core , context , beans , dll. yang kami perlukan, semua yang kami butuhkan telah ditarik bersama spring-webmvc .
Kita perlu membuat penafian kecil. Biasanya disarankan untuk tetap menambahkan ketergantungan secara terpisah untuk setiap perpustakaan yang digunakan, meskipun sudah dibundel dengan yang sudah ditambahkan, karena ini dapat membantu menghindari beberapa masalah dan gangguan. Sebuah contoh sederhana. Katakanlah kita menambahkan ketergantungan yang menggunakan beberapa API, dan pada saat yang sama akan menarik beberapa jenis implementasi untuk API ini. Lalu kami menambahkan ketergantungan lain yang menggunakan API yang sama dan juga melakukan beberapa implementasinya untuk ini, namun kali ini berbeda. Jadi, kita akan memiliki 2 implementasi berbeda dari API yang sama. Dan jika kita sendiri ingin menggunakan beberapa metode API ini di suatu tempat, maka akan timbul masalah, karena sistem tidak mengetahui implementasi mana yang akan digunakan, sistem akan memilih secara acak, mungkin bukan yang kita harapkan. Dan jika Anda secara eksplisit menentukan ketergantungan untuk salah satu implementasi, maka prioritas akan diberikan padanya. Namun, ini bukan rekomendasi yang ketat; ini terutama berlaku untuk proyek besar yang menggunakan banyak perpustakaan berbeda dari perusahaan berbeda. Kami tidak akan melakukan itu di sini, agar tidak memuat file POM terlalu banyak; diperkirakan tidak ada masalah. Namun demikian, hal ini tetap perlu diingat. |
provided
Tergantung maksudnya apa javax.servlet-api
? Scope adalah cakupan dependensi, provided
artinya dependensi akan tersedia pada tahap kompilasi dan pengujian aplikasi, namun tidak akan diarsipkan. Faktanya adalah untuk menyebarkan aplikasi kita akan menggunakan wadah servlet, Tomcat, dan sudah memiliki perpustakaan seperti itu di dalamnya, jadi tidak perlu mentransfernya ke sana dan membebani arsip dengan beban yang tidak perlu. Ke depan, untuk alasan yang sama kita akan melakukannya tanpa metode biasa main
, karena sudah ada di dalam Tomcat.
Membuat Halaman dan Pengontrol
Mari kita coba memasak sesuatu yang sederhana sekarang. Pertama, mari kita buatwebapp
direktori tambahan, misalnya pages
, di mana pandangan kita akan disimpan, mis. jsp halaman, dan buat beberapa halaman. Kita memerlukan halaman yang nantinya akan ditampilkan daftar film, misalnya films.jsp
, dan mungkin kita bisa membuat halaman terpisah untuk diedit, biarlah editPage.jsp
. Kami tidak akan mengisinya dengan sesuatu yang serius untuk saat ini; hanya untuk pengujian, kami akan membuat link dari satu halaman ke halaman lainnya. Sekarang kita membutuhkan kelas yang akan memproses permintaan, mis. pengontrol. Mari tambahkan paket baru controller
dan buat kelas di dalamnya FilmController
(secara umum, tidak perlu mengemas semuanya dalam paket yang berbeda, aplikasi ini akan sangat kecil dan sederhana, tetapi dalam proyek normal bisa ada banyak pengontrol, kelas konfigurasi, model , dll, jadi walaupun memulai proyek kecil, lebih baik segera biasakan melakukan segala sesuatunya dengan tertib dan terstruktur agar tidak berantakan). Di kelas ini kita akan membuat metode yang akan mengembalikan pandangan kita sebagai respons terhadap permintaan.
package testgroup.filmography.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class FilmController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView allFilms() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("films");
return modelAndView;
}
@RequestMapping(value = "/edit", method = RequestMethod.GET)
public ModelAndView editPage() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("editPage");
return modelAndView;
}
}
Apa gunanya? Spring MVC memiliki sesuatu yang disebut DispatcherServlet
. Ini seperti pengontrol utama, semua permintaan masuk melewatinya dan kemudian meneruskannya ke pengontrol tertentu. Anotasi @Controller
hanya memberi tahu Spring MVC bahwa kelas ini adalah pengontrol (secara umum logis), operator akan memeriksa anotasi @RequestMapping
untuk memanggil metode yang sesuai. Anotasi @RequestMapping
memungkinkan Anda menyetel alamat untuk metode pengontrol yang akan tersedia di klien (browser). Ini juga dapat diterapkan pada kelas pengontrol untuk mengatur, bisa dikatakan, alamat root untuk semua metode. allFilms()
Parameter untuk metode ini value
diatur ke " /
", sehingga akan langsung dipanggil ketika kombinasi http://host:port/ dimasukkan di browser (yaitu, secara default adalah http://localhost:8080/ atau http ://127.0 .0.1:8080/ ). Parameter method
menentukan jenis permintaan yang didukung (GET, POST, PUT, dll.). Karena di sini kami hanya menerima data, maka GET digunakan. Nanti ketika muncul metode untuk menambah dan mengedit, sudah ada permintaan POST. (Omong-omong, alih-alih anotasi @RequestMapping
yang menunjukkan suatu metode, Anda dapat menggunakan anotasi @GetMapping
, @PostMapping
dll. @GetMapping
secara setara @RequestMapping(method = RequestMethod.GET
)). Dalam metode kami, kami membuat objek ModelAndView
dan menetapkan nama tampilan yang perlu dikembalikan.
Konfigurasi
Mari beralih ke pengaturan konfigurasi.config
Mari kita buat kelas di dalam paket WebConfig
. Ini hanya akan memiliki satu metode yang mengembalikan objek bertipe ViewResolver
, ini adalah antarmuka yang diperlukan untuk menemukan representasi berdasarkan nama.
package testgroup.filmography.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "testgroup.filmography")
public class WebConfig {
@Bean
ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/pages/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
@Configuration
memberitahu Spring bahwa kelas ini adalah kelas konfigurasi dan berisi definisi dan dependensi bean
komponen. Kacang adalah objek yang dikelola oleh Spring. Anotasi digunakan untuk mendefinisikan kacang @Bean
. @EnableWebMvc
memungkinkan Anda mengimpor konfigurasi Spring MVC dari file WebMvcConfigurationSupport
. Anda juga dapat mengimplementasikan, misalnya, antarmuka WebMvcConfigurer
yang memiliki banyak metode, dan menyesuaikan semuanya sesuai keinginan Anda, namun kita tidak perlu membahasnya dulu, pengaturan standar saja sudah cukup. @ComponentScan
memberi tahu Spring di mana mencari komponen yang harus dikelola, mis. kelas yang ditandai dengan anotasi @Component
atau turunannya seperti @Controller
, @Repository
, @Service
. Anotasi ini secara otomatis mendefinisikan kacang kelas. Dalam metode ini, viewResolver()
kami membuat implementasinya dan menentukan di mana tepatnya mencari representasi di webapp
. Oleh karena itu, ketika dalam metode pengontrol kita menetapkan nama " films
", tampilan akan ditemukan sebagai " /pages/films.jsp
" Jadi, kita memiliki kelas konfigurasi, tetapi untuk saat ini hanya semacam kelas terpisah, itu tidak mempengaruhi aplikasi kita dengan cara apa pun . Kita perlu mendaftarkan konfigurasi ini dalam konteks Spring. Untuk ini, Anda memerlukan kelas AbstractAnnotationConfigDispatcherServletInitializer
. Di dalam paket, config
kami membuat penerusnya, misalnya AppInitializer , dan mengimplementasikan metodenya.
package testgroup.filmography.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
Metode terakhir mendaftarkan alamat dan ada 2 metode lagi untuk mendaftarkan kelas konfigurasi. Konfigurasi web, di mana ViewResolver
's dan sejenisnya didefinisikan, ditempatkan di getServletConfigClasses()
. Lebih baik membaca tentang semua ini di dokumentasi dan berbagai panduan, tetapi dalam kasus kami belum perlu mendalami hal ini, WebConfig
pada prinsipnya, kami dapat RootClasses
mendefinisikan keduanya, Anda bahkan dapat mendefinisikan keduanya sekaligus, itu akan tetap berfungsi . Satu hal lagi. Mungkin ada masalah dengan pengkodean ketika, saat mengirim nilai dengan karakter Rusia dari formulir, hasilnya adalah coretan. Untuk mengatasi masalah ini, kami akan menambahkan filter yang akan memproses permintaan terlebih dahulu. Kami pergi ke kelas AppInitializer dan mengganti metode getServletFilters
di mana kami menunjukkan pengkodean yang diinginkan, tentu saja, itu harus sama seperti di tempat lain, seperti pada halaman dan di database:
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return new Filter[] {characterEncodingFilter};
}
Tampaknya semuanya sudah diatur, Anda dapat mencoba menjalankannya dan melihat apa yang terjadi. Jalankan -> Jalankan -> Edit Konfigurasi -> Tambahkan Konfigurasi Baru -> Server Tomcat -> Lokal Selanjutnya, Anda perlu memilih artefak yang akan digunakan. Idenya sendiri akan memberikan petunjuk. Peringatan: Tidak ada artefak yang ditandai untuk ditempatkan . Klik tombol perbaikan dan pilih ...: perang meledak . Atau Anda bisa pergi ke Deployment -> add -> Artifact -> ...: war meledak . Dan Anda juga perlu pergi ke Deployment dan mengatur bidang konteks Applecation (ini akan menjadi bagian dari alamat url tempat aplikasi akan tersedia di browser) ke " /
". Kemudian aplikasi kita akan segera tersedia di http://localhost:8080/ (tetapi Anda juga dapat menentukan sesuatu di sana, misalnya " /filmography
", dan kemudian Anda hanya perlu menambahkan ini ke semua alamat, misalnya tidak akan ada " http://localhost:8080/edit" , tetapi akan menjadi "http://localhost:8080/filmography/edit" ). Klik Jalankan dan tunggu sampai dimulai. Inilah yang saya dapatkan: Segalanya tampak baik-baik saja, tetapi ada satu peringatan. Faktanya adalah halaman kita sekarang dapat diakses publik dan dapat diakses langsung dengan menulis jalurnya di bilah alamat. Kami masuk ke http://localhost:8080/pages/films.jsp dan sekarang kami telah menerima halaman kami tanpa sepengetahuan pengontrol. Entah kenapa ini kurang tepat, jadi kita akan membuat webapp
direktori khusus WEB-INF
. Apa yang ada di dalamnya akan disembunyikan dari publik dan hanya dapat diakses melalui pengontrol. Kami menempatkan direktori dengan pandangan kami ( pages
) di WEB-INF
, dan ViewResolver
karenanya menambahkannya ke awalan:
viewResolver.setPrefix("/WEB-INF/pages/");
Sekarang kita mendapatkan halaman kita di http://localhost:8080 , tetapi jika kita mencoba langsung ke http://localhost:8080/WEB-INF/pages/films.jsp kita mendapatkan kesalahan 404. Bagus sekali, kita punya aplikasi web paling sederhana, Hello World seperti yang mereka katakan. Struktur proyek saat ini terlihat seperti ini:
Model
Kita sudah mempunyai view dan controller, tapi di MVC juga ada huruf ke-3, jadi untuk melengkapi gambarnya kita juga akan menambahkan model. Di dalam paket,model
mari kita buat kelas Film
, misalnya, dengan bidang berikut:, int id
( String title
judul), int year
(tahun rilis), String genre
(genre) dan boolean watched
(yaitu apakah Anda sudah menonton film ini atau belum).
package testgroup.filmography.model;
public class Film {
private int id;
private String title;
private int year;
private String genre;
private boolean watched;
// + Getters and setters
}
Tidak ada yang istimewa, hanya kelas biasa, private field, getter dan setter. Objek dari kelas seperti itu juga disebut POJO
(Objek Java Lama Biasa), yaitu. "objek java sederhana". Sekarang mari kita coba membuat objek seperti itu dan menampilkannya di halaman. Untuk saat ini, kami tidak akan terlalu khawatir tentang cara membuat dan menginisialisasinya. Untuk mencobanya, kita langsung saja membuatnya langsung di controller, misalnya seperti ini:
public class FilmController {
private static Film film;
static {
film = new Film();
film.setTitle("Inception");
film.setYear(2010);
film.setGenre("sci-fi");
film.setWatched(true);
}
Dan tambahkan objek ini ke objek kita ModelAndView
menggunakan metode addObject
:
@RequestMapping(method = RequestMethod.GET)
public ModelAndView allFilms() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("films");
modelAndView.addObject("film", film);
return modelAndView;
}
Sekarang kita dapat menampilkan objek ini di halaman kita. Sebagai films.jsp
pengganti Hello World kita akan menulis ${film}
dan objek yang sesuai dengan nama atribut " film
" akan diganti di sini. Mari kita coba menjalankannya dan melihat apa yang terjadi (untuk keluaran objek yang jelas, kelasnya Film
telah didefinisikan ulang toString()
):
Pengontrol Tampilan Model
Pada tahap ini, sepertinya kami sudah memiliki aplikasi Spring MVC yang lengkap. Sebelum melanjutkan, ada baiknya untuk melihat semuanya lagi dan mencari tahu cara kerjanya. Di Internet Anda dapat menemukan banyak gambar dan diagram tentang ini, saya suka yang ini:Dispatcher Servlet
, lalu ia menemukan pengontrol yang cocok untuk memproses permintaan ini menggunakan HandlerMapping
(ini adalah antarmuka untuk memilih pengontrol, memeriksa pengontrol mana yang tersedia yang memiliki metode yang menerima alamat tersebut) , memanggil metode yang sesuai dan Controller
mengembalikan informasi tentang tampilan, kemudian petugas operator menemukan tampilan yang diinginkan berdasarkan nama menggunakan ViewResolver
'a, setelah itu data model ditransfer ke tampilan ini dan kami mendapatkan halaman kami sebagai output. Sesuatu seperti ini. Bersambung... Memperkenalkan Maven, Spring, MySQL, Hibernate dan aplikasi CRUD pertama (bagian 1) Memperkenalkan Maven, Spring, MySQL, Hibernate dan aplikasi CRUD pertama (bagian 2) Memperkenalkan Maven, Spring, MySQL, Hibernate dan aplikasi CRUD pertama (part 3) Pengenalan Maven, Spring, MySQL, Hibernate dan aplikasi CRUD pertama (part 4)
GO TO FULL VERSION