JavaRush /Kurslar /All lectures for UZ purposes /Metodlarni ishlov beruvchi

Metodlarni ishlov beruvchi

All lectures for UZ purposes
Daraja, Dars
Mavjud

@RequestMapping annotatsiyasi bilan metodlar moslashuvchan imzoga ega bo'lib, controller metodining qator qo'llab-quvvatlanadigan argumentlari va qaytish qiymatlaridan tanlab olishlari mumkin.

Metodning argumentlari

Quyidagi jadvalda controller metodining qo'llab-quvvatlanadigan argumentlari tavsiflanadi. Reaktiv turlari hech bir argument uchun qo'llab-quvvatlanmaydi.

JDK 8 dan java.util.Optional argumenti required atributiga ega annotatsiyalar bilan mos ravishda (masalan, @RequestParam, @RequestHeader va boshqalar) metodning argumenti sifatida qo'llab-quvvatlanadi va required=false ga teng.

Controller metodi argumenti Tavsif

WebRequest, NativeWebRequest

So'rov parametrlariga, so'rov va sessiyaga atributlarga to'g'ridan-to'g'ri foydalanmasdan turib, tiplangan kirishni ta'minlaydi.

javax.servlet.ServletRequest, javax.servlet.ServletResponse

Har qanday aniq so'rov yoki javob turini tanlash uchun mo'ljallangan - masalan, ServletRequest, HttpServletRequest yoki Spring'dan MultipartRequest, MultipartHttpServletRequest.

javax.servlet.http.HttpSession

Sessiyaning mavjudligidan foydalanishni ta'minlaydi. Natijada, bunday argument hech qachon null bo'lmaydi. Sessiyaga kirish thread-safe emasligini unutmang. Sessiyaga bir nechta so'rovlar uchun bir vaqtda kirishga ruxsat berilgan bo'lsa, RequestMappingHandlerAdapter instansiyasining synchronizeOnSession bayrog'ini true ga o'rnatishni o'ylab ko'ring.

javax.servlet.http.PushBuilder

Servlet 4.0 push builder API HTTP/2 resurslarini dasturiy ravishda yuborish uchun. Servlet spetsifikatsiyasiga ko'ra, mijoz ushbu HTTP/2 funksiyasini qo'llab-quvvatlamasa, PushBuilder injektsiya qilingan instansiyasi bo'sh bo'lishi mumkinligini unutmang.

java.security.Principal

Joriy autentifikatsiya qilingan foydalanuvchi - agar ma'lum bo'lsa, Principal ning aniq amalga oshirish sinfi bo'lishi mumkin.

Ushbu argument, agar u tanlangan indentifikatorlarni ajratish uchun mo'ljallangan anotatsiyaga ega bo'lsa, tezroq ajratilmaganligini unutmang. Masalan, Spring Security'dan Authentication Principal ni amalga oshiradi va HttpServletRequest#getUserPrincipal orqali injektsiya qilinadi, faqat u @AuthenticationPrincipal bilan ham annotatsiyalanmagan bo'lsa, Spring Security ning tanlangan ajratgichi orqali Authentication#getPrincipal orqali ajratiladi.

HttpMethod

So'rovning HTTP metodi.

java.util.Locale

So'rovning joriy hududiy sozlanmalari, mavjud qandaydir LocaleResolver tomonidan aniqlanadi.

java.util.TimeZone + java.time.ZoneId

So'rov bilan bog'liq vaqt zonasi, LocaleContextResolver tomonidan aniqlangan.

java.io.InputStream, java.io.Reader

So'rovning xom tanasi bilan Servlet API'da namoyon etilgan shaklda kirish uchun mo'ljallangan.

java.io.OutputStream, java.io.Writer

Javobning xom tanasi bilan Servlet API'ga ochiq kirish uchun mo'ljallangan.

@PathVariable

URI identifikatorlarining shablon o'zgaruvchilariga kirish uchun mo'ljallangan.

@MatrixVariable

URI identifikatorlarining yo'l segmentlaridagi "nom-qiymat" juftliklariga kirish uchun mo'ljallangan.

@RequestParam

Servlet so'rov parametrlariga kirish uchun mo'ljallangan, shu jumladan ko'p qismli fayllar. Parametr qiymatlari metodning deklaratsiyalangan argument turiga o'zgartiriladi.

