제이온

[สปริง] Filter, Interceptor, Argument Resolver คืออะไร?

สร้าง: 2024-04-27

สร้าง: 2024-04-27 00:41

อะไรคือตัวกรอง (Filter)?

ตัวกรองเป็นฟังก์ชันมาตรฐาน J2EE ที่ให้ความสามารถในการประมวลผลงานเพิ่มเติมสำหรับทุกคำขอที่ตรงกับรูปแบบ url ก่อน/หลังการส่งคำขอไปยัง Dispatcher Servlet หมายความว่าถูกจัดการโดยเว็บคอนเทนเนอร์ เช่น Tomcat ไม่ใช่สปริงคอนเทนเนอร์ ดังนั้นจึงประมวลผลคำขอ ก่อนที่จะไปถึง Dispatcher Servlet


[สปริง] Filter, Interceptor, Argument Resolver คืออะไร?


การใช้งานตัวกรอง (Filter)

เพื่อเพิ่มตัวกรอง คุณต้องใช้อินเทอร์เฟซ Filter ของ javax.servlet ซึ่งมีเมธอด 3 เมธอด ดังต่อไปนี้


  • เมธอด init
    • เป็นเมธอดสำหรับการเริ่มต้นวัตถุตัวกรองและเพิ่มลงในบริการ เว็บคอนเทนเนอร์จะเรียกเมธอด init หนึ่งครั้งเพื่อเริ่มต้นวัตถุตัวกรอง จากนั้นคำขอต่อๆ ไปจะถูกประมวลผลผ่านเมธอด doFilter()
  • เมธอด doFilter
    • เป็นเมธอดที่ถูกเรียกใช้โดยเว็บคอนเทนเนอร์ก่อนที่ทุกคำขอ HTTP ที่ตรงกับรูปแบบ url จะถูกส่งไปยัง Dispatcher Servlet และถูกเรียกใช้โดยเว็บคอนเทนเนอร์ก่อนที่ Dispatcher Servlet จะส่งการตอบสนอง HTTP ไปยังไคลเอ็นต์
      พารามิเตอร์ของ doFilter() มี FilterChain ซึ่ง chain.doFilter() จะส่งคำขอไปยังเป้าหมายถัดไป เราสามารถแทรกกระบวนการประมวลผลที่เราต้องการก่อน/หลัง chain.doFilter() เพื่อดำเนินการประมวลผลที่ต้องการ
  • เมธอด destory
    • เป็นเมธอดสำหรับการลบวัตถุตัวกรองออกจากบริการและส่งคืนทรัพยากรที่ถูกใช้ เป็นเมธอดที่ถูกเรียกใช้โดยเว็บคอนเทนเนอร์เพียงครั้งเดียว หลังจากนั้นจะไม่ได้รับการประมวลผลโดย doFilter() อีกต่อไป


ตัวอย่างรหัส - ข้อมูลจำเพาะของ Servlet

```javascript @WebFilter("/*") public class dolphagoFilter implements Filter {

FilterChain filterChain) throws IOException, ServletException { //การประมวลผลเบื้องต้นที่นี่ request.setCharacterEncoding("UTF-8"); System.out.println("doFilter() ก่อน...");

}


ตัวอย่างรหัส - @Component

```javascript @Order(1) @Component public class CustomFilter implements Filter {

}


  • @Component: สามารถลงทะเบียน Filter เป็น Bean ของ Spring ได้
  • @Order: สามารถระบุลำดับได้ หากมีตัวกรองหลายตัว
  • หากลงทะเบียนตัวกรองที่ตรงกับข้อมูลจำเพาะของ Servlet เป็น Bean ของ Spring จะสามารถใช้ Bean อื่นๆ ที่ตรงกับข้อมูลจำเพาะของ Spring ได้


ตัวอย่างรหัส - @Configuration

