Tarkib:
- Kirish
- Loyiha yaratish
- Bahor MVC ulanishi
- Sahifalar va boshqaruvchi yaratish
- Konfiguratsiya
- Model
- Model-View-Controller
Kirish
Men uchun yangi bo'lgan texnologiyalar va ramkalar bilan ular ishlatilgan turli xil misollarni o'rganish orqali tanishishni boshladim, chunki odatda men to'liq huquqli dastur misolidan foydalanib, biror narsani amalda ko'rganimda yaxshi tushunaman. Odatda, bunday misollar CRUD ilovalari ( C reate, Read , U pdate, D elete), Internet turli darajadagi murakkablikdagi bunday misollar bilan to'la. Muammo shundaki, ular odatda u erda qanday, nima va nima uchun qilinganligi, nima uchun falon tobelik qo'shilganligi, falon sinf nima uchun kerakligini va hokazolarni batafsil tushuntirmaydi. Ko'pgina hollarda, ular yakuniy POM fayli, sinflarning yakuniy versiyalari bilan to'liq tugallangan dasturni oladilar va tajribali odamga tushunarli bo'lib tuyuladigan kichik narsalarga e'tibor bermasdan, oddiygina har biridan o'tadilar. Men bunday misollarning ko'pini ko'rib chiqdim va odatda hamma narsa qanday ishlashi aniq, ammo ular qanday qilib bunga erishganlari to'liq aniq emas. Shuning uchun men bunday misolni tajribali ishlab chiquvchining pozitsiyasidan emas, balki bahor, hibernate va boshqa narsalar bilan hech qachon shug'ullanmagan boshlang'ich pozitsiyasidan foydali bo'lishiga qaror qildim.Loyiha yaratish
Shunday qilib, men yangi boshlovchi bo'lganim uchun, biz hech qanday noaniq arxetiplardan foydalanmaymiz. Spring initializr hali ham juda qo'rqinchli eshitiladi. Shuning uchun biz eng oddiy oddiy Maven loyihasini yaratamiz. Mening domen nomim yo'q, shuning uchun groupidda men shunchaki yozamantestgroup
va artefaktda nomni yozaman, masalan, filmography
(bu filmlar ro'yxati bo'ladi). Biz loyiha yaratamiz va Enable auto-import
g'oya qachon taklif qilishini tanlaymiz. Buning yordamida har safar biz POM fayliga biron bir o'zgartirish kiritganimizda (Project Object Model, bu fayl Maven loyihasining butun tuzilishini tavsiflaydi), hamma narsa darhol loyihaga avtomatik ravishda qo'llaniladi. Kutubxonalar bizning mahalliy omborimizdan olinadi, agar ular bizda mavjud bo'lsa yoki biz ilgari ishlamagan yangi bog'liqliklardan foydalansak, Maven ularni Internet orqali markaziy ombordan yuklab oladi. Maven shuningdek, manbalar va hujjatlarni yuklab olish funktsiyasiga ega (yuklab olish manbalari va/yoki hujjatlar). Bundan tashqari, bu juda qulay, agar biron bir sinf yoki usulda biror narsa aniq bo'lmasa, siz manba kodiga o'tishingiz va uning ichida qanday ishlashini ko'rishingiz mumkin. Keling, bir nechta tafsilotlarni qo'shamiz. Bu veb-ilova bo'ladi va biz Tomcat dan foydalanamiz . Tomcat-ga ilovani joylashtirish uchun siz uni urush arxivi ko'rinishida o'tkazishingiz kerak (Veb ilovalar resursi, veb-ilovalar uchun maxsus format). Buning uchun POM fayliga quyidagi qatorni qo'shing, shunda dastur urush arxiviga to'planadi:
<packaging>war</packaging>
Xo'sh, sizga veb-manbalar uchun maxsus katalog ham kerak bo'ladi, bizning holatlarimizda jsp sahifalari va ba'zi veb-resurslar bo'ladi . Keling, main
katalog yarataylik webapp
. Uni aynan shunday deb atash kerak va xuddi main
shu tarzda joylashgan bo'lishi kerak java
, resources
chunki bu standart Maven katalog tuzilishi. Paketni o'rnatganimizdan so'ng war
va bu veb-loyiha ekanligini aniqlaganimizdan so'ng, katalog webapp
avtomatik ravishda veb-ilova manbalari sifatida belgilanadi (uning ustida ko'k nuqta bo'ladi) va veb bilan bog'liq barcha narsalar ushbu papkada qidiriladi. Va bir daqiqa. Odatiy bo'lib, Maven tilning 1.5 versiyasidan foydalanadi, lekin men, masalan, 1.8 - Java 8 versiyasidan foydalanmoqchiman (siz 10 yoki 11 ni olishingiz mumkin, ammo u erdan biron bir xususiyatdan foydalanish rejalari yo'q, shuning uchun u 8 bo'lsin. ). Buni juda oddiy hal qilish mumkin, biz Google-ga "Maven java 8" kabi narsalarni yozamiz va Maven kerakli versiya uchun sinflarimizni kompilyatsiya qilish uchun POM fayliga nima qo'shilishi kerakligini ko'ramiz. Natijada, bizda quyidagilar mavjud:
Bahor MVC ulanishi
Biror joydan boshlash kerak. Rejaga ko'ra, biz ma'lumotlar bazasini ulaymiz va Hibernate-dan foydalanamiz, ammo bularning barchasi hozircha juda qo'rqinchli ko'rinadi. Avval oddiyroq narsani qilishimiz kerak. Bahor MVC, bu allaqachon yaxshiroq, biz MVC namunasi bilan uzoq vaqtdan beri tanishmiz, u kursning katta vazifalarining yarmida ishlatilgan. Bu erdan biz raqsga tushamiz. Spring MVC bilan veb-ilovani yaratish uchun bizga Servlet-API ham kerak, ya'ni. so'rov-javob o'zaro ta'siri amalga oshiriladigan narsa. Keling, buni ulashga harakat qilaylik. Biz Google-ga boramiz, Maven omborida kerakli bog'liqliklarni qidiramiz va ularnipom.xml
. Tashqi kutubxonalar bo'limida siz nafaqat spring-webmvc yuklanganligini , balki boshqa ko'plab narsalarni ham ko'rishingiz mumkin. Bular. bahor yadrosi , kontekst , loviya va boshqalar uchun bog'liqliklarni qo'shimcha kiritishimiz shart emas. bizga kerak bo'lgan hamma narsa spring-webmvc bilan birga tortildi .
Biz kichik rad etishimiz kerak. Odatda, har bir foydalanilgan kutubxona uchun, hatto ular allaqachon qo'shilganlar bilan birga bo'lsa ham, alohida bog'liqlikni qo'shish tavsiya etiladi, chunki bu ba'zi muammolar va nosozliklardan qochishga yordam beradi. Oddiy misol. Aytaylik, biz ba'zi API ishlatadigan qaramlikni qo'shdik va shu bilan birga u ushbu API uchun qandaydir dasturni tortib oladi. Va keyin biz bir xil API-dan foydalanadigan va buning uchun ba'zi bir amalga oshirishni talab qiladigan boshqa qaramlikni qo'shdik, ammo bu safar u boshqacha. Shunday qilib, biz bir xil API ning 2 xil ilovalariga ega bo'lamiz. Va agar biz o'zimiz biron bir joyda ushbu API-ning ba'zi usullaridan foydalanmoqchi bo'lsak, unda muammo paydo bo'ladi, chunki tizim qaysi dasturni ishlatishni bilmaydi, u tasodifiy tanlaydi, ehtimol biz kutganini emas. Va agar siz ilovalardan biriga bog'liqlikni aniq belgilab qo'ysangiz, unga ustuvorlik beriladi. Biroq, bu unchalik qat'iy tavsiya emas, u asosan turli kompaniyalarning turli xil kutubxonalari qo'llaniladigan yirik loyihalarga tegishli. POM faylini juda ko'p yuklamaslik uchun biz buni bu erda qilmaymiz; hech qanday muammo kutilmaydi. Ammo shunga qaramay, buni yodda tutish kerak. |
provided
Bog'lanish nimani anglatadi javax.servlet-api
? Qo'llash doirasi - bu bog'liqlik doirasi, provided
ya'ni bog'liqlik ilovani kompilyatsiya qilish va sinovdan o'tkazish bosqichida mavjud bo'ladi, lekin u arxivlanmaydi. Gap shundaki, dasturni o'rnatish uchun biz Tomcat servlet konteyneridan foydalanamiz va uning ichida allaqachon shunday kutubxonalar mavjud, shuning uchun ularni u erga o'tkazish va arxivni keraksiz yuk bilan yuklashning hojati yo'q. Oldinga qarab, xuddi shu sababga ko'ra biz odatdagi usulsiz qilamiz main
, chunki u Tomcat ichida allaqachon mavjud.
Sahifalar va boshqaruvchi yaratish
Keling, oddiy taom tayyorlashga harakat qilaylik. Birinchidan, qo'shimcha katalog yarataylikwebapp
, masalan pages
, unda bizning ko'rinishlarimiz saqlanadi, ya'ni. jsp sahifalarini yarating va bir nechta sahifa yarating. Bizga kelajakda filmlar ro'yxati ko'rsatiladigan sahifa kerak bo'ladi, masalan films.jsp
, va, ehtimol, biz tahrirlash uchun alohida sahifa qilishimiz mumkin editPage.jsp
. Biz ularni hozircha jiddiy narsa bilan to'ldirmaymiz; faqat sinov uchun biz bir sahifada boshqasiga havola qilamiz. Endi bizga so'rovlarni qayta ishlaydigan sinf kerak, ya'ni. boshqaruvchi. Keling, yangi paket qo'shamiz controller
va unda sinf yaratamiz FilmController
(umuman olganda, hamma narsani turli paketlarga to'plash shart emas, bu dastur juda kichik va oddiy bo'ladi, lekin oddiy loyihada ko'plab kontrollerlar, konfiguratsiya sinflari, modellar bo'lishi mumkin. va hokazo, shuning uchun hatto kichik loyihalardan boshlab, tartibsizliklar bo'lmasligi uchun darhol hamma narsani tartibli va tizimli bajarishga odatlanganingiz ma'qul). Ushbu sinfda biz so'rovlarga javoban fikrlarimizni qaytaradigan usullarni yaratamiz.
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;
}
}
Buning nima keragi bor? Spring MVC deb nomlangan narsa bor DispatcherServlet
. Bu asosiy kontrollerga o'xshaydi, barcha kiruvchi so'rovlar u orqali o'tadi va keyin ularni ma'lum bir kontrollerga uzatadi. Izoh @Controller
shunchaki Spring MVC-ga bu sinf boshqaruvchi (yaxshi, umuman mantiqiy) ekanligini aytadi, dispetcher @RequestMapping
tegishli usulni chaqirish uchun izohlarni tekshiradi. Izoh @RequestMapping
sizga kontroller usullari uchun manzillarni belgilash imkonini beradi, ular yordamida mijoz (brauzer)da mavjud bo'ladi. Bundan tashqari, barcha usullar uchun ildiz manzilini o'rnatish uchun boshqaruvchi sinfiga ham qo'llanilishi mumkin. Usul allFilms()
parametri value
" " ga o'rnatilgan , shuning uchun brauzerga http://host:port//
kombinatsiyasi kiritilganda darhol chaqiriladi (ya'ni, sukut bo'yicha http://localhost:8080/ yoki http) . ://127.0 .0.1:8080/ ). Parametr qaysi turdagi so'rovlar qo'llab-quvvatlanishini belgilaydi (GET, POST, PUT va boshqalar). Bu erda biz faqat ma'lumotlarni olamiz, GET ishlatiladi. Keyinchalik, qo'shish va tahrirlash usullari paydo bo'lganda, POST so'rovlari allaqachon paydo bo'ladi. (Aytgancha, usulni ko'rsatuvchi izoh o'rniga siz annotatsiyalardan foydalanishingiz mumkin va hokazo. ekvivalent )). Bizning usullarimizda biz ob'ekt yaratamiz va qaytarilishi kerak bo'lgan ko'rinish nomini o'rnatamiz. method
@RequestMapping
@GetMapping
@PostMapping
@GetMapping
@RequestMapping(method = RequestMethod.GET
ModelAndView
Konfiguratsiya
Keling, konfiguratsiyani o'rnatishga o'tamiz. Paketdaconfig
sinf yarataylik WebConfig
. U turdagi ob'ektni qaytaradigan faqat bitta usulga ega bo'ladi ViewResolver
, bu nom bo'yicha vakillikni topish uchun zarur bo'lgan interfeysdir.
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
Springga bu sinf konfiguratsiya sinfi ekanligini va bean
komponentlarning ta'riflari va bog'liqliklarini o'z ichiga olganligini aytadi. Fasol bahor tomonidan boshqariladigan ob'ektlardir. Annotatsiya fasolni aniqlash uchun ishlatiladi @Bean
. @EnableWebMvc
dan Spring MVC konfiguratsiyasini import qilish imkonini beradi WebMvcConfigurationSupport
. Shuningdek, siz, masalan, WebMvcConfigurer
ko'plab usullarga ega bo'lgan interfeysni amalga oshirishingiz va hamma narsani o'zingizning xohishingizga ko'ra sozlashingiz mumkin, ammo biz bunga hali kirishimiz shart emas, standart sozlamalar etarli bo'ladi. @ComponentScan
Bahorga u boshqarishi kerak bo'lgan komponentlarni qaerdan izlash kerakligini aytadi, ya'ni. annotatsiya yoki uning hosilalari bilan belgilangan sinflar , , , @Component
kabilar . Ushbu izohlar sinf fasolini avtomatik ravishda belgilaydi. Usulda biz uni amalga oshirishni yaratamiz va tasvirlarni qaerdan qidirish kerakligini aniqlaymiz . Shuning uchun, kontroller usulida biz " " nomini o'rnatganimizda, ko'rinish " " shaklida topiladi. Shunday qilib, bizda konfiguratsiya sinfi mavjud, ammo hozircha bu alohida sinfning qandaydir turi, u bizning ilovamizga hech qanday ta'sir qilmaydi. . Ushbu konfiguratsiyani Spring kontekstida ro'yxatdan o'tkazishimiz kerak. Buning uchun sizga sinf kerak . Paketda biz uning vorisi yaratamiz, aytaylik AppInitializer va uning usullarini amalga oshiramiz. @Controller
@Repository
@Service
viewResolver()
webapp
films
/pages/films.jsp
AbstractAnnotationConfigDispatcherServletInitializer
config
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[]{"/"};
}
}
Oxirgi usul manzillarni qayd qiladi va konfiguratsiya sinflarini ro'yxatdan o'tkazish uchun yana 2 ta usul mavjud. 's va shunga o'xshashlar aniqlangan veb-konfiguratsiyalar ViewResolver
ga joylashtirilgan getServletConfigClasses()
. Bularning barchasini hujjatlarda va turli qo'llanmalarda o'qib chiqish yaxshiroqdir, ammo bizning holatlarimizda bu haqda hali chuqurroq o'rganish shart emas, biznikini, WebConfig
qoida tariqasida, RootClasses
ikkalasida ham aniqlash mumkin, hatto ikkalasini ham birdaniga belgilashingiz mumkin, u hali ham ishlaydi . Yana bir narsa. Shakldan ruscha belgilar bilan qiymatlarni yuborishda, natijada chizmalar paydo bo'lganda, kodlash bilan bog'liq muammolar bo'lishi mumkin. Ushbu muammoni hal qilish uchun biz so'rovlarni oldindan qayta ishlaydigan filtr qo'shamiz. Biz AppInitializer sinfiga o'tamiz va usulni bekor qilamiz getServletFilters
, unda biz kerakli kodlashni ko'rsatamiz, u, albatta, sahifalarda va ma'lumotlar bazasida bo'lgani kabi, hamma joyda bo'lgani kabi bo'lishi kerak:
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return new Filter[] {characterEncodingFilter};
}
Xo'sh, hamma narsa o'rnatilganga o'xshaydi, siz uni ishga tushirishga urinib ko'rishingiz va nima bo'lishini ko'rishingiz mumkin. Run -> Run -> Konfiguratsiyalarni tahrirlash -> Yangi konfiguratsiyani qo'shish -> Tomcat Server -> Local Keyingi, siz o'rnatish uchun artefaktni tanlashingiz kerak. G'oyaning o'zi bir maslahat beradi Ogohlantirish: joylashtirish uchun hech qanday artefakt belgilanmagan . Tuzatish tugmasini bosing va ... ni tanlang: urush portladi . Yoki siz Joylashtirish -> qo'shish -> Artifakt -> ... ga o'tishingiz mumkin : urush portladi . Shuningdek, siz Joylashtirishga o'tishingiz va Applecation kontekst maydonini (bu ilova brauzerda mavjud bo'lgan url manzilining bir qismi bo'ladi) " /
" ga o'rnatishingiz kerak. Keyin bizning ilovamiz darhol http://localhost:8080/ manzilida mavjud bo'ladi (lekin siz u erda biror narsani ham belgilashingiz mumkin, masalan, " " va keyin buni barcha manzillarga qo'shishingiz kerak bo'ladi, ya'ni, masalan, bo'lmaydi. " http://localhost:8080/edit" , lekin u "http://localhost:8080/filmography/edit" bo'ladi ). "Ishga tushirish" tugmasini bosing va u boshlanishini kuting. Mana men tushundim: hamma narsa yaxshi ko'rinadi, lekin bitta ogohlantirish bor. Gap shundaki, bizning sahifalarimiz endi hamma uchun ochiq va manzil satriga yo'lni yozish orqali to'g'ridan-to'g'ri kirish mumkin. Biz http://localhost:8080/pages/films.jsp ga kiramiz va endi biz sahifamizni boshqaruvchining xabarisiz oldik. Qandaydir tarzda bu juda to'g'ri emas, shuning uchun biz maxsus katalog yaratamiz . Ichkaridagi narsalar ommadan yashiriladi va unga faqat kontroller orqali kirish mumkin. Biz ko'rinishlarimiz bilan katalogni ( ) ichiga joylashtiramiz va shunga mos ravishda uni prefiksga qo'shamiz: /filmography
webapp
WEB-INF
pages
WEB-INF
ViewResolver
viewResolver.setPrefix("/WEB-INF/pages/");
Endi biz sahifamizni http://localhost:8080 manzilida olamiz , lekin agar biz to'g'ridan-to'g'ri http://localhost:8080/WEB-INF/pages/films.jsp ga harakat qilsak, 404 xatoga ega bo'lamiz. eng oddiy veb-ilova, ular aytganidek, Salom Dunyo. Hozirgi vaqtda loyiha tuzilishi quyidagicha ko'rinadi:
Model
Bizda allaqachon ko'rinishlar va boshqaruvchi bor, lekin MVC-da 3-harf ham bor, shuning uchun rasmni to'ldirish uchun biz modelni ham qo'shamiz. Paketdamodel
sinf yarataylik Film
, masalan, quyidagi maydonlar bilan: int id
, String title
(nomi), int year
(chiqarilgan yili), String genre
(janr) va boolean watched
(ya'ni, siz ushbu filmni allaqachon ko'rganmisiz yoki yo'q).
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
}
Hech qanday maxsus narsa yo'q, oddiy sinf, shaxsiy maydonlar, oluvchilar va setterlar. Bunday sinflarning ob'ektlari ham deyiladi POJO
(Plain Old Java Object), yaxshi, ya'ni. "oddiy java ob'ekti". Keling, bunday ob'ektni yaratishga va uni sahifada ko'rsatishga harakat qilaylik. Hozircha uni qanday yaratish va ishga tushirish haqida ko'p tashvishlanmaymiz. Buni sinab ko'rish uchun, keling, ahmoqona uni to'g'ridan-to'g'ri kontrollerda yarataylik, masalan:
public class FilmController {
private static Film film;
static {
film = new Film();
film.setTitle("Inception");
film.setYear(2010);
film.setGenre("sci-fi");
film.setWatched(true);
}
ModelAndView
Va usul yordamida ushbu ob'ektni bizning ob'ektimizga qo'shing addObject
:
@RequestMapping(method = RequestMethod.GET)
public ModelAndView allFilms() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("films");
modelAndView.addObject("film", film);
return modelAndView;
}
Endi biz ushbu ob'ektni sahifamizda ko'rsatishimiz mumkin. Hello World o'rniga films.jsp
biz yozamiz ${film}
va bu erda atribut nomiga mos keladigan ob'ekt " film
" almashtiriladi. Keling, uni ishga tushirishga harakat qilaylik va nima sodir bo'lganini ko'rib chiqaylik (ob'ektning aniq chiqishi uchun sinf Film
qayta aniqlangan toString()
):
Model-View-Controller
Ushbu bosqichda bizda allaqachon to'liq Spring MVC ilovasi mavjud. Davom etishdan oldin, hamma narsani qayta ko'rib chiqish va barchasi qanday ishlashini aniqlash yaxshi bo'lardi. Internetda siz bu haqda ko'plab rasmlar va diagrammalarni topishingiz mumkin, men buni yoqtiraman:Dispatcher Servlet
, keyin u ushbu so'rovni qayta ishlash uchun mos boshqaruvchini topadi HandlerMapping
(bu kontrollerni tanlash interfeysi, mavjud kontrollerlardan qaysi biri bunday manzilni qabul qiladigan usulga ega ekanligini tekshiradi) , mos usulni chaqiradi va Controller
ko'rinish haqidagi ma'lumotni qaytaradi, keyin dispetcher ViewResolver
"a" dan foydalanib kerakli ko'rinishni topadi, shundan so'ng model ma'lumotlari ushbu ko'rinishga o'tkaziladi va biz sahifamizni chiqish sifatida olamiz. Shunga o'xshash narsa. Davomi... Maven, Spring, MySQL, Hibernate va birinchi CRUD ilovasi bilan tanishtirish (1-qism) Maven, Spring, MySQL, Hibernate va birinchi CRUD ilovasi bilan tanishtirish (2-qism) Maven, Spring, MySQL, Hibernate va birinchi CRUD ilovasi (3-qism) Maven, Spring, MySQL, Hibernate va birinchi CRUD ilovasiga kirish (4-qism)
GO TO FULL VERSION