Oddiy parametr qiymatlari uchun @RequestParam annotatsiyasidan foydalanish majburiy emasligini unutmang. Ushbu jadval oxiridagi "Boshqa har qanday argument" ga qarang.

@RequestHeader

So'rovning sarlavhalariga kirish uchun mo'ljallangan. Sarlavha qiymatlari metodning deklaratsiyalangan argument turiga o'zgartiriladi.

@CookieValue

Cookie qiymatlari orqali kirish ta'minlash uchun mo'ljallangan. Cookie qiymatlari metodning deklaratsiyalangan argument turiga o'zgartiriladi.

@RequestBody

HTTP so'rov tanasiga kirish uchun. Tana mazmuni HttpMessageConverter amalga oshirishlari yordamida metodning deklaratsiyalangan argument turiga aylantiriladi.

HttpEntity<B>

So'rovning sarlavhalari va tanasiga kirish uchun mo'ljallangan. Tana HttpMessageConverter yordamida aylantiriladi.

@RequestPart

multipart/form-data so'rovidagi qismga HttpMessageConverter orqali tanani aylantirish orqali kirishni ta'minlash uchun mo'ljallangan.

java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap

HTML-controllerlarda va ko'rinishni render qilishning bir qismi sifatida shablonlarda ishlatiladigan modelga kirishni ta'minlash uchun mo'ljallangan.

RedirectAttributes