```javascript @Configuration public class CustomRegistrationBean {

}

หากคุณต้องการให้ตัวกรองทำงานเฉพาะกับ URI เฉพาะ คุณสามารถลงทะเบียนตัวกรองเป็น Bean ของ Spring โดยใช้ FilterRegistrationBean


การใช้งานตัวกรอง (Filter)

มักจะรับผิดชอบในการตรวจสอบและประมวลผลพารามิเตอร์ของคำขอเอง


  • งานทั่วไปที่เกี่ยวข้องกับความปลอดภัย
    • เนื่องจากตัวกรองทำงานในเว็บคอนเทนเนอร์ ดังนั้นจึงสามารถตรวจสอบความปลอดภัย (XSS, การป้องกัน CSRF ฯลฯ) และบล็อกคำขอที่ไม่ถูกต้องได้ สิ่งนี้สามารถเพิ่มความปลอดภัยได้มากขึ้น เนื่องจากคำขอจะไม่ถูกส่งไปยังสปริงคอนเทนเนอร์
  • การบันทึกสำหรับทุกคำขอ
  • การบีบอัดรูปภาพ/ข้อมูล และการเข้ารหัสสตริง
    • ตัวกรองได้ใช้ฟังก์ชันทั่วไปในแอปพลิเคชันเว็บ เช่น การบีบอัดรูปภาพหรือข้อมูล และการเข้ารหัสสตริง
  • การปรับแต่ง ServletRequest
    • HttpServletRequest สามารถอ่านเนื้อหาของ Body ได้เพียงครั้งเดียว ดังนั้น Filter หรือ Interceptor ไม่สามารถอ่าน Body ได้ เราสามารถสร้าง ServletRequest ที่กำหนดเองเพื่อบันทึก Body


ตัวตัดรับ (Interceptor)

อะไรคือตัวตัดรับ (Interceptor)?

ตัวตัดรับ (Interceptor) ไม่เหมือนกับตัวกรอง (Filter) ซึ่งเป็นข้อมูลจำเพาะมาตรฐาน J2EE เป็นเทคโนโลยีที่สปริงให้บริการ และสามารถอ้างอิงหรือประมวลผลคำขอและการตอบสนองก่อน/หลัง Dispatcher Servlet เรียกคอนโทรลเลอร์ หมายความว่าตัวตัดรับทำงานในสปริงคอนเท็กซ์ ต่างจากตัวกรองที่ทำงานในเว็บคอนเทนเนอร์


Dispatcher Servlet จะขอให้แมปตัวจัดการเพื่อค้นหาคอนโทรลเลอร์ที่เหมาะสม ซึ่งจะส่งคืนสายโซ่การดำเนินการ (HandlerExecutionChain) ดังนั้น หากสายโซ่การดำเนินการนี้มีตัวตัดรับที่ลงทะเบียนไว้มากกว่า 1 รายการ จะดำเนินการตัวตัดรับตามลำดับก่อนที่จะเรียกใช้คอนโทรลเลอร์ และหากไม่มีตัวตัดรับ จะเรียกใช้คอนโทรลเลอร์โดยตรง


การใช้งานตัวตัดรับ (Interceptor)

เพื่อเพิ่มตัวตัดรับ คุณต้องใช้อินเทอร์เฟซ HandlerInterceptor ของ org.springframework.web.servlet ซึ่งมีเมธอด 3 เมธอด ดังต่อไปนี้


  • เมธอด preHandle
    • เมธอด preHandle จะถูกเรียกใช้ก่อนที่จะเรียกใช้คอนโทรลเลอร์ ดังนั้นจึงสามารถใช้สำหรับงานประมวลผลเบื้องต้น ก่อนคอนโทรลเลอร์ หรือเพื่อประมวลผลหรือเพิ่มข้อมูลคำขอ
    • พารามิเตอร์ handler ในเมธอด preHandle คือวัตถุที่เป็นนามธรรมของข้อมูลของเมธอดที่มี @RequestMapping
    • ประเภทผลลัพธ์ของเมธอด preHandle คือ boolean หากผลลัพธ์เป็น true จะดำเนินการต่อในขั้นตอนถัดไป แต่หากเป็น false งานจะถูกหยุด และงานที่ตามมา (ตัวตัดรับถัดไปหรือคอนโทรลเลอร์) จะไม่ถูกดำเนินการ
  • เมธอด postHandle
    • เมธอด postHandle จะถูกเรียกใช้หลังจากที่คอนโทรลเลอร์ถูกเรียกใช้ ดังนั้นจึงสามารถใช้สำหรับงานประมวลผลหลังการประมวลผล หลังคอนโทรลเลอร์
  • เมธอด afterCompletion
    • เมธอด afterCompletion จะถูกเรียกใช้หลังจากที่งานทั้งหมดเสร็จสิ้น รวมถึงการสร้างผลลัพธ์สุดท้ายจากทุกมุมมอง


ตัวอย่างรหัส

```javascript @Component public class CustomInterceptor implements HandlerInterceptor {

}

