Spring WebFlux annotatsiyalarga asoslangan dasturlash modelini taqdim etadi, bunda @Controller va @RestController komponentlari so'rovlarni aniqlash, so'rovlar kiritish, istisnolarni qayta ishlash va boshqalar uchun annotatsiyalarni ishlatadilar. Annotatsiyalangan kontrollerlar moslashuvchan metod imzolariga ega bo'lib, bazaviy sinflarni kengaytirishlari yoki ma'lum interfeyslarni amalga oshirishlari shart emas.
Quyidagi ro'yxatda asosiy misol keltirilgan:
@RestController
public class HelloController {
@GetMapping("/hello")
public String handle() {
return "Hello WebFlux";
}
}
@RestController
class HelloController {
@GetMapping("/hello")
fun handle() = "Hello WebFlux"
}
Oldingi misolda metod javobni yozish uchun String ni qaytaradi.
@Controller
Siz Spring-ning standart binalarini aniqlash orqali kontroller binalarini aniqlashingiz mumkin. @Controller stereotipi avtomatik aniqlashni ta'minlaydi va classpath-da @Component annotatsiyasiga ega bo'lgan sinflarni aniqlash va binalar ta'riflarini avtomatik ro'yxatga olish uchun Spring-ning umumiy qo'llab-quvvatlash vositalariga mos keladi. Bu, shuningdek, veb-komponent sifatida belgilangan sinf uchun stereotip sifatida ishlaydi.
@Controller annotatsiyasiga ega binalarni avtomatik aniqlashni yoqish uchun siz Java konfiguratsiyasida komponentlarni skanerlashni qo'shishingiz mumkin, quyidagi misol ko'rsatilgan:
@Configuration
@ComponentScan("org.example.web")
public class WebConfig {
// ...
}
- Paketi skanerlash
org.example.web.
@Configuration
@ComponentScan("org.example.web")
class WebConfig {
// ...
}
- Paketi skanerlash
org.example.web.
@RestController - bu o'z-o'zidan @Controller va @ResponseBody annotatsiyalari bilan meta-annotatsiya qilingan murakkab annotatsiya bo'lib, u har bir metodi @ResponseBody annotatsiyasini meros qilib olgan kontrollerni belgilab, HTML-shablon orqali ko'rinishni aniqlash va ko'rsatish o'rniga javob tanasiga to'g'ridan-to'g'ri yozishni amalga oshiradi.
So'rovlarni xaritalash
@RequestMapping annotatsiyasi kontroller metodlariga so'rovlarni xaritalash uchun ishlatiladi. U URL-manzilga, HTTP-metodga, so'rov parametrlariga, sarlavhalariga va ma'lumot uzatish muhitlari turlariga moslash uchun turli atributlarga ega. Siz uni sinf darajasida umumiy xaritalashlarni ifodalash uchun yoki metod darajasida endpoint uchun aniq xaritalashni aniqlash uchun ishlatishingiz mumkin.
HTTP-metod uchun maxsus @RequestMapping annotatsiyasining qisqartirilgan variantlari ham mavjud:
-
@GetMapping -
@PostMapping -
@PutMapping -
@DeleteMapping -
@PatchMapping
Yuqoridagi annotatsiyalar maxsus annotatsiyalardir, chunki ko'pchilik kontroller metodlarining aniq HTTP-metodiga xaritalangan bo'lishi ehtimoli yuqori. Biroq, @RequestMapping annotatsiyasi hali ham umumiy xaritalashlarni ifodalash uchun sinf darajasida kerakli bo'lib qolmoqda.
Quyidagi misolda sinf va metod darajasidagi xaritalashlar ishlatiladi:
@RestController
@RequestMapping("/persons")
class PersonController {
@GetMapping("/{id}")
public Person getPerson(@PathVariable Long id) {
// ...
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void add(@RequestBody Person person) {
// ...
}
}
@RestController
@RequestMapping("/persons")
class PersonController {
@GetMapping("/{id}")
fun getPerson(@PathVariable id: Long): Person {
// ...
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
fun add(@RequestBody person: Person) {
// ...
}
}
URI shablonlari
So'rovlarni xaritalash uchun odatdagi niqoblar (ularni glob patterns deb ham atashadi) va o'rinnoma belgilar orqali xaritalash mumkin:
| Shablon | Ta'rif | Misol |
|---|---|---|
|
|
Bitta belgiga mos keladi |
|
|
|
Yo'l segmentida noldan ko'p belgigacha mos keladi |
|
|
|
Yo'lning oxirigacha bo'lgan noldan ko'proq yo'l segmentlariga mos keladi |
|
|
|
Yo'l segmentiga mos keladi va uni "name" nomli o'zgaruvchiga yozadi. |
|
|
|
|
|
|
|
Yo'lning oxirigacha bo'lgan noldan ko'proq yo'l segmentlariga mos keladi va uni "path" nomli o'zgaruvchiga yozadi. |
|
Ushlangan URI o'zgaruvchilariga @PathVariable annotatsiyasi orqali kirish mumkin, quyidagi misolda ko'rsatilganidek:
@GetMapping("/owners/{ownerId}/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
// ...
}
@GetMapping("/owners/{ownerId}/pets/{petId}")
fun findPet(@PathVariable ownerId: Long, @PathVariable petId: Long): Pet {
// ...
}
URI o'zgaruvchilarini sinf va metod darajasida e'lon qilish mumkin, quyidagi misolda ko'rsatilganidek:
@Controller
@RequestMapping("/owners/{ownerId}")
public class OwnerController {
@GetMapping("/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
// ...
}
}
- Sinf darajasida URI identifikatori xaritasi.
- Metod darajasida URI identifikatori xaritasi.
@Controller
@RequestMapping("/owners/{ownerId}")
class OwnerController {
@GetMapping("/pets/{petId}")
fun findPet(@PathVariable ownerId: Long, @PathVariable petId: Long): Pet {
// ...
}
}
- Sinf darajasida URI xaritasi.
- Metod darajasida URI xaritasi.
URI o'zgaruvchilari mos keladigan turga aylantiriladi, aks holda TypeMismatchException xatosi yuzaga keladi. Oddiy turlar (int, long, Date va hokazo) odatda qo'llab-quvvatlanadi, lekin siz har qanday boshqa turdagi ma'lumotlar uchun qo'llab-quvvatlashni ro'yxatga olishingiz mumkin.
Siz URI o'zgaruvchilariga maxsus nom berishingiz mumkin (masalan, @PathVariable("customId")), lekin bu ma'lumotlarni ko'rsatmasangiz ham, agar nomlar bir xil bo'lsa va sizning kodingiz otladka ma'lumotlari bilan yoki Java 8-dagi -parameters kompilyator bayrog'i bilan kompilyatsiya qilingan bo'lsa, ishlaydi.
{*varName} sintaksisi URI o'zgaruvchisini e'lon qiladi, bu nol yoki undan ko`p qoldirilgan yo'l segmentlariga mos keladi. Masalan, /resources/{*path} katalogdagi barcha fayllarga mos keladi /resources/, "path" o'zgaruvchisi katalogdagi to'liq yo'lni ko'rsatadi /resources.
{varName:regex} sintaksisi URI o'zgaruvchisini regex orqali e'lon qiladi, u quyidagi sintaksisga ega: {varName:regex}. Masalan, /spring-web-3.0.5.jar URL-manzilida quyidagi metod fayl nomini, versiyasini va kengaytmasini olishadi:
@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String ext) {
// ...
}
@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
fun handle(@PathVariable version: String, @PathVariable ext: String) {
// ...
}
URI identifikatori yo`l shablonlari, shuningdek, ${…} ichiga o'rnatilgan joy to'ldiruvchilarni o'z ichiga olishi mumkin. Ular PropertySourcesPlaceholderConfigurer yordamida mahalliy, tizimdagi, atrof-muhitdagi va boshqa xususiyatlar manbalarida ishga tushiriladi. Masalan, ba'zi tashqi konfiguratsiyaga asoslangan asosiy URL-manzilni parametrik qilish mumkin.
PathPattern va
PathPatternParserdan foydalanadi. Ikkala sinf ham
spring-webda joylashgan bo'lib, ko'plab URI yo'l shablonlari ish vaqti davomida xaritaga ega bo'lgan veb-ilovalarda HTTP yo`l URL-larini ishlatish uchun maxsus ishlab chiqilgan.
Spring WebFlux Spring MVC-dan farqli ravishda tasvirli suffiks xaritalashni qo'llab-quvvatlamaydi, unda /person kabi xaritalash ham /person.* bilan mos keladi. URL-manzil asosida mazmunni moslashtirish uchun, agar kerak bo'lsa, maslahatingiz sifatida so'rov parametridan foydalanishni tavsiya etamiz, bu sodda, aniq va URL yo'li ekspluotatsiyasiga kamroq moyil.
Shablonlarni taqqoslash
Agar bir nechta namuna URL-manzilga mos kelsa, eng yaxshi mos keladiganini topish uchun ularni taqqoslash kerak. Bu PathPattern.SPECIFICITY_COMPARATOR orqali amalga oshiriladi, bu esa yanada aniqroq bo'lgan namunalarni qidiradi.
Har bir namuna uchun URI identifikatori o'zgaruvchilari va o'rinnoma belgilarining soniga asoslanib baho hisoblanadi, bunda URI o'zgaruvchisi o'rinndan past baholab olinadi. Kam skorli namuna g'olib bo'ladi. Agar ikki namunada bir xil ko'rsatkichlar bo'lsa, ko'proq uzunlikdagi tanlanadi.
Hamma narsani tutuvchi namuna (masalan, **, {*varName}) hisobdan chiqariladi va har doim oxirida tartiblanadi. Agar ikki namuna hamma narsani tutuvchi bo'lsa, ko'proq uzunlikdagi tanlanadi.
Ma'lumot uzatish muhitlari turlari
So'rovni Content-Type asosida ko'rsatilgan misol quyida ko'rsatilganidek:
@PostMapping(path = "/pets", consumes = "application/json")
public void addPet(@RequestBody Pet pet) {
// ...
}
@PostMapping("/pets", consumes = ["application/json"])
fun addPet(@RequestBody pet: Pet) {
// ...
}
"consumes" atributi ham inkor ifodalarini qo'llab-quvvatlaydi - masalan, !text/plain text/plaindan boshqa har qanday turdagi mazmunni anglatadi.
Siz umumiy "consumes" atributini sinf darajasida e'lon qilishingiz mumkin. Biroq, so'rov xaritalash atributlarining ko'pchiligidan farqli o'laroq, sinf darajasida foydalanilganda, metod darajasidagi "consumes" atributi aslida sinf darajasidagi e'lonni kengaytirish o'rniga uni bekor qiladi.
MediaType ko'pincha qo'llaniladigan ma'lumot uzatish muhit turiga doir konstantalarni ta'minlaydi, masalan,
APPLICATION_JSON_VALUE va
APPLICATION_XML_VALUE.
Ma'lumot uzatish muhitlari turlarini ishlab chiqarish
So'rovni Accept sarlavhasi va kontroller metodi ishlab chiqaradigan kontent turlariga asoslanib ko'rsatilgan diapazonni toraytirishingiz mumkin, quyidagi misolda ko'rsatilganidek:
@GetMapping(path = "/pets/{petId}", produces = "application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId) {
// ...
}
@GetMapping("/pets/{petId}", produces = ["application/json"])
@ResponseBody
fun getPet(@PathVariable String petId): Pet {
// ...
}
Ma'lumot uzatish muhit turi belgilar to'plamini aniqlashi mumkin. Inkor qilinadigan ifodalar qo'llab-quvvatlanadi - masalan, !text/plain text/plaindan boshqa har qanday kontent turini anglatadi.
Umumiy "produces" atributini sinf darajasida e'lon qilishingiz mumkin. Biroq, ko'pgina so'rov xaritalash atributlaridan farqli o'laroq, sinf darajasida foydalanilganda, metod darajasidagi "produces" atributi aslida sinf darajasidagi e'lonni kengaytirish o'rniga uni bekor qiladi.
MediaType ko'pincha qo'llaniladigan ma'lumot uzatish muhit turiga doir konstantalarni ta'minlaydi, masalan,
APPLICATION_JSON_VALUE va
APPLICATION_XML_VALUE.
Parametrlar va sarlavhalar
So'rov parametrlari shartlari asosida so'rov xaritalash diapazonini toraytirishingiz mumkin. So'rov parametrlari mavjudligini (myParam), yo'qligini (!myParam) yoki ma'lum bir qiymat mavjudligini (myParam=myValue) tekshirishingiz mumkin. Quyidagi misollarda qiymat mavjudligi tekshiriladi:
@GetMapping(path = "/pets/{petId}", params = "myParam=myValue")
public void findPet(@PathVariable String petId) {
// ...
}
myParammyValuega teng ekanligiga ishonch hosil qiling.
@GetMapping("/pets/{petId}", params = ["myParam=myValue"])
fun findPet(@PathVariable petId: String) {
// ...
}
myParammyValuega teng ekanligiga ishonch hosil qiling.
Xuddi shu tarzda so'rov sarlavhalari shartlari bilan ham ishlatishingiz mumkin, quyidagi misolda ko'rsatilganidek:
@GetMapping(path = "/pets", headers = "myHeader=myValue")
public void findPet(@PathVariable String petId) {
// ...
}
myHeadermyValuega teng ekanligiga ishonch hosil qiling.
@GetMapping("/pets", headers = ["myHeader=myValue"])
fun findPet(@PathVariable petId: String) {
// ...
}
myHeadermyValuega teng ekanligiga ishonch hosil qiling.
HEAD, OPTIONS HTTP-metodlar
@GetMapping (va @RequestMapping(method=HttpMethod.GET)) so'rovlarni xaritalash uchun HEAD HTTP-metodini shaffof tarzda qo'llab-quvvatlaydi. Kontroller metodlarini o'zgartirishning hojati yo'q. Javobni o'ramlash funksiyasi HttpHandlerda qo'llanilib, Content-Length sarlavhasini o'rnatadi (javob yozmasdan).
OPTIONS HTTP-metodi odatda Allow javob sarlavhasini o'rnatish orqali ishlov beradi, bu esa @RequestMapping annotatsiyasi bilan belgilangan barcha metodlarda ko'rsatilgan HTTP-metodlar ro'yxatiga o'zgaradi.
@RequestMapping annotatsiyasining HTTP-metodlari e'lon qilinmagan holda, Allow sarlavhasi GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONSga o'rnatiladi. Kontroller metodlari har doim qo'llab-quvvatlanadigan HTTP-metodlarni e'lon qilishi kerak (masalan, HTTP-metod uchun maxsus variantlar bilan: @GetMapping, @PostMapping va boshqalar).
Siz aniq @RequestMapping annotatsiyasini HEAD va OPTIONS HTTP-metodlariga xaritalashingiz mumkin, lekin odatda bunga ehtiyoj yo'q.
Maxsus annotatsiyalar
Spring WebFlux so'rovlarni xaritalash uchun murakkab annotatsiyalardan foydalanishni qo'llab-quvvatlaydi. Bu annotatsiyalar @RequestMapping meta-annotatsiyalari bo'lib, ular @RequestMapping annotatsiyasi bilan belgilanadigan atributlarning qisman (yoki barchasi) qayta e'lon qilinishini takrorlash uchun tuzilgandir.
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping va @PatchMapping murakkab annotatsiyalarning misollaridir. Ular kontroller metodlarining ko'pchilik ehtimoliy xususiyatlarini ifodalab o'tishda @RequestMapping annotatsiyasidan ko'ra ko'proq xususiylashtirilgan, to'liq maqsadli bo'lishi mumkin.
Spring WebFlux, shuningdek, maxsus so'rov xaritalash atributlarini va maxsus belgilangan so`rov xaritalash mantiqi bilan qo'llab-quvvatlashni ta'minlaydi. Bu ResponseEntityning kengaytirilgan versiyasi bo'lib, so'rov xaritasini qo'llab-quvvatlash uchun getCustomMethodCondition metodini qayta belgilash va maxsus atributni tekshirishni talab qiladi.
Aniq ro'yxatga olish
Kontroller metodlarini dasturiy ro'yxatdan o'tkazishingiz mumkin, bu esa dinamik ro'yxatga olish yoki murakkabroq hollarda - masalan, bir xil kontrollerning turli namunalarini turli URL-manzillar ostida boshqarishga imkon beradi. Quyidagi misolda qanday qilib buni qilish mumkinligi ko'rsatilgan:
@Configuration
public class MyConfig {
@Autowired
public void setHandlerMapping(RequestMappingHandlerMapping mapping, UserHandler handler) (1) throws NoSuchMethodException {
RequestMappingInfo info = RequestMappingInfo
.paths("/user/{id}").methods(RequestMethod.GET).build();
Method method = UserHandler.class.getMethod("getUser", Long.class);
mapping.registerMapping(info, handler, method);
}
}
- Maqsadli handler va kontrollerlar uchun handler xaritasini kiritamiz.
- So'rov xaritalash metadata tayyorlaymiz.
- Handler metodini olamiz.
- Ro'yxatdan o'tishni qo'shamiz.
@Configuration
class MyConfig {
@Autowired
fun setHandlerMapping(mapping: RequestMappingHandlerMapping, handler: UserHandler) {
val info = RequestMappingInfo.paths("/user/{id}").methods(RequestMethod.GET).build()
val method = UserHandler::class.java.getMethod("getUser", Long::class.java)
mapping.registerMapping(info, handler, method)
}
}
- Maqsadli handler va kontrollerlar uchun handler xaritasini kiritamiz.
- So'rov xaritalash metadata tayyorlaymiz.
- Handler metodini olamiz.
- Ro'yxatdan o'tishni qo'shamiz.
Handler metodlar
@RequestMapping annotatsiyali handler metodlar moslashuvchan imzolarga ega bo'lib, kontroller metodining qator qo'llab-quvvatlangan argumentlari va qaytadigan qiymatlarini tanlashi mumkin.
Metod argumentlari
Quyidagi jadvalda kontroller metodining qo'llab-quvvatlanadigan argumentlari ko'rsatilgan.
Reaktiv turlar (Reactor, RxJava yoki boshqalar) bloklashni kiritish-chiqarish talab qiladigan argumentlarda qo'llab-quvvatlanadi (masalan, so'rov tanasini o'qish). Bu "Tavsif" ustunida belgilanadi. Bloklanishni talab qilmaydigan argumentlarda reaktiv turlar kutilmadi.
JDK 1.8 dan ijro etiladigan java.util.Optional argumenti required atributiga ega annotatsiyalar bilan kombinatsiyada (masalan, @RequestParam, @RequestHeader va boshqalar) metod argumenti sifatida qo'llab-quvvatlanadi va required=false ekvivalenti hisoblanadi.
| Kontroller metodining argumenti | Ta'rif |
|---|---|
|
|
To'liq |
|
|
HTTP so'rov yoki javobga kirishni ta'minlaydi. |
|
|
Sessiyaga kirishni ta'minlaydi. Bu yangi sessiyani boshlamaydi, agar atributlar qo'shilmasa. Reaktiv turlar bilan qo'llab-quvvatlanadi. |
|
|
Joriy tasdiqlangan foydalanuvchi - ma'lum bo'lsa, |
|
|
So'rovning HTTP-metodi. |
|
|
So'rovning joriy mintaqaviy sozlamalari, mavjud bo'lgan eng konkret |
|
|
So'rovning joriy soat mintaqasi, |
|
|
URI identifikatori shablon o'zgaruvchilariga kirishni ta'minlaydi. |
|
|
URI identifikatori yo'l segmentlaridagi "ism-qiymat" juftliklariga kirishni ta'minlaydi. |
|
|
So'rov parametrlari kirishni ta'minlaydi. Parametr qiymatlari metod argumentining e'lon qilingan turiga aylantiriladi.
|
|
|
So'rov sarlavhalariga kirishni ta'minlaydi. Sarlavha qiymatlari metod argumentining e'lon qilingan turiga aylantiriladi. |
|
|
HTTP cookie-iga kirishni ta'minlaydi. Cookie qiymatlari metod argumentining e'lon qilingan turiga aylantiriladi. |
|
|
HTTP so'rov tanasiga kirishni ta'minlaydi. Tana tarkibi |
|
|
So'rov sarlavhalari va tanasiga kirishni ta'minlaydi. Tana |
|
|
|
|
|
HTML kontrollerlarda foydalaniladigan va ko'rinish tasvirlashning bir qismi sifatida shablonlarda ko'rsatadigan modelga kirishni ta'minlaydi. |
|
|
Modeldagi mavjud atributga kirishni ta'minlaydi (agar mavjud bo'lmasa, uning nusxasi yaratiladi) ma'lumotlar bog'lanishi va validatsiyasi bilan.
|
|
|
Buyruq ob'ekti uchun ma'lumotlarni bog'lash va validatsiya xatolariga kirishni ta'minlaydi, ya'ni |
|
|
Forma qayta ishlashini tugatishni belgilash uchun, bu |
|
|
Amaldagi so'rovning host, port, sxema va konteks yo'li bilan bog'liq URL-manzilni tayyorlash uchun ishlatiladi. |
|
|
Har qanday sessiya atributiga kirish uchun, |
|
|
So'rov atributlariga kirishni ta'minlaydi. |
| Boshqa har qanday argument |
Agar metod argumenti yuqoridagilarning hech biriga mos kelmasa, u |
Qaytadigan qiymatlar
Quyidagi jadvalda kontroller metodining qo'llab-quvvatlanadigan qaytadigan qiymatlari ko'rsatilgan. E'tibor bering, Reactor, RxJava va boshqa kutubxonalarning reaktiv turlari odatda barcha qaytayotgan qiymatlar uchun qo'llab-quvvatlanadi.
| Kontroller metodining qaytadigan qiymati | Ta'rif |
|---|---|
|
|
Qaytadigan qiymat |
|
|
To'liq javob, shu jumladan HTTP-sarlavhalar va tana, |
|
|
Sarlavhalar bilan, lekin tanasiz, javobni qaytarish uchun mo'ljallangan. |
|
|
Ko'rinish nomi, |
|
|
Notanish model bilan ko'rinish |
|
|
Modelga qo'shiladigan atributlar, ko'rinish nomi esa so'rov yo'liga asoslanib aniqlanadi. |
|
|
Modelga qo'shilgan atribut, ko'rinish esa so'rov yo'liga asoslanib aniqlanadi.
|
|
|
Model va ko'rinish ssenariylari uchun API. |
|
|
|
GO TO FULL VERSION