Redirect holatida ishlatiladigan attributlarni (ya'ni, so'rov satriga qo'shiladi) va redirect so'rovidan keyin qabul qilingan flash attributlarini belgilaydi.

@ModelAttribute

Modeldagi mavjud atributga kirish uchun (agar yo'q bo'lsa, uning nusxasi yaratiladi) ma'lumotlarni biriktirish va tekshirish bilan.

Annotatsiya @ModelAttribute dan foydalanish majburiy emas (masalan, atributlarini o'rnatish uchun). Ushbu jadval oxiridagi "Boshqa har qanday argument" ga qarang.

Errors, BindingResult

Komanda ob'ekti uchun (ya'ni, @ModelAttribute annotatsiyasi bilan foydalaniladigan argument) yoki @RequestBody yoki @RequestPart annotatsiyalari bilan annotatsiyalangan argumentlar uchun tekshirish xatolariga kirishni ta'minlash uchun mo'ljallangan. Errors yoki BindingResult argumenti to'g'ridan-to'g'ri tekshiriladigan metod argumentidan keyin e'lon qilinishi kerak.

SessionStatus + class-level @SessionAttributes

Formani yakunlash belgisini qo'yish uchun mo'ljallangan, bu esa @SessionAttributes annotatsiyasi bilan class-levelda e'lon qilingan sessiya attributlarini tozalashni qo'zg'atadi.

UriComponentsBuilder

Joriy so'rov va servlet renderining literal komponentlari bilan bog'langan host, port, sxema va kontekstli yo'l URL manzili tayyorlash uchun mo'ljallangan.

@SessionAttribute

Session attributlariga kirishni ta'minlash uchun mo'ljallangan, bu sinf-levelda @SessionAttributes annotatsiyasi orqali e'lon qilingan model attributlaridan farqli o'laroq.

@RequestAttribute

So'rov attributlariga kirishni ta'minlash uchun mo'ljallangan.

Boshqa har qanday argument

Agar metod argumenti ushbu jadvaldagi avvalgi hech bir qiymatga to'g'ri kelmasa va oddiy tur bo'lsa ( BeanUtils#isSimpleProperty tomonidan aniqlangan), u @RequestParam sifatida hal qilinadi. Aks holda, u @ModelAttribute sifatida hal qilinadi.

Qaytish qiymatlari

Quyidagi jadvalda controller metodining qo'llab-quvvatlanadigan qaytish qiymatlari tavsiflanadi. Reaktiv turlari barcha qaytish qiymatlari uchun qo'llab-quvvatlanadi.

Controller metodi qaytish qiymati Tavsif

@ResponseBody

Qaytish qiymati HttpMessageConverter orqali o'zgartiriladi va javobga yoziladi.

HttpEntity<B>, ResponseEntity<B>

To'liq javobni (shu jumladan HTTP sarlavhalari va tanasi) aniqlaydigan qaytish qiymati HttpMessageConverter orqali o'zgartiriladi va javobga yoziladi.

HttpHeaders

Javobni sarlavhalar bilan, lekin tana holda qaytarish uchun mo'ljallangan.

String

Ko'rinish nomi, ViewResolver amalga oshirishlari orqali tan olinishi va @ModelAttribute annotatsiyasi bilan metodlar orqali aniqlangan ob'ektlar bilan foydalanilishi mumkin. Ishlovchi metod ham Model argumenti e'lon qilinib, modelni dasturiy ravishda maxsus ko'rsatishi mumkin.

View

Ko'rinishni render qilish uchun @ModelAttribute annotatsiyasi bilan metodlar orqali aniqlangan va ishlatilgan View instansiyasi bilan modelni render qilish uchun mo'ljallangan. Ishlovchi metod ham Model argumenti e'lon qilinib, modelni dasturiy ravishda maxsus ko'rsatishi mumkin.

java.util.Map, org.springframework.ui.Model

Ko'rinish nomi, RequestToViewNameTranslator orqali ne'lam aniqlangan, modeli bilan yangi atributlar.

@ModelAttribute

Ko'rinish nomi, RequestToViewNameTranslator orqali ne'lam aniqlangan, yangi atribut modeli.

Annotatsiya @ModelAttribute zarur emasligini unutmang. Ushbu jadval oxiridagi "Boshqa har qanday qaytish qiymati" ga qarang.

ModelAndView ob'ekti

Ko'rinishda ishlatiladigan atributlar va, agar kerak bo'lsa, javob statusi.

void

Argument ServletResponse yoki OutputStream yoki @ResponseStatus annotatsiyasiga ega bo'lgan metod, javobni to'liq qayta ishlagan hisoblanadi. Xuddi shu narsa, agar controller ETag yoki lastModified tekshirishni muvaffaqiyatli bajargan bo'lsa.

Yuqoridagi hech biri to'g'ri bo'lmasa, void turidagi qaytish HTML-контроллерлари uchun odatiy ko'rinish nomining tanlanishini bildirishi mumkin.

DeferredResult<V>

Istalgan yuqoridagi qaytish qiymatini, masalan, qandaydir hodisa yoki callback natijasida, istalgan ipdan asenkron ravishda ishlab chiqaradi.

Callable<V>

Spring MVC tomonidan boshqariladigan ipda yuqoridagi qaytish qiymatlarini asenkron ravishda ishlab chiqaradi.

ListenableFuture<V>, java.util.concurrent.CompletionStage<V>, java.util.concurrent.CompletableFuture<V>

DeferredResult uchun yanada qulayroq alternativa (masalan, asosiy xizmat ulardan birini qaytaradi).

ResponseBodyEmitter, SseEmitter

HttpMessageConverter amalga oshirishlari orqali javobga yozish uchun obyektlar oqimini asenkron ravishda yaratadi. Shuningdek, ResponseEntity uchun tanasi sifatida qo'llab-quvvatlanadi.

StreamingResponseBody

Javobning OutputStream ga asenkron ravishda yozilishi. Shuningdek, ResponseEntity uchun tanasi sifatida qo'llab-quvvatlanadi.

Reaktiv turlar - Reactor, RxJava yoki boshqa ReactiveAdapterRegistry orqali

Flux, Observable kabi ko'p qiymatli oqimlar bilan DeferredResultga alternativ. text/event-stream, application/json+stream kabi oqim senariylarida SseEmitter va ResponseBodyEmitter dan foydalaniladi, bu yerda Spring MVC tomonidan boshqariladigan ipda ServletOutputStream bloklash amalga oshiriladi, har bir yozuv tugagach, javob qo'ng'iroq qilishni amalga oshiradi.

Boshqa har qanday qaytish qiymati

Agar ushbu jadvaldagi avvalgi hech bir qiymatga to'g'ri kelmasa va String yoki void bo'lsa, u RequestToViewNameTranslator orqali odatiy ko'rinish nomining tanlanishi sifatida ko'rib chiqiladi, agar u java.lang.Class tomonidan aniqlangan oddiy tur ( BeanUtils#isSimpleProperty). Oddiy turlar bo'lgan qiymatlar yechilmagan holda qoladi.

Tur o'zgartirish

Controller metodining ba'zi annotatsiyalangan argumentlari, String asosida so'rov kirishini ifodalaydi (masalan, @RequestParam, @RequestHeader, @PathVariable, @MatrixVariable va @CookieValue) agar argument String bo'lmasa, tur o'zgartirish zarur bo'lishi mumkin.

Bunday hollarda tur o'zgartirish avtomatik ravishda sozlangan o'zgartirgichlar asosida qo'llaniladi. Oddiy turlar (int, long, Date va boshqalar) uchun qo'llab-quvvatlanadi. Tur o'zgartiruvchilarni WebDataBinder orqali yoki Formatters ni FormattingConversionService ga ro'yxatdan o'tkazish orqali sozlashingiz mumkin.

Tur o'zgartirishdagi amaliy masala bu bo'sh qator manba qiymatni qayta ishlash. Bunday qiymat, tur o'zgartirish natijasida null ga aylanadi. Bu Long, UUID va boshqa maqsadli turlarga xos bo'lishi mumkin. Agar siz null kiritishni ma'qullashni istasangiz, demak required flagini annotatsiya argumentida ishlatish yoki @Nullable argumentini e'lon qilish kerak.

5.3-versiyadan boshlab, null bo'lmagan argumentlar, ularni moslashtirishdan keyin ham ishlatiladi. Agar controller metodiga bo'sh qiymat kiritilishi kerak bo'lsa, unda @Nullable sifatida e'lon qiling yoki @RequestParam kabi mos annotatsiyaga required=false ni qo'ying. Bu 5.3-versiyaga yangilashda yuzaga keladigan regressiyalar uchun eng yaxshi usul va tavsiya etilgan yechimdir.

Bundan tashqari, agar @PathVariable annotatsiyasi majburiy bo'lsa, unda yuzaga keladigan MissingPathVariableException istisnosini maxsus tarzda qayta ishlash mumkin. Tur o'zgartirilgandan so'ng Null qiymati bo'sh manba qiymat sifatida ko'rib chiqiladi, shuning uchun Missing…Exception istisno variantlari yaratiladi.

Matritsa o'zgaruvchilari

RFC 3986 yo'l segmentlaridagi "nom-qiymat" juftliklarini tasvirlaydi. Spring MVC da biz ularni "matritsa o'zgaruvchilari" deb ataymiz, Tim Berners-Lining "eski postiga" asoslanib, lekin ularni URI identifikatorlari yo'l parametrlari deb ham atash mumkin.

Matritsa o'zgaruvchilari har qanday yo'l segmentida paydo bo'lishi mumkin, har bir o'zgaruvchi nuqta-vergul bilan, bir nechta qiymatlar esa vergul bilan ajratiladi (masalan, /cars;color=red,green;year=2012). Bir nechta qiymatlar ham o'zgaruvchi nomlarining takrorlanishi orqali belgilanishi mumkin (masalan, color=red;color=green;color=blue).

Agar URL manzili matritsa o'zgaruvchilarini o'z ichiga olishi kutilsa, controller metodi uchun qo'llash so'rovi muvaffaqiyatli so'rov moslashini ta'minlash uchun ushbu matritsa o'zgaruvchisining mazmunini maskalash uchun URI identifikatori o'zgaruvchisidan foydalanishi kerak. Quyidagi misolda matritsa o'zgaruvchisi ishlatilgan:

Java
// GET /pets/42;q=11;r=22
@GetMapping("/pets/{petId}")
public void findPet(@PathVariable String petId, @MatrixVariable int q) {
    // petId == 42
    // q == 11
}
Kotlin
// GET /pets/42;q=11;r=22
@GetMapping("/pets/{petId}")
fun findPet(@PathVariable petId: String, @MatrixVariable q: Int) {
    // petId == 42
    // q == 11
}

Yo'lning barcha segmentlari matritsa o'zgaruvchilariga ega bo'lishi mumkinligini hisobga olsak, ba'zida matritsa o'zgaruvchisining qaysi yo'l o'zgaruvchisida bo'lishi kerakligini aniqlash kerak bo'lishi mumkin. Quyidagi misolda bu qanday amalga oshirilishi ko'rsatilgan:

Java
// GET /owners/42;q=11/pets/21;q=22
@GetMapping("/owners/{ownerId}/pets/{petId}")
public void findPet(
        @MatrixVariable(name="q", pathVar="ownerId") int q1,
        @MatrixVariable(name="q", pathVar="petId") int q2) {
    // q1 == 11
    // q2 == 22
}
Kotlin
// GET /owners/42;q=11/pets/21;q=22
@GetMapping("/owners/{ownerId}/pets/{petId}")
fun findPet(
        @MatrixVariable(name = "q", pathVar = "ownerId") q1: Int,
        @MatrixVariable(name = "q", pathVar = "petId") q2: Int) {
    // q1 == 11
    // q2 == 22
}

Matritsa o'zgaruvchisi quyidagi misolda ko'rsatilganidek, ixtiyoriy qilib belgilanishi va default qiymatga ega bo'lishi mumkin:

Java
// GET /pets/42
@GetMapping("/pets/{petId}")
public void findPet(@MatrixVariable(required=false, defaultValue="1") int q) {
    // q == 1
}
Kotlin
// GET /pets/42
@GetMapping("/pets/{petId}")
fun findPet(@MatrixVariable(required = false, defaultValue = "1") q: Int) {
    // q == 1
}

Barcha matritsa o'zgaruvchilarini olish uchun MultiValueMap dan foydalanishingiz mumkin, quyidagi misolda ko'rsatilganidek:

Java
// GET /owners/42;q=11;r=12/pets/21;q=22;s=23
@GetMapping("/owners/{ownerId}/pets/{petId}")
public void findPet(
        @MatrixVariable MultiValueMap<String, String> matrixVars,
        @MatrixVariable(pathVar="petId") MultiValueMap<String, String> petMatrixVars) {
    // matrixVars: ["q" : [11,22], "r" : 12, "s" : 23]
    // petMatrixVars: ["q" : 22, "s" : 23]
}
Kotlin
// GET /owners/42;q=11;r=12/pets/21;q=22;s=23
@GetMapping("/owners/{ownerId}/pets/{petId}")
fun findPet(
        @MatrixVariable matrixVars: MultiValueMap<String, String>,
        @MatrixVariable(pathVar="petId") petMatrixVars: MultiValueMap<String, String>) {
    // matrixVars: ["q" : [11,22], "r" : 12, "s" : 23]
    // petMatrixVars: ["q" : 22, "s" : 23]
}

E'tibor bering, tilla belgilangan so'zlar yordamida matritsa o'zgaruvchilaridan foydalanishni faollashtirish kerak. Java'da MVC konfiguratsiyasida UrlPathHelper ni removeSemicolonContent=false ga o'rnatish kerak. XML'da MVC spacesida <mvc:annotation-driven enable-matrix-variables="true"/> o'rnatilishi mumkin.

@RequestParam

@RequestParam annotatsiyasi controller metodidagi argumentga servlet so'rov parametrlarini (ya'ni, so'rov parametrlarini yoki forma ma'lumotlarini) biriktirish uchun foydalanilishi mumkin.