@Configuration public class WebMvcConfiguration implements WebMvcConfigurer {

}


  • ลงทะเบียนตัวตัดรับที่สร้างขึ้นเป็น Bean
  • ลงทะเบียนตัวตัดรับที่สร้างขึ้นในเมธอด addInterceptors() ของอินเทอร์เฟซ WebMvcConfigurer
  • ตัวตัดรับจะทำงานตามลำดับที่ลงทะเบียนไว้ใน InterceptorRegistry


การใช้งานตัวตัดรับ (Interceptor)

มักจะรับผิดชอบในการประมวลผลความถูกต้องของข้อมูลคำขอโดยใช้ตรรกะบริการ


  • งานทั่วไป เช่น การรับรองความถูกต้อง/การอนุญาต
    • ตัวอย่างเช่น การรับรองความถูกต้องหรือการอนุญาต ซึ่งเป็นงานที่เกี่ยวข้องกับคำขอของไคลเอ็นต์ สามารถตรวจสอบได้ก่อนที่จะส่งไปยังคอนโทรลเลอร์
  • การบันทึกสำหรับการเรียกใช้ API
    • สามารถบันทึกข้อมูลของไคลเอ็นต์ผ่านวัตถุ HttpServletRequest และ HttpServletResponse ที่ได้รับ
  • การประมวลผลข้อมูลที่จะส่งไปยัง Controller
    • สามารถประมวลผลวัตถุ HttpServletRequest และ HttpServletResponse ที่ได้รับ และส่งไปยังคอนโทรลเลอร์
  • เลียนแบบ AOP
    • สามารถระบุข้อมูลเพิ่มเติม เช่น ลายเซ็นของเมธอดที่จะเรียกใช้ผ่าน HandlerMethod ซึ่งเป็นพารามิเตอร์ที่ 3 ของเมธอด preHandle() เพื่อตัดสินใจว่าจะดำเนินการตรรกะหรือไม่


ตัวกรอง (Filter) vs ตัวตัดรับ (Interceptor)

  • ตัวกรองจะทำงานในเว็บคอนเท็กซ์ และตัวตัดรับจะทำงานในสปริงคอนเท็กซ์ ดังนั้นจุดเวลาในการดำเนินการจึงแตกต่างกัน
  • ตัวกรองสามารถจัดการก่อน/หลัง Dispatcher Servlet และตัวตัดรับสามารถจัดการก่อน/หลังคอนโทรลเลอร์ได้
  • ตัวกรองเหมาะสำหรับใช้ในกรณีที่ต้องประมวลผลงานทั่วไปที่ไม่เกี่ยวข้องกับสปริง ตรวจสอบพารามิเตอร์อินพุตเอง หรือใช้ ServletRequest แทน HttpServletRequest
  • ตัวตัดรับเหมาะสำหรับใช้ในกรณีที่ต้องประมวลผลงานทั่วไปที่เกี่ยวข้องกับคำขอของไคลเอ็นต์ที่เข้าสู่สปริง หรือเมื่อต้องการผสมตรรกะบริการ
  • ตัวตัดรับสามารถใช้ @ControllerAdvice และ @ExceptionHandler เพื่อจัดการข้อยกเว้น แต่ตัวกรองไม่สามารถใช้เพื่อจัดการข้อยกเว้นได้
    • ตัวกรองมักจะจัดการข้อยกเว้นที่เกิดขึ้นในขั้นตอนนั้นโดยตรงโดยการห่อ doFilter() รอบๆ ด้วยบล็อก try~catch


