Мазмуну:
- Киришүү
- Долбоорду түзүү
- Жазгы MVC байланышы
- Барактарды жана контроллерди түзүү
- Конфигурация
- Модел
- Model-View-Controller
Киришүү
Мен үчүн жаңы болгон технологиялар жана фреймворктар менен тааныша баштадым, алар колдонулган ар кандай мисалдарды изилдөө менен, анткени мен, адатта, толук кандуу тиркеменин мисалын колдонуп, аны иш жүзүндө көргөндө жакшыраак түшүнөм. Адатта, мындай мисалдар CRUD тиркемелери ( C reate, Read , U pdate, D elete ), Интернет ар кандай татаалдыктагы мисалдарга толгон. Маселе, алар, адатта, кантип, эмне жана эмне үчүн ал жерде жасалган, эмне үчүн тигил же бул көз карандылык кошулган, эмне үчүн тигил же бул класс керек ж.б.у.с. майда-чүйдөсүнө чейин түшүндүрбөйт. Көпчүлүк учурларда, алар толугу менен даяр тиркемени, акыркы POM файлы менен, класстардын акыркы versionларын алып, тажрыйбалуу адамга айкын көрүнгөн майда нерселерге көңүл бурбастан, жөн гана ар бири аркылуу өтүшөт. Мен мындай мисалдардын көбүн карап чыктым, адатта, баары кандай иштээри түшүнүктүү, бирок алар буга кантип жеткени так эмес. Ошондуктан, мен мындай мисал тажрыйбалуу иштеп чыгуучунун позициясынан эмес, Жаз, Күтүү жана башка нерселер менен эч качан алектенбеген башталгычтын позициясынан пайдалуу болот деп чечтим.Долбоорду түзүү
Ошентип, мен жаңы болгондуктан, биз эч кандай түшүнүксүз архетиптерди колдонбойбуз. Жазгы инициализатор дагы деле коркунучтуу угулат. Ошондуктан, биз эң жөнөкөй Maven долбоорун түзөбүз. Менде домен атым жок, андыктан groupidде мен жөн гана жазамtestgroup
, ал эми артефактиде мен атын жазам, мисалы, filmography
(бул тасмалардын тизмеси болот). Долбоорду түзүп, Enable auto-import
качан идея сунуш кылганда тандайбыз. Ушунун аркасында, биз POM файлына кандайдыр бир өзгөртүүлөрдү киргизген сайын (Project Object Model, бул файл Maven долбоорунун бүт структурасын сүрөттөйт), бардыгы дароо долбоорго автоматтык түрдө колдонулат. Китепканалар биздин жергorктүү репозиторийден алынат, эгерде бизде алар мурунтан эле бар болсо же биз буга чейин карабаган жаңы көз карандылыктарды колдонсок, Maven аларды жөн гана борбордук репозиторийден Интернет аркылуу жүктөп алат. Maven ошондой эле булактарды жана documentтерди жүктөө функциясына ээ (Булактарды жана/же Документацияны жүктөө). Бул дагы абдан ыңгайлуу, эгер кандайдыр бир класс же ыкма менен бир нерсе түшүнүксүз болсо, сиз баштапкы codeго кирип, анын бардыгынын ичинде кантип иштээрин көрө аласыз. Келгиле, бир-эки деталдарды кошолу. Бул веб-тиркеме болот жана биз Tomcat колдонобуз . Тиркемени Tomcat'ке жайгаштыруу үчүн, сиз аны согуш архиви түрүндө өткөрүп беришиңиз керек (Web Application Resource, веб тиркемелер үчүн атайын формат). Бул үчүн, POM файлына төмөнкү сапты кошуп, тиркеме согуш архивине түзүлөт:
<packaging>war</packaging>
Ошондой эле, сизге веб булактары үчүн атайын каталог керек болот, биздин учурда jsp баракчалары жана кээ бир веб-ресурстар болот . main
Каталог түзөлү webapp
. Аны дал ушундай деп аташ керек жана дал main
ошол эле жол менен жайгаштырылышы керек java
, resources
анткени бул стандарттуу Maven каталог түзүмү. Пакетти орнотуп war
, ошону менен бул веб-долбоор экенин аныктагандан кийин, каталог webapp
автоматтык түрдө Веб тиркеме булактары катары белгиленет (анын үстүндө көк чекит болот) жана бул папкадан желеге тиешелүү бардык нерселер изделет. Жана бир көз ирмем. Демейки боюнча, Maven 1.5 тил versionсын колдонот, бирок мен, мисалы, 1.8 - Java 8 versionсын колдонгум келет (Сиз 10 же 11ди ала аласыз, бирок дагы эле ал жерден кандайдыр бир функцияларды колдонуу пландары жок, ошондуктан 8 болсун. ). Муну жөнөкөй эле чечсе болот, биз Google'га "Maven java 8" сыяктуу нерсени жазабыз жана Maven биздин класстарды керектүү versionга компиляциялоо үчүн POM файлына эмнелерди кошуу керек экенин көрөбүз. Натыйжада, биз төмөнкүлөргө ээ:
Жазгы MVC байланышы
Сиз бир жерден баштоо керек. Планга ылайык, биз маалымат базасын туташтырабыз жана Hibernate режимин колдонобуз, бирок мунун баары азыр бир аз коркунучтуу угулат. Биз биринчи жөнөкөй нерсе кылышыбыз керек. Жазгы MVC, бул жакшыраак, биз MVC үлгүсү менен көптөн бери таанышпыз, ал курстун чоң тапшырмаларынын жарымында колдонулган. Ушул жерден бийлей баштайбыз. Spring MVC менен веб тиркемесин түзүү үчүн бизге Servlet-API керек, б.а. ошол нерсе, анын жардамы менен суроо-жооп өз ара аракеттенүүсү ишке ашат. Келгиле, муну байланыштырганга аракет кылалы. Биз Google'га барып, Maven репозиторийинен керектүү көз карандылыктарды издеп , алардыpom.xml
. Тышкы китепканалар бөлүмүндө жаз-webmvc гана эмес , башка көптөгөн нерселер жүктөлгөнүн көрө аласыз . Ошол. жазгы өзөк , контекст , буурчак ж.б. үчүн кошумча көз карандылыкты кошуунун кереги жок. бизге керек болгон нерселердин бардыгы жаз-webmvc менен бирге тартылды .
Биз кичинекей баш тартуу керек. Адатта, колдонулган ар бир китепкана үчүн көз карандылыкты өзүнчө кошуу сунушталат, ал тургай, алар мурунтан эле кошулган китепканалар менен бириктирилген болсо да, анткени бул кээ бир көйгөйлөрдү жана каталарды алдын алууга жардам берет. Жөнөкөй мисал. Биз кээ бир API колдонгон көз карандылыкты коштук дейли, ошол эле учурда ал бул API үчүн кандайдыр бир ишке ашырууну тартат. Анан биз ошол эле APIди колдонгон дагы бир көз карандылыкты коштук, ошондой эле бул үчүн анын айрым ишке ашырылышын тартат, бирок бул жолу башкача. Ошентип, биз бир эле API 2 башка ишке ашырууга ээ болот. Жана эгер биз өзүбүз бул API'нин кээ бир ыкмаларын бир жерде колдонгубуз келсе, анда көйгөй пайда болот, анткени система кайсы ишке ашырууну колдонууну билбей калат, ал кокусунан тандап алат, балким биз күткөн эмес. Эгер сиз ишке ашыруулардын бирине көз карандылыкты ачык көрсөтсөңүз, анда ага артыкчылык берилет. Бирок, бул анчалык катуу сунуш эмес, ал негизинен ар кандай компаниялардын ар кандай китепканалары колдонулган ири долбоорлорго тиешелүү. POM файлын өтө көп жүктөбөш үчүн, биз муну бул жерде кылбайбыз; эч кандай көйгөйлөр күтүлбөйт. Бирок, ошентсе да, муну эстен чыгарбоо керек. |
provided
көз каранды деген эмнени билдирет javax.servlet-api
? Колдонуу - бул көз карандылыктын чөйрөсү, provided
бул көз карандылык тиркемени түзүү жана сынап көрүү стадиясында жеткorктүү болот, бирок ал архивделбейт. Чындыгында, тиркемени жайылтуу үчүн биз Tomcat сервлет контейнерин колдонобуз жана анын ичинде мындай китепканалар бар, ошондуктан аларды ал жакка өткөрүп берүүнүн жана архивди ашыкча жүктөөнүн кереги жок. Алдыга карап, ошол эле себептен биз кадимки ыкмасыз жасайбыз main
, анткени ал Tomcat ичинде мурунтан эле бар.
Барактарды жана контроллерди түзүү
Келгиле, азыр жөнөкөй бир нерсе жасаганга аракет кылалы. Биринчиден, кошумча каталог түзөлүwebapp
, мисалы pages
, анда биздин көз караштар сакталат, б.а. jsp барактарын түзүп, бир нече барактарды түзүңүз. Бизге келечекте тасмалардын тизмеси көрсөтүлө турган барак керек болот, мисалы films.jsp
, жана балким, биз монтаждоо үчүн өзүнчө барак жасай алабыз editPage.jsp
. Биз аларды азырынча олуттуу эч нерсе менен толтурбайбыз; жөн гана тестирлөө үчүн, биз бир баракта башкасына шилтеме жасайбыз. Эми бизге суроо-талаптарды иштете турган класс керек, б.а. контролер. Келгиле, жаңы пакетти кошуп controller
, ага класс түзөлү FilmController
(жалпысынан, бардыгын ар кандай пакеттерге пакеттөө зарыл эмес, бул тиркеме өтө кичинекей жана жөнөкөй болот, бирок кадимки долбоордо көптөгөн контроллерлор, конфигурация класстары, моделдер болушу мүмкүн. ж.б.у.с., андыктан кичинекей долбоорлордон баштап, эч кандай баш аламандык болбошу үчүн дароо бардык нерсени иреттүү жана структуралык кылууга көнүп алганыңыз жакшы). Бул класста биз суроо-талаптарга жооп катары көз карашыбызды кайтара турган ыкмаларды түзөбүз.
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;
}
}
Мунун эмне кереги бар? Spring MVC деген нерсе бар DispatcherServlet
. Бул негизги контроллер сыяктуу, бардык кирүүчү суроо-талаптар ал аркылуу өтүп, андан кийин аларды белгилүү бир контроллерге өткөрүп берет. Аннотация Spring MVCге бул класс контроллер (жакшы, жалпысынан логикалык) экенин айтат, диспетчер тиешелүү ыкманы чакыруу үчүн @Controller
annotationларды текшерет . @RequestMapping
Аннотация @RequestMapping
контроллердин ыкмалары үчүн даректерди көрсөтүүгө мүмкүндүк берет, алар кардарда (браузерде) жеткorктүү болот. Ал ошондой эле бардык ыкмалар үчүн, мындайча айтканда, тамыр дарегин коюу үчүн контроллер классына колдонулушу мүмкүн. Метод үчүн allFilms()
параметр value
" " деп коюлган , ошондуктан ал http://host:port//
айкалышы браузерге киргизилгенде дароо чакырылат (б.а., демейки боюнча бул http://localhost:8080/ же http ://127.0 .0.1:8080/ ). Параметр суроо-талаптын кайсы түрү колдоого алынарын аныктайт (GET, POST, PUT ж.б.). Бул жерде биз маалыматтарды гана алгандыктан, GET колдонулат. Кийинчерээк, кошуу жана түзөтүү ыкмалары пайда болгондо, POST сурамдары мурунтан эле пайда болот. (Баса, ыкманы көрсөткөн annotationнын ордуна annotationларды ж.б. эквиваленттүү түрдө колдонсоңуз болот )). Биздин методдордо биз an object түзүп , кайтарылышы керек болгон көрүнүштүн атын коёбуз. method
@RequestMapping
@GetMapping
@PostMapping
@GetMapping
@RequestMapping(method = RequestMethod.GET
ModelAndView
Конфигурация
Конфигурацияны орнотууга өтөлү. Пакеттеconfig
класс түзөлү WebConfig
. Ал түрдөгү an objectти кайтаруучу бир гана ыкмага ээ болот ViewResolver
, бул аталышы боюнча өкүлчүлүктү табуу үчүн зарыл болгон интерфейс.
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
Spring бул класстын конфигурация классы экенин жана bean
компоненттердин аныктамаларын жана көз карандылыктарын камтыйт. Фасоль - бул Жаз тарабынан башкарылуучу an objectтер. Аннотация буурчакты аныктоо үчүн колдонулат @Bean
. @EnableWebMvc
Spring MVC конфигурациясын WebMvcConfigurationSupport
. Ошондой эле, мисалы, WebMvcConfigurer
бир топ ыкмаларды камтыган интерфейсти ишке ашырып, бардыгын өзүңүз каалагандай ыңгайлаштыра аласыз, бирок буга азырынча киришүүнүн кереги жок, стандарттык орнотуулар жетиштүү болот. @ComponentScan
Жазга башкара турган компоненттерди кайдан издөө керектигин айтат, б.а. annotation менен белгиленген класстар @Component
же анын туундулары, мисалы @Controller
, @Repository
, , @Service
. Бул annotationлар класстын буурчакты автоматтык түрдө аныктайт. Методдо viewResolver()
биз аны ишке ашырууну түзөбүз жана webapp
. Ошондуктан, контроллер ыкмасына " " атын койгондо, films
көрүнүш " " катары табылат. /pages/films.jsp
Демек, бизде конфигурация классы бар, бирок азыр ал өзүнчө класстын кандайдыр бир түрү, ал биздин колдонмобузга эч кандай таасир этпейт. . Бул конфигурацияны Жаз контекстинде катташыбыз керек. Бул үчүн сизге класс керек AbstractAnnotationConfigDispatcherServletInitializer
. Пакетте config
биз анын мураскерин түзөбүз, айталы , AppInitializer жана анын ыкмаларын ишке ашырабыз.
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[]{"/"};
}
}
Акыркы ыкма даректерди каттайт жана конфигурация класстарын каттоонун дагы 2 ыкмасы бар. Веб конфигурациялары, ViewResolver
's жана ушу сыяктуулар аныкталган жерде, жайгаштырылган getServletConfigClasses()
. Мунун бардыгын documentациядан жана ар кандай колдонмолордон окуганыңыз жакшы, бирок биздин учурда буга чейин тереңдеп кирүүнүн кереги жок, биздики, WebConfig
негизинен, RootClasses
экөөнү тең аныктаса болот, экөөнү тең бир убакта аныктай аласыз, ал дагы деле иштейт . Дагы бир нерсе. Формадан орус тамгалары менен баалуулуктарды жөнөткөндө, натыйжада скрипкалар пайда болгондо codeдоодо көйгөйлөр болушу мүмкүн. Бул көйгөйдү чечүү үчүн биз сурамдарды алдын ала иштете турган чыпка кошобуз. Биз AppInitializer классына барабыз жана методду жокко чыгарабыз getServletFilters
, анда биз каалаган codeдоону көрсөтөбүз, ал, албетте, бардык жердегидей, беттердеги жана маалымат базасындагыдай болушу керек:
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return new Filter[] {characterEncodingFilter};
}
Ооба, баары орнотулган окшойт, сиз аны иштетип, эмне болорун көрүүгө аракет кылсаңыз болот. Run -> Run -> Конфигурацияларды түзөтүү -> Жаңы конфигурация кошуу -> Tomcat Server -> Local Кийинки, жайылтуу үчүн артефактты тандоо керек. Идеянын өзү ишарат берет Эскертүү : Жайгаштыруу үчүн эч кандай артефакт жок . Оңдоо баскычын чыкылдатып , ... тандаңыз : согуш жарылды . Же Deployment -> add -> Artifact -> ... дегенге өтсөңүз болот : war exploded . Жана ошондой эле Жайгаштыруу бөлүмүнө өтүп, Applecation контекст талаасын (бул колдонмо браузерде жеткorктүү боло турган url дарегинин бир бөлүгү болот) " " кылып коюшуңуз керек . Андан кийин биздин тиркеме дароо эле жеткorктүү болот http://localhost:8080/ (бирок сиз ошол жерден бир нерсени көрсөтсөңүз болот, мисалы " ", андан кийин сиз жөн гана муну бардык даректерге кошушуңуз керек болот, б.а., мисалы, жок болот. " http://localhost:8080/edit" , бирок ал "http://localhost:8080/filmography/edit" болот ). Run дегенди басыңыз жана ал башталганга чейин күтө туруңуз. Мен муну алдым: баары жакшы окшойт, бирок бир эскертүү бар. Чындыгында, биздин баракчалар азыр жалпыга ачык жана дарек тилкесинде жолду жазуу менен түз кирүүгө болот. Биз http://localhost:8080/pages/films.jsp киребиз жана азыр биз баракчабызды контролердун кабары жок алдык. Бул эмнегедир туура эмес, ошондуктан биз атайын каталогду түзөбүз . Ичиндегилер коомчулуктан жашырылып, ага контроллер аркылуу гана кирүүгө болот. Биз өз көз карашыбыз менен каталогду ( ) ичинде жайгаштырабыз жана ага ылайык аны префикске кошобуз: /
/filmography
webapp
WEB-INF
pages
WEB-INF
ViewResolver
viewResolver.setPrefix("/WEB-INF/pages/");
Эми биз баракчабызды http://localhost:8080 дарегинен алабыз, бирок түз эле http://localhost:8080/WEB-INF/pages/films.jsp дарегине аракет кылсак, 404 катасын алабыз. Ооба, сонун, бизде эң жөнөкөй веб-тиркеме, алар айткандай Hello World. Учурда долбоордун структурасы төмөнкүдөй көрүнөт:
Модел
Бизде мурунтан эле көз караштар жана контроллер бар, бирок MVCде 3-тамга да бар, андыктан сүрөттү толуктоо үчүн биз моделди кошобуз. Пакеттеmodel
класс түзөлү Film
, мисалы, төмөнкү талаалар менен: int id
, String title
(аталышы), int year
(чыгарылган жылы), String genre
(жанр) жана boolean watched
(б.а. сиз бул тасманы көргөнсүзбү же көргөн эмессизби).
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
}
Өзгөчө эч нерсе жок, жөн гана катардагы класс, жеке талаалар, алуучулар жана сетерлер. Мындай класстардын an objectтери да POJO
(Plain Old Java Object) деп аталат, ошондой эле, б.а. "жөнөкөй Java an objectи". Эми ушундай an object түзүп, аны бетке көрсөтүүгө аракет кылалы. Азырынча аны кантип түзүү жана инициализациялоо жөнүндө көп кабатырланбайбыз. Аны сынап көрүү үчүн, келгиле, аны түз эле контроллерде түзөлү, мисалы, мындай:
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
Бул ыкманы колдонуп, бул an objectти биздикиге кошуңуз addObject
:
@RequestMapping(method = RequestMethod.GET)
public ModelAndView allFilms() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("films");
modelAndView.addObject("film", film);
return modelAndView;
}
Эми биз бул an objectти биздин баракчада көрсөтө алабыз. Hello World ордуна films.jsp
биз жазабыз ${film}
жана бул жерде " " атрибутунун атына туура келген an object film
алмаштырылат. Келгиле, аны иштетип, эмне болгонун карап көрөлү (an objectтин так чыгышы үчүн класс Film
кайра аныкталды toString()
):
Model-View-Controller
Бул этапта бизде толук кандуу Spring MVC тиркемеси бар окшойт. Улантуудан мурун, бардыгына дагы бир жолу көз чаптырып, анын кантип иштээрин түшүнүп алганыңыз жакшы болот. Интернетте бул тууралуу көптөгөн сүрөттөрдү жана диаграммаларды таба аласыз, мага бул жагат:Dispatcher Servlet
, андан кийин ал бул суроону иштетүү үчүн ылайыктуу контроллерди табат HandlerMapping
(бул контроллерди тандоо үчүн интерфейс, колдо болгон контроллердин кайсынысында ушундай даректи кабыл алган ыкма бар экенин текшерет) , ылайыктуу методду чакырат жана Controller
көрүнүш жөнүндө маалыматты кайтарат, андан кийин диспетчер ViewResolver
'a аркылуу аты боюнча керектүү көрүнүштү табат, андан кийин моделдин маалыматтары бул көрүнүшкө өткөрүлүп берилет жана биз чыгуу катары баракчабызды алабыз. Ушул сыяктуу бир нерсе. Улантылуу... Maven, Spring, MySQL, Hibernate жана биринчи CRUD тиркемесин тааныштыруу (1-бөлүк) Maven, Spring, MySQL, Hibernate жана биринчи CRUD тиркемесин тааныштыруу (2-бөлүк) Maven, Spring, MySQL, Hibernate жана биринчи CRUD тиркемеси (3-бөлүк) Maven, Spring, MySQL, Hibernate жана биринчи CRUD колдонмосуна киришүү (4-бөлүк)
GO TO FULL VERSION