Quyidagi misolda bu qanday amalga oshirilgani ko'rsatilgan:

Java
@Controller
@RequestMapping("/pets")
public class EditPetForm {
    // ...
    @GetMapping
    public String setupForm(@RequestParam("petId") int petId, Model model) { 
        Pet pet = this.clinic.loadPet(petId);
        model.addAttribute("pet", pet);
        return "petForm";
    }
    // ...
}
  1. @RequestParam annotatsiyasidan foydalanib petId ni biriktirish.
Kotlin
import org.springframework.ui.set
@Controller
@RequestMapping("/pets")
class EditPetForm {
    // ...
    @GetMapping
    fun setupForm(@RequestParam("petId") petId: Int, model: Model): String { 
        val pet = this.clinic.loadPet(petId);
        model["pet"] = pet
        return "petForm"
    }
    // ...
}
  1. @RequestParam annotatsiyasidan foydalanib petId ni biriktirish.

Ushbu annotatsiyadan foydalanadigan metod parametrlar odatda majburiy bo'lib, siz metod parametrining ixtiyoriy ekanligini, @RequestParam annotatsiyasining required bayrog'ini false ga o'rnatish yoki java.util.Optional wrapper funksiyasidan foydalanib e'lon qilishingiz mumkin.

Agar maqsadli metodning parametr turi String bo'lmasa, turli o'zgartirishlar avtomatik ravishda qo'llaniladi.