ตัวแก้ไขอาร์กิวเมนต์ (Argument Resolver)

ตัวแก้ไขอาร์กิวเมนต์ (Argument Resolver) คืออะไร?

ตัวแก้ไขอาร์กิวเมนต์ (Argument Resolver) สามารถสร้างวัตถุที่ต้องการจากค่าที่ส่งมาพร้อมกับคำขอไปยังคอนโทรลเลอร์ได้อย่างอ้อม


การใช้งานตัวแก้ไขอาร์กิวเมนต์ (Argument Resolver)

สมมติว่าคำขอมาพร้อมกับโทเค็น JWT ตัวอย่างเช่น เราจำเป็นต้องตรวจสอบว่าโทเค็นนี้เป็นโทเค็นที่ถูกต้องหรือไม่ และดึง id ที่เก็บอยู่ในโทเค็นออก แล้วสร้างเป็นวัตถุผู้ใช้ที่เข้าสู่ระบบ

ในกรณีนี้ หากไม่ใช้ตัวแก้ไขอาร์กิวเมนต์ คุณจะต้องใช้วิธีการตรวจสอบโทเค็นและแปลงเป็นวัตถุผู้ใช้ที่เข้าสู่ระบบในทุกคอนโทรลเลอร์ ซึ่งจะทำให้เกิดรหัสซ้ำซ้อนในคอนโทรลเลอร์ที่จำเป็นต้องตรวจสอบผู้ใช้ และเพิ่มความรับผิดชอบของคอนโทรลเลอร์ ตัวแก้ไขอาร์กิวเมนต์ สามารถแก้ไขปัญหานี้ได้


การใช้งานตัวแก้ไขอาร์กิวเมนต์ (Argument Resolver)

ตัวแก้ไขอาร์กิวเมนต์สามารถใช้งานได้โดยการใช้อินเทอร์เฟซ HandlerMethodArgumentResolver และอินเทอร์เฟซนี้จะระบุให้ใช้เมธอดสองเมธอดดังต่อไปนี้


```javascript boolean supportsParameter(MethodParameter parameter);

@Nullable Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;


  • เมธอด supportsParameter
    • สร้างและแนบคำอธิบายประกอบเฉพาะกับพารามิเตอร์ของเมธอดที่ต้องการให้ตัวแก้ไขอาร์กิวเมนต์ทำงาน เมธอด supportsParameter() จะตรวจสอบว่าเมธอดที่ร้องขอมีคำอธิบายประกอบที่ต้องการหรือไม่ และส่งคืน true หากมีคำอธิบายประกอบที่ต้องการ
  • เมธอด resolveArgument
    • หากได้รับ true จาก supportsParameter หมายความว่ามีเมธอดที่มีคำอธิบายประกอบเฉพาะ เป็นเมธอดที่ผูกข้อมูลกับพารามิเตอร์ให้เป็นรูปแบบที่ต้องการและส่งคืน


นี่คือวิธีการใช้งานตัวแก้ไขอาร์กิวเมนต์ในคอนโทรลเลอร์


```javascript @GetMapping("/me") public ResponseEntity findMemberOfMine(@AuthenticationPrincipal LoginMember loginMember) { MemberResponse memberResponse = memberService.findMember(loginMember.getId()); return ResponseEntity.ok().body(memberResponse); }


ความแตกต่างระหว่างตัวแก้ไขอาร์กิวเมนต์ (Argument Resolver) และตัวตัดรับ (Interceptor)

  • ตัวแก้ไขอาร์กิวเมนต์จะทำงานหลังจากตัวตัดรับ และจะส่งคืนวัตถุที่ต้องการจากค่าที่ส่งมาพร้อมกับคำขอไปยังคอนโทรลเลอร์
  • ในทางกลับกัน ตัวตัดรับจะสกัดกั้นคำขอ ก่อนที่จะเรียกใช้คอนโทรลเลอร์จริง และไม่สามารถส่งคืนวัตถุใดๆ จะมีเฉพาะประเภทผลลัพธ์ boolean หรือ void เท่านั้น


