Кіріспе
Біз білетіндей, Java-ның жетістігі желіге қосылуға ұмтылатын бағдарламалық жасақтаманың эволюциясының арқасында келді. Сондықтан біз кәдімгі « Hello World » консольдік қосымшасын негізге аламыз және оның консольдік қолданбадан желілік қолданба болу үшін не қажет екенін түсінеміз. Сонымен, алдымен Java жобасын жасау керек. Бағдарламашылар - жалқау адамдар. Тарихқа дейінгі дәуірде, кейбіреулері мамонттарды аулап жүргенде, басқалары отырып, Java кітапханалары мен каталог құрылымдарының әртүрлілігінде шатастырмауға тырысты. Әзірлеуші қосымшаны жасау процесін басқара алатындай етіп, ол жай ғана «Мен осындай және осындай 2-нұсқаның кітапханасын қалаймын» деп жаза алатындай етіп, олар арнайы құралдарды - жүйелерді құрастыруды ойлап тапты. Ең танымал екеуі - Мэвен және Градл . Бұл мақала үшін біз Gradle бағдарламасын қолданамыз. Егер бұрын каталог құрылымын өзіміз жасауымыз керек болса, енді Gradle Gradle Init плагинін пайдалана отырып, бір командада каталог құрылымы мен негізгі негізгі класы бар Java жобасын жасауға мүмкіндік береді:gradle init --type java-application
Бұл пәрмен үшін инициализацияны (init) орындайды. бізге Hello World консолі бар Java қолданбасы (java-application). Аяқтағаннан кейін файл каталогта пайда болады - build.gradle . Бұл біздің құрастыру сценарийі - яғни бұл үшін қандай әрекеттерді орындау керектігі сипатталған қосымшаны құруға арналған белгілі бір сценарий. Оны ашып, оған жолды қосамыз: jar.baseName = 'webproject'
Gradle жобада әртүрлі әрекеттерді орындауға мүмкіндік береді және бұл әрекеттер тапсырмалар деп аталады . Пәрменді (тапсырманы) орындау арқылы /build/libsgradle build
каталогында JAR файлы жасалады . Ал, сіз ойлағандай, оның атауы енді webproject.jar болады . Бірақ орындасақ , қате пайда болады: . Себебі java қосымшасы үшін белгілі бір манифестті тіркеу керек – бұл қосымшамен жұмыс істеу, оны қабылдаудың сипаттамасы. Содан кейін java қосымшасын орындайтын JVM қай сынып бағдарламаға кіру нүктесі және басқа ақпарат (мысалы, сынып жолы) екенін біледі. Егер құрастыру сценарийінің мазмұнын мұқият қарастыратын болсақ, қосылатын плагиндерді көреміз. Мысалы: Егер біз Gradle Java Plugin бетіне өтсек , манифестті конфигурациялай алатынымызды көреміз: java -jar ./build/libs/webproject.jar
no main manifest attribute
apply plugin: 'java'
jar {
manifest {
attributes 'Main-Class': 'App'
}
}
Негізгі класс, бағдарламаға кіру нүктесі біз үшін Gradle Init Plugin арқылы жасалған. Және ол тіпті mainClassName параметрінде көрсетілген. Бірақ бұл бізге ұнамады, өйткені... бұл параметр басқа плагинге, Gradle қолданбасының плагиніне сілтеме жасайды . Сонымен, бізде экранда Hello World көрсететін Java қолданбасы бар. Бұл Java қолданбасы JAR (Java ARchive) ішінде жинақталған. Бұл қарапайым, консольге негізделген, заманауи емес. Оны веб-қосымшаға қалай айналдыруға болады?
Сервлет API
Java желімен жұмыс істей алуы үшін ерте заманда Servlet API деп аталатын спецификация пайда болды . Дәл осы спецификация клиент пен serverдің өзара әрекеттесуін, клиенттен хабарлама алуды (мысалы, браузер) және жауапты жіберуді (мысалы, бет мәтінімен) сипаттайды. Әрине, содан бері көп нәрсе өзгерді, бірақ мәселе Java қолданбасы веб-қосымшаға айналуы үшін Servlet API қолданылады. Негізсіз болжам жасамау үшін дәл осы спецификацияны алайық: JSR-000340 JavaTM Servlet 3.1 . Бізді ең алдымен « 1-тарау: шолу » қызықтырады . Ол біз түсінуге тиіс негізгі ұғымдарды сипаттайды. Біріншіден, сервлет дегеніміз не? « 1.1 Сервлет дегеніміз не? » тарауында Сервлет контейнер арқылы басқарылатын және динамикалық мазмұнды жасайтын Java құрамдас бөлігі екені айтылады . Басқа Java компоненттері сияқты, сервлет byte-codeқа құрастырылған және Java технологиясы арқылы веб-serverге жүктелетін Java класы болып табылады. Сервлеттердің веб-клиентпен (мысалы, браузер) Сервлет контейнері жүзеге асыратын сұрау/жауап парадигмасы шеңберінде әрекеттесуі маңызды. Сервлеттер қандай да бір сервлет контейнерінде тұрады екен. Бұл не? « 1.2 Сервлет контейнері дегеніміз не? » тарауында Сервлет контейнері сұраулар жіберілетін және жауаптар жіберілетін желілік қызметтерді ұсынатын веб-serverдің немесе қолданбалы serverдің кейбір бөлігі екені айтылады . Бұл Сервлет контейнері сервлеттердің өмірлік циклін басқарады. Барлық Сервлет Контейнерлер HTTP протоколын кем дегенде қолдауы керек, бірақ басқаларына қолдау көрсетуі мүмкін. Мысалы, HTTPS. Сервлет контейнері сервлеттер орындалатын ортаға қауіпсіздікке қатысты кез келген шектеулерді қоя алатыны да маңызды. Сондай-ақ, « 10.6 Веб қолданбасының мұрағат файлына » сәйкес веб-бағдарлама WAR (Web ARchive) файлында пакеттелген болуы маңызды. Яғни, енді біз басқа нәрсе үшін банканы және қолданба плагиндерін алып тастауымыз керек. Және бұл Gradle WAR плагині . Ал jar.baseName орнына war.baseName себебін көрсетіңіз Біз енді jar плагинін пайдаланbyteындықтан, манифест параметрлерін де алып тастадық. Біз JAR іске қосқан кезде, Java виртуалды машинасына (JVM) біздің қолданбамен қалай жұмыс істеу керектігін манифест арқылы айту керек болды. Өйткені JVM оны іске қосты. Веб-қосымшаны веб-serverдің қандай да бір түрі орындайтын сияқты. Оған біздің веб-қосымшамен қалай жұмыс істеу керектігін айту керек пе? Және бұл иә болып шықты. Веб-қосымшалардың өздерінің арнайы манифесі бар. Ол Deployment Descriptor деп аталады . Бүкіл бөлім оған арналған: “ 14. Орналастыру дескрипторы ”. Маңызды бөлім бар: « 10-тарау:". Ол Servlet API тұрғысынан веб-қосымшаның не екені туралы айтады. Мысалы, " 10.5 Каталог құрылымы " тарауында орналастыру дескрипторы қай жерде болуы керектігі көрсетілген:/WEB-INF/web.xml
. WEB-INF қайда орналастыру керек? Gradle WAR плагинінде айтылғандай, ол жаңа макет қосады : src/main/webapp
.Сондықтан осындай каталогты жасайық, ішінде біз WEB-INF каталогын жасаймыз, ал ішінде web.xml файлын жасаймыз.Каталогтың болуы маңызды. META-INF емес, WEB-INF деп аталады! Оны " 14.5.1 Негізгі мысал " XML мысалынан көшіріп алайық :
specification is available at http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd
біз схемаға сілтемені барлық жерде көрсетілген xsd-мен ауыстыруымыз керек, оны version="2.5"
3.1-ге өзгертуді ұмытпауымыз керек, сонымен қатар барлық жерде аттар кеңістігін өзгерту керек ( xmlns және xsi:schemaLocation ішінде). Олар қай аттар кеңістігінде жұмыс істейтінімізді көрсетеді (қарапайым тілмен айтқанда, қандай элемент атауларын пайдалана аламыз). Схема файлын ашсаңыз, targetNamespace біз көрсетуге тиісті аттар кеңістігін қамтиды:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class App extends HttpServlet {
public String getGreeting() {
return "Hello world.";
}
public void doGet(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/html");
try {
response.getWriter().println(getGreeting());
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
Бірақ біздің жоба әлі дайын емес. Өйткені біз қазір Servlet API 3.1 нұсқасына тәуелдіміз. Бұл біздің құрастыру сценарийінде Servlet API-ге тәуелділікті көрсетуіміз керек дегенді білдіреді. JVM codeта жазғаныңыздың дұрыс екенін және оны қалай пайдалану керектігін білуі керек. Естеріңізде болса, спецификация негізінен барлығының қалай жұмыс істейтінін сипаттайтын интерфейстер ғана. Ал іске асыру веб-server жағында жатыр. Сондықтан, Servlet API болмаса, Maven Central жүйесінде қажетті кітапхананы табу болады: javax.servlet-api . Тәуелділіктер блогына жазба қосыңыз . Maven репозиторийінде, сіз көргендей, ол қамтамасыз етілген дейді. Тәуелділікті пайдаланбас бұрын, аумақты көрсету керек. Gradle-де "берілген" деп аталатын аумақ жоқ, бірақ оның " тек компиляция " ауқымы бар. Сондықтан біз мынаны көрсетеміз: providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
Уф, бәрі жақсы сияқты ма? Gradle Build жобамызды WAR файлына құрастырады. Ал енді онымен не істеуіміз керек? Біріншіден, бізге веб-server қажет. Google-де біз « веб-serverдің java тізімі » деп жазамыз және веб-serverлердің тізімін көреміз. Осы тізімнен таңдайық, мысалы, TomCat . Apache Tomcat веб-сайтына өтіңіз , соңғы нұсқасын (қазіргі 9 нұсқасы) zip мұрағаты ретінде жүктеп алыңыз (Windows үшін болса). Оны кейбір каталогқа шығарыңыз. Ура, бізде веб-server бар. bin ішкі каталогындағы веб-server каталогынан біз пәрмен жолынан catalina орындаймыз және қолжетімді опцияларды көреміз. жасайық: catalina start
. Әрбір веб-serverде веб-server бақылайтын каталогы болады. Онда веб-бағдарлама файлы пайда болса, веб-server оны орнатуды бастайды. Бұл орнату орналастыру немесе орналастыру деп аталады . Иә иә, сондықтан « орналастыру дескрипторы ». Яғни, қолданбаны қалай дұрыс орналастыру керек. Tomcat-та бұл каталог webapps болып табылады . Онда gradle build көмегімен жасаған соғысты көшіріп алайық. Осыдан кейін журналда біз келесідей нәрсені көреміз: Жақсырақ түсіну үшін tomcat каталогында келесі жолдарды қоса отырып, Deployment of web application archive [tomcat\webapps\webproject.war] has finished in [время] ms
файлды өңдейміз :\conf\tomcat-users.xml
http://127.0.0.1:8080/manager
жерде біз барлық қолданбалардың жолдарын көреміз. Біздің веб-жобаға /webproject жолы берілген болуы мүмкін. Бұл қандай жол? " 10.1 Веб-serverлердегі веб-қосымшалар " тарауындағы спецификация веб-бағдарламаның қолданба ішіндегі кейбір жолмен байланысты екенін айтады (бұл жағдайда, /webproject). Осы жол арқылы барлық сұраулар бірдей ServletContext-пен байланыстырылады. Бұл жолды contextRoot деп те атайды . Және " 10.2 ServletContext қатынасына " сәйкес сервлет контейнері веб-бағдарлама мен ServletContext бір-біріне қатыстырады. Яғни, әрбір веб-қосымшаның өзінің ServletContext бар. ServletContext дегеніміз не ? Техникалық сипаттамада көрсетілгендей, ServletContext сервлеттерді олар іске қосылған " бағдарлама көрінісімен" қамтамасыз ететін нысан болып табылады . Servlet мәтінмәні Servlet API спецификациясының 4-тарауында толығырақ сипатталған. Бір қызығы, 3.1 нұсқасындағы Servlet API енді web.xml болуын талап етпейді. Мысалы, annotationлар арқылы сервлетті анықтауға болады:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/app2")
public class App2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
response.getWriter().println("app2");
}
}
Сондай-ақ келесі тақырып бойынша ұсынылады: " Java EE сұхбаты - JEE Servlet API (сұрақтар мен жауаптар) ". Сонымен, бізде Сервлет бар - ол веб-клиентке қандай жауап беруге жауапты. Бізде пайдаланушыдан сұрауларды қабылдайтын, сервлет жолымен қол жеткізілген жолға сәйкес келетін және сәйкестік табылса, Сервлетті орындайтын ServletContainer бар. Жақсы. Бұл әлем суретінде көктем қандай орын алады ?
Spring Web MVC
Керемет, бізде веб-қосымша бар. Енді көктемді қосу керек. Мұны қалай істей аламыз? Алдымен көктемді жобаға қалай дұрыс қосу керектігін анықтау керек. Бұрын көктемгі платформа жобасының құжаттамасына сәйкес мұны істеуге болатыны белгілі болды , бірақ қазір « Платформа 2019 жылдың 9 сәуірінде қолдау көрсетілетін қызмет мерзімін аяқтайды », яғни оны жасау ұсынылмайды. оны қолданыңыз, өйткені ол жақын арада бұдан былай қолдау көрсетпейді. Шығудың жалғыз жолы - « Платформа пайдаланушыларына Spring Boot тәуелділігін басқаруды пайдалануды бастау ұсынылады ». Сондықтан Spring Boot құжаттамасына көшейік . Түсіндіруге рұқсат етіңіздер, біз Spring Boot қолданбасының өзін емес, тек Spring Boot-тен тәуелділікті басқаруды қолданамыз. Яғни, Spring Boot жобасы кітапханалардың қай нұсқаларын (соның ішінде Spring MVC) пайдалану керектігі туралы білім бере алады. Онда біз 3.2 табамыз . Spring Boot тәуелділігін басқаруды оқшаулауда пайдалану . Құжаттамаға сәйкес құрастыру сценарийіне келесіні қосыңыз:plugins {
id 'org.springframework.boot' version '2.0.4.RELEASE' apply false
}
apply plugin: 'io.spring.dependency-management'
Және
dependencyManagement {
imports {
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
}
}
Көріп отырғаныңыздай, біз көрсеттік apply false
, яғни. Біз Spring Boot қолданбасының өзін пайдаланбаймыз, бірақ тәуелділікті басқаруды сол жерден қолданамыз. Бұл тәуелділікті басқару BOM деп те аталады - " Материалдар тізімі ". Енді біз Spring Web MVC жобасының өзін қосуға дайынбыз. Spring Web MVC Spring Framework жобасының бөлігі болып табылады және бізді " Web Servlet " бөлімі қызықтырады . Құрылым сценарийіне тәуелділікті қосамыз: compile 'org.springframework:spring-webmvc'
. Көріп отырғанымыздай, біз ауқымды компиляцияны орнаттық, өйткені веб-server бізге көктемді бермейді. Біздің жоба Көктем кітапханасын өз ішіне қосуға мәжбүр. Әрі қарай, біз үшін « 1.2. DispatcherServlet » бөлімін оқу маңызды , мұнда Spring MVC « Front controller » үлгісінің айналасында құрылған , мұнда конфигурацияны және басқа компоненттерге өкілдік беруді қамтамасыз ететін қандай да бір орталық сервлет бар. . Диспетчерді диспетчер деп аударуға болады. Сонымен, ең алдымен, web.xml файлында мынаны жариялаймыз:
applicationContext.xml
Біз бұрын көрсеткен файлды жасауды ұмытпаңыз . Spring құжаттамасынан мысал келтірейік: " 1.10.3. Класстарды автоматты түрде анықтау және бұршақ анықтамаларын тіркеу ".
-
Веб конфигурациясы, мысалы, Java мәнері конфигурациясы:
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/WEB-INF/pages/", ".jsp"); } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }
Бұл мысал Spring Framework құжаттамасында сипатталған: " 1.11. MVC конфигурациясы ".
Мұнда біз jsp беттерінің қай жерде орналасқанын анықтауға көмектесетін ViewResolver бағдарламасын тіркейміз. Екінші әдіс « Әдепкі сервлеттің » қосылғанын қамтамасыз етеді.
Бұл туралы толығырақ мына жерден оқи аласыз: « Әдепкі-сервлет-өңдеуші не қажет және оны пайдалану ».
-
Нақты JSP-ге сұрауларды салыстыруды сипаттауға арналған HelloController контроллері
@Controller public class HelloController { @GetMapping("/hello") public String handle(Model model) { return "hello"; } }
Мұнда біз құжаттамада " 1.4. Аннотацияланған контроллерлер " тарауында сипатталған @Controller annotationсын қолдандық.
/webproject/hello
(мұнда /webproject мәтінмән түбірі болып табылады), алдымен DispatcherServlet өңделеді. Ол негізгі диспетчер ретінде біздің /* ағымдағы сұрауға сәйкес келетінін анықтайды, яғни DispatcherServlet бірдеңе істеуі керек. Содан кейін ол тапқан барлық салыстырулардан өтеді. Ол /hello-ға салыстырылған және оны орындайтын дескриптор әдісі бар HelloController бар екенін көреді. Бұл әдіс «сәлем» мәтінін қайтарады. Бұл мәтінді ViewResolver алады, ол serverге клиентке көрсетілуі керек jsp файлдарын қайдан іздеу керектігін айтады. Осылайша, клиент осы өте қымбат бетті алады.
GO TO FULL VERSION