Argument turini massiv yoki ro'yxat sifatida e'lon qilish sizga bir xil parametr nomi uchun bir nechta qiymatlarni yechish imkonini beradi.

Agar @RequestParam annotatsiyasi Map<String, String> yoki MultiValueMap<String, String> sifatida e'lon qilinsa va annotationsiz nomi bo'lmasa, xarita har bir berilgan parametr nomi uchun so'rov parametrlarining qiymatlari bilan to'ldiriladi.

E'tibor bering, @RequestParam annotatsiyasidan foydalanish majburiy emas (masalan, atributlarni o'rnatish uchun). Oddiy qiymatli tur ( BeanUtils#isSimpleProperty tomonidan aniqlanganidek) bo'lgan va hech qanday boshqa argument ajratgichi tomonidan hal qilinmagan har qanday argument, xuddi @RequestParam bilan annotatsiyalanganidek hal qilinadi.

@RequestHeader

@RequestHeader annotatsiyasidan controller metodidagi argumentga so'rov sarlavhasini biriktirish uchun foydalanish mumkin.

Quyidagi sarlavhalar bilan so'rovni ko'rib chiqing:

Host                    localhost:8080
Accept                  text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Language         fr,en-gb;q=0.7,en;q=0.3
Accept-Encoding         gzip,deflate
Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive              300

Quyidagi misolda Accept-Encoding va Keep-Alive sarlavhalarining qiymatlarini olish ko'rsatilgan:

Java
@GetMapping("/demo")
public void handle(
        @RequestHeader("Accept-Encoding") String encoding, 
        @RequestHeader("Keep-Alive") long keepAlive) { 
    //...
}
  1. Accept-Encoding sarlavhasining qiymatlarini olish.
  2. Keep-Alive sarlavhasining qiymatlarini olish.
Kotlin
@GetMapping("/demo")
fun handle(
        @RequestHeader("Accept-Encoding") encoding: String, 
        @RequestHeader("Keep-Alive") keepAlive: Long) { 
    //...
}
  1. Accept-Encoding sarlavhasining qiymatlarini olish.
  2. Keep-Alive sarlavhasining qiymatlarini olish.

Agar maqsadli metodning parametr turi String bo'lmasa, turli o'zgartirishlar avtomatik ravishda qo'llaniladi.

Agar @RequestHeader annotatsiyasi Map<String, String>, MultiValueMap<String, String>, yoki HttpHeaders argumentida ishlatilsa, xarita barcha sarlavhalarning qiymatlari bilan to'ldiriladi.

Ajratilgan vergul bilan qatorni stringlar qatori yoki boshqa turlar ketma-ketligi yoki kolleksiyasiga aylantirish uchun ichki qo'llab-quvvatlash mavjud. Masalan, @RequestHeader("Accept") bilan annotatsiyalangan metod parametri String yoki String[] yoki List<String> bo'lishi mumkin.

@CookieValue

@CookieValue annotatsiyasidan controller metodidagi argumentga HTTP cookie qiymatlarini biriktirish uchun foydalanish mumkin.

Quyidagi cookie bilan so'rovni ko'rib chiqing:

JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84

Quyidagi misolda cookie qiymatini olish ko'rsatilgan:

Java
@GetMapping("/demo")
public void handle(@CookieValue("JSESSIONID") String cookie) { 
    //...
}
  1. JSESSIONID cookie qiymatini olish.
Kotlin
@GetMapping("/demo")
fun handle(@CookieValue("JSESSIONID") cookie: String) { 
    //...
}
  1. JSESSIONID cookie qiymatini olish.

Agar maqsadli metodning parametr turi String bo'lmasa, turli o'zgartirishlar avtomatik ravishda qo'llaniladi.

@ModelAttribute

@ModelAttribute annotatsiyasidan metod argumenti uchun modellardan atributga kirish yoki u mavjud bo'lmasa, uning nusxasini yaratish uchun foydalanish mumkin. Model atributiga parametr nomlari mos keladigan HTTP servlet so'rov parametrlari bilan qoplangan. Bu ma'lumotlarni biriktirish deb ataladi va alohida so'rov parametrlarini va forma maydonlarini tahlil qilish va o'zgartirish zaruriyatidan qutqaradi. Quyidagi misolda bu qanday amalga oshirilgani ko'rsatilgan:

Java
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) {
    // method logic...
}
Kotlin
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
fun processSubmit(@ModelAttribute pet: Pet): String {
    // method logic...
}