แหล่งที่มา


คำถามที่คาดหวังในการสัมภาษณ์และคำตอบ

ตัวกรองคืออะไร?

ตัวกรองเป็นฟังก์ชันที่ให้ความสามารถในการประมวลผลงานเพิ่มเติมสำหรับทุกคำขอที่ตรงกับรูปแบบ url ก่อน/หลังการส่งคำขอไปยัง Dispatcher Servlet และทำงานในระดับ Servlet Container


เวลาใดที่ควรใช้ตัวกรอง?

ตัวกรองสามารถใช้สำหรับประมวลผลงานทั่วไปที่ไม่เกี่ยวข้องกับสปริงได้ หรือใช้เมื่อต้องการตรวจสอบพารามิเตอร์คำขอ

ตัวอย่างเช่น งานทั่วไปที่เกี่ยวข้องกับความปลอดภัย การบันทึกสำหรับทุกคำขอ การบีบอัดรูปภาพ/ข้อมูล และการเข้ารหัสสตริง และการปรับแต่ง ServletRequest


ตัวตัดรับคืออะไร?

ตัวตัดรับสามารถอ้างอิงหรือประมวลผลคำขอและการตอบสนองก่อน/หลัง Dispatcher Servlet เรียกคอนโทรลเลอร์ และทำงานในระดับ Spring Container


เวลาใดที่ควรใช้ตัวตัดรับ?

ตัวตัดรับสามารถใช้สำหรับประมวลผลงานทั่วไปที่เกี่ยวข้องกับคำขอของไคลเอ็นต์ หรือเมื่อต้องการตรวจสอบและใช้ตรรกะบริการ

ตัวอย่างเช่น งานทั่วไป เช่น การรับรองความถูกต้อง/การอนุญาต การบันทึกสำหรับการเรียกใช้ API และการประมวลผลข้อมูลที่จะส่งไปยัง Controller


ความแตกต่างระหว่างตัวกรองและตัวตัดรับคืออะไร?

ตัวกรองจะทำงานในระดับ Servlet Container และตัวตัดรับจะทำงานในระดับ Spring Container

ตัวกรองสามารถจัดการก่อน/หลัง Dispatcher Servlet และตัวตัดรับสามารถจัดการก่อน/หลังคอนโทรลเลอร์ได้

ดังนั้น ตัวกรองจึงเหมาะสำหรับใช้ในกรณีที่ต้องประมวลผลงานทั่วไปที่ไม่เกี่ยวข้องกับสปริง และตัวตัดรับจึงเหมาะสำหรับใช้ในกรณีที่ต้องประมวลผลงานทั่วไปที่เกี่ยวข้องกับคำขอของไคลเอ็นต์


ตัวแก้ไขอาร์กิวเมนต์คืออะไร?

ตัวแก้ไขอาร์กิวเมนต์สามารถสร้างวัตถุที่ต้องการจากค่าที่ส่งมาพร้อมกับคำขอไปยังคอนโทรลเลอร์ได้อย่างอ้อม


เวลาใดที่ควรใช้ตัวแก้ไขอาร์กิวเมนต์?

ตัวอย่างเช่น เมื่อคำขอมาพร้อมกับโทเค็น JWT เราจำเป็นต้องตรวจสอบว่าโทเค็นนี้เป็นโทเค็นที่ถูกต้องหรือไม่ และดึง id ที่เก็บอยู่ในโทเค็นออก แล้วสร้างเป็นวัตถุ LoginMember


ความแตกต่างระหว่างตัวตัดรับและตัวแก้ไขอาร์กิวเมนต์คืออะไร?

ตัวแก้ไขอาร์กิวเมนต์จะส่งคืนวัตถุที่ต้องการจากค่าที่ส่งมาพร้อมกับคำขอไปยังคอนโทรลเลอร์ ในขณะที่ตัวตัดรับไม่สามารถส่งคืนวัตถุใดๆ และตัวแก้ไขอาร์กิวเมนต์จะทำงานหลังจากตัวตัดรับ

ความคิดเห็น0

[สำหรับผู้ไม่ใช่ผู้เชี่ยวชาญ ด้านการพัฒนาซอฟต์แวร์ เพื่อความอยู่รอด] 14. สรุปเนื้อหาสัมภาษณ์ทางเทคนิคที่ผู้พัฒนาซอฟต์แวร์มือใหม่ถามบ่อยสรุปคำถามทางเทคนิคที่มักถามในการสัมภาษณ์งานผู้พัฒนาซอฟต์แวร์มือใหม่ (พื้นที่หน่วยความจำ โครงสร้างข้อมูล ฐานข้อมูล ฯลฯ) หวังว่าจะเป็นประโยชน์ในการเตรียมตัวสัมภาษณ์งานด้านการพัฒนา
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

April 3, 2024

เกี่ยวกับการโหลดทรัพยากรของเบราว์เซอร์บทความนี้จะอธิบายวิธีการใช้แอตทริบิวต์ต่างๆ เช่น JavaScript (async, defer), CSS (preload, media), รูปภาพ (loading="lazy", srcset, sizes) และอื่นๆ (prefetch, preconnect, dns-prefetch) เพื่อเพิ่มประสิทธิภาพความเร็วในการโหลดเว็บเพจ
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

October 1, 2024

การตั้งค่าหลักในการใช้ nginx เป็นเว็บเซิร์ฟเวอร์บทความนี้จะอธิบายวิธีการปรับแต่งประสิทธิภาพเว็บไซต์โดยใช้การตั้งค่าหลักของเว็บเซิร์ฟเวอร์ nginx เช่น การบีบอัด gzip, proxy_buffer, การตั้งค่า worker/http และ location block ควรทำการทดสอบประสิทธิภาพก่อนนำไปใช้งานจริง
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

September 26, 2024

สร้างเฟรมเวิร์กระดับ DI ด้วย Node.js แม้จะเป็นมือใหม่บทความนี้จะอธิบายวิธีการใช้การอัดฉีดการพึ่งพา (DI) ในการพัฒนาเซิร์ฟเวอร์ Node.js โดยใช้ฟังก์ชัน Reflect Metadata ของคอมไพเลอร์ TypeScript ในการใช้ DI และแนะนำไลบรารีที่เกี่ยวข้อง
Sunrabbit
Sunrabbit
Sunrabbit
Sunrabbit

November 8, 2024

วิธีแคชการตอบสนอง API + การแคชหน้าเว็บบทความนี้แนะนำวิธีการแคชหน้าเว็บและการตอบสนอง API การแคชหลายวิธีโดยใช้พื้นที่จัดเก็บของเบราว์เซอร์, Axios interceptor, เฟรมเวิร์ก Nuxt, Nginx และอื่นๆ พร้อมคำอธิบายข้อดีข้อเสียของการแคชฝั่งเซิร์ฟเวอร์
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들
뚠뚠멍의 생각들

September 29, 2024

การสืบค้นข้อมูลบนเว็บ (Crawling) คืออะไร?เรียนรู้เกี่ยวกับการสืบค้นข้อมูลบนเว็บ ซึ่งเป็นกระบวนการที่เว็บครอลเลอร์ค้นหาและรวบรวมข้อมูลจากหน้าเว็บอินเทอร์เน็ต การสืบค้นข้อมูลบนเว็บถูกนำไปใช้ในหลากหลายสาขา เช่น เครื่องมือค้นหา การเปรียบเทียบราคา และการวิเคราะห์โซเชียลมีเดีย
여행가고싶은블로거지만여행에대해다루진않을수있어요
여행가고싶은블로거지만여행에대해다루진않을수있어요
여행가고싶은블로거지만여행에대해다루진않을수있어요
여행가고싶은블로거지만여행에대해다루진않을수있어요

April 26, 2024