Yuqoridagi Pet misol quyidagi usullar orqali qayta ishlanadi:

  • U @ModelAttribute annotatsiyasiga ega bo'lgan metod orqali modeldan ajratiladi.

  • Agar class-leveldagi @SessionAttributes annotatsiyasida model attributi sifatida belgilangan bo'lsa, HTTP sessiyadan ajratiladi.

  • U qandaydir Converter orqali, masalan, URI identifikator o'zgaruvchisi yoki so'rov parametri (keyingi misolga qarang) orqali, so'roq qiymati nomi bilan mos keladigan model attributi nomi orqali olinadi.

  • Default konstruktor orqali yaratiladi.

  • Servlet so'rov parametrlari bilan mos keladigan argumentlarga ega "birinchi konstruktor" orqali yaratildi. Argument nomlari JavaBeans sinflarining @ConstructorProperties annotatsiyasi orqali yoki bayt-kodda runtime-da saqlanuvchi parametr nomlari orqali aniqlanadi.

@ModelAttribute annotatsiyalangan metod orqali uni ta'minlash yoki model attributi yaratishni ramkaga topshirish o'rniga, Converter<String, T> dan foydalanib misolni taqdim etish mumkin. Bu model attributi nomi URI identifikator o'zgaruvchisi yoki so'rov parametri kabi so'rov qiymati nomi bilan mos kelganda va String ni model attributi turiga o'zgartiruvchi Converter mavjud bo'lsa qo'llaniladi. Quyidagi misolda model attributi nomi account bo'lib, bu URI identifikator o'zgaruvchisi account bilan mos keladi, va String dan Accountgacha ro'yxatdan o'tgan Converter mavjud bo'lib, bu Account ma'lumotlar joyidan yuklashi mumkin:

Java
@PutMapping("/accounts/{account}")
public String save(@ModelAttribute("account") Account account) {
    // ...
}
Kotlin
@PutMapping("/accounts/{account}")
fun save(@ModelAttribute("account") account: Account): String {
    // ...
}

Atributning nusxasi ajratilganidan so'ng, ma'lumotlar biriktiriladi. WebDataBinder servlet so'rov parametrlari (so'rov parametrlari va forma maydonlari) nomlarini maqsadli ob'ekt maydon nomlari bilan moslashtiradi. Mos kelgan maydonlar, kerakli joyda turli o'zgartirishlarni amalga oshirganidan so'ng to'ldiriladi.

Ma'lumotlarni biriktirish xatolarga olib kelishi mumkin. Default holda BindException istisnosi yuzaga keladi. Biroq, bunday xatolarni tekshirish uchun controller metodida BindingResult argumentini, to'g'ridan-to'g'ri @ModelAttribute annotatsiyasi bilan usullarining yonida qo'shish mumkin, quyidagi misolda ko'rsatilganidek:

Java
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) { 
    if (result.hasErrors()) {
        return "petForm";
    }
    // ...
}
  1. @ModelAttribute annotatsiyasi bilan BindingResult qo'shib qo'yish.
Kotlin
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
fun processSubmit(@ModelAttribute("pet") pet: Pet, result: BindingResult): String { 
    if (result.hasErrors()) {
        return "petForm"
    }
    // ...
}
  1. @ModelAttribute annotatsiyasi bilan BindingResult qo'shib qo'yish.

Ba'zi hollarda, ma'lumotlarni biriktirishsiz model attributiga kirish zarur bo'lishi mumkin. Bunday hollarda controllerga Model ni injektsiya qilish va unga to'g'ridan-to'g'ri kirish yoki alternativ holda @ModelAttribute(binding=false) qo'yish mumkin, quyidagi misolda ko'rsatilganidek:

Java
@ModelAttribute
public AccountForm setUpForm() {
    return new AccountForm();
}
@ModelAttribute
public Account findAccount(@PathVariable String accountId) {
    return accountRepository.findOne(accountId);
}
@PostMapping("update")
public String update(@Valid AccountForm form, BindingResult result,
        @ModelAttribute(binding=false) Account account) { 
    // ...
}
  1. @ModelAttribute(binding=false) sozlash.
Kotlin
@ModelAttribute
fun setUpForm(): AccountForm {
    return AccountForm()
}
@ModelAttribute
fun findAccount(@PathVariable accountId: String): Account {
    return accountRepository.findOne(accountId)
}
@PostMapping("update")
fun update(@Valid form: AccountForm, result: BindingResult,
           @ModelAttribute(binding = false) account: Account): String { 
    // ...
}
  1. @ModelAttribute(binding=false) sozlash.

Siz ma'lumotlarni biriktirishdan so'ng avtomatik tarzda tekshirishni amalga oshirish uchun javax.validation.Valid yoki Spring dan @Validated annotatsiyasidan foydalanishingiz mumkin. Quyidagi misolda bu qanday amalga oshirilgani ko'rsatilgan:

Java
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) { 
    if (result.hasErrors()) {
        return "petForm";
    }
    // ...
}
  1. Pet ning validsiyalash.
Kotlin
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
fun processSubmit(@Valid @ModelAttribute("pet") pet: Pet, result: BindingResult): String { 
    if (result.hasErrors()) {
        return "petForm"
    }
    // ...
}

E'tibor bering, @ModelAttribute annotatsiyasidan foydalanish majburiy emas (masalan, atributlarni o'rnatish uchun). Oddiy qiymatli tur bo'lmagan va BeanUtils#isSimpleProperty tomonidan aniqlanganidek boshqa ajratgich tomonidan hal qilinmagan har qanday argument, xuddi @ModelAttribute bilan annotatsiyalanganidek hal qilinadi.

@SessionAttributes

@SessionAttributes annotatsiyasi, model attributlarini HTTP servlet sessiyasida so'rovlar orasida saqlash uchun ishlatiladi. Bu ma'lum bir controller tomonidan ishlatiladigan sessiya attributlarini e'lon qiladigan tur darajasidagi annotatsiya. Bu odatda sessiyada keyingi so'rovlar uchun shaffof ravishda saqlanishi kerak bo'lgan model attributlari nomlari yoki turdagi model attributlaridan iborat.

Quyidagi misolda @SessionAttributes annotatsiyasidan foydalanilgan:

Java
@Controller
@SessionAttributes("pet") 
public class EditPetForm {
    // ...
}
  1. @SessionAttributes annotatsiyasidan foydalanish.
Kotlin
@Controller
@SessionAttributes("pet") 
class EditPetForm {
    // ...
}
  1. @SessionAttributes annotatsiyasidan foydalanish.

Birinchi so'rovda, pet nomi bilan modelga qo'shilgan model atributi avtomatik ravishda oshkor etiladi va HTTP servlet sessiyasida saqlanadi. U bir nechta boshqa so'rovlarni qayta ishlovchi metod SessionStatus metod argumentini ishlatmaguncha saqlanadi, quyidagi misolda ko'rsatilganidek:

Java
@Controller
@SessionAttributes("pet") 
public class EditPetForm {
    // ...
    @PostMapping("/pets/{id}")
    public String handle(Pet pet, BindingResult errors, SessionStatus status) {
        if (errors.hasErrors) {
            // ...
        }
        status.setComplete(); 
        // ...
    }
}
  1. Servlet sessiyasida Pet qiymatini saqlash.
  2. Servlet sessiyasidan Pet qiymatini tozalash.
Kotlin
@Controller
@SessionAttributes("pet") 
class EditPetForm {
    // ...
    @PostMapping("/pets/{id}")
    fun handle(pet: Pet, errors: BindingResult, status: SessionStatus): String {
        if (errors.hasErrors()) {
            // ...
        }
        status.setComplete() 
        // ...
    }
}
  1. Servlet sessiyasida Pet qiymatini saqlash.
  2. Servlet sessiyasidan Pet qiymatini tozalash.

@SessionAttribute

Agar controller tashqarisida global darajada boshqariladigan (masalan, filter orqali) va mavjud yoki mavjud bo'lmagan sessiya attributlariga kirish zarur bo'lsa, metod parametri uchun @SessionAttribute annotatsiyasidan foydalanishingiz mumkin, quyidagi misolda ko'rsatilganidek:

Java
@RequestMapping("/")
public String handle(@SessionAttribute User user) { 
    // ...
}
  1. @SessionAttribute annotatsiyasidan foydalanish.
Kotlin
@RequestMapping("/")
fun handle(@SessionAttribute user: User): String { 
    // ...
}

Atributlarni sessiyaga qo'shish yoki olib tashlashni talab qiladigan foydalanish holatlari uchun controller metodiga org.springframework.web.context.request.WebRequest yoki javax.servlet.http.HttpSession injektsiya qilishni ko'rib chiqing.

Controller ish jarayonining bir qismi sifatida sessiyada vaqtinchalik model attributlarini saqlash uchun @SessionAttributes annotatsiyasidan foydalanishni ko'rib chiqing.

@RequestAttribute

@SessionAttribute annotatsiyasiga o'xshash, Filter yoki HandlerInterceptor servletlar tomonidan oldin yaratilgan so'rov attributlariga kirishni ta'minlash uchun @RequestAttribute annotatsiyasidan foydalanishingiz mumkin:

Java
@GetMapping("/")
public String handle(@RequestAttribute Client client) {

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION