แอปพลิเคชัน Spring MVC มาตรฐานของคุณจะตอบสนองคำขอทั้งหมดผ่านทางDispatcherServlet
ที่คุณได้ลงทะเบียนไว้กับคอนเทนเนอร์ Servlet ของคุณ
DispatcherServlet
รูปลักษณ์ที่ดีApplicationContext
และหากมีการApplicationContext
ลงทะเบียนกับContextLoaderListener
ถั่วพิเศษจะต้องมีการติดตั้งขอตรรกะการแสดง ถั่วเหล่านี้จะอธิบายไว้ในเอกสาร
ที่สำคัญที่สุดถั่วประเภทHandlerMapping
แผนที่
คำขอที่เข้ามาถึงตัวจัดการและรายชื่อของตัวจัดการก่อนและหลังโปรเซสเซอร์ (ตัวดักจับตัวจัดการ) ตามเกณฑ์บางประการซึ่งรายละเอียดจะแตกต่างกันไปตามHandlerMapping
การนำไปใช้ การใช้งานที่ได้รับความนิยมสูงสุดสนับสนุนตัวควบคุมที่มีคำอธิบายประกอบ แต่มีการใช้งานอื่น ๆ
Javadoc ของHandlerMapping
ต่อไปอธิบายวิธีการใช้งานจะต้องประพฤติ
DispatcherServlet
พบถั่วประเภทนี้ทั้งหมดและลงทะเบียนไว้ในลำดับที่บางคน (สามารถกำหนดเองได้) ในขณะที่การให้บริการการร้องขอที่DispatcherServlet
ลูปเหล่านี้ผ่านHandlerMapping
วัตถุและการทดสอบแต่ละของพวกเขาด้วยที่จะหาคนที่สามารถจัดการกับการร้องขอเข้ามาแสดงเป็นมาตรฐานgetHandler
HttpServletRequest
ตั้งแต่ 4.3.x หากไม่พบสิ่งใดระบบจะบันทึกคำเตือนที่คุณเห็น
ไม่พบการแมปสำหรับคำขอ HTTP ที่มี URI [/some/path]
ในDispatcherServlet
ชื่อ SomeName
และทั้งพ่นNoHandlerFoundException
หรือทันทีกระทำการตอบสนองด้วยรหัสสถานะ 404 ไม่พบ
เหตุใดจึงไม่DispatcherServlet
พบสิ่งHandlerMapping
ที่สามารถจัดการกับคำขอของฉันได้
การHandlerMapping
ใช้งานที่พบบ่อยที่สุดคือการRequestMappingHandlerMapping
จัดการการลงทะเบียน@Controller
bean เป็นตัวจัดการ (จริงๆแล้วเป็น@RequestMapping
วิธีการที่มีคำอธิบายประกอบ) คุณสามารถประกาศถั่วชนิดนี้ด้วยตัวเอง (มี@Bean
หรือ<bean>
หรือกลไกอื่น ๆ ) หรือคุณสามารถใช้ตัวเลือก เหล่านี้คือ:
- คำอธิบายของคุณเรียนกับ
@Configuration
@EnableWebMvc
- ประกาศ
<mvc:annotation-driven />
สมาชิกในการกำหนดค่า XML ของคุณ
ตามที่ลิงค์ด้านบนอธิบายไว้ทั้งสองอย่างนี้จะลงทะเบียนRequestMappingHandlerMapping
bean (และของอื่น ๆ อีกมากมาย) อย่างไรก็ตาม a HandlerMapping
ไม่มีประโยชน์มากหากไม่มีตัวจัดการ RequestMappingHandlerMapping
คาดหวัง@Controller
ถั่วบางอย่างดังนั้นคุณต้องประกาศสิ่งเหล่านี้ด้วย@Bean
วิธีการในการกำหนดค่า Java หรือ<bean>
การประกาศในการกำหนดค่า XML หรือผ่านการสแกนส่วนประกอบของ@Controller
คลาสที่มีคำอธิบายประกอบในอย่างใดอย่างหนึ่ง ตรวจสอบให้แน่ใจว่ามีถั่วเหล่านี้อยู่
หากคุณได้รับข้อความเตือนและ 404 และคุณได้กำหนดค่าทั้งหมดข้างต้นอย่างถูกต้องแสดงว่าคุณกำลังส่งคำขอของคุณไปยัง URI ที่ไม่ถูกต้องซึ่งไม่ได้รับการจัดการโดย@RequestMapping
วิธีการจัดการคำอธิบายประกอบที่ตรวจพบ
spring-webmvc
ข้อเสนออื่น ๆ ในห้องสมุดในตัวHandlerMapping
การใช้งาน ตัวอย่างเช่นBeanNameUrlHandlerMapping
แผนที่
จาก URL ไปจนถึงถั่วที่มีชื่อที่ขึ้นต้นด้วยเครื่องหมายทับ ("/")
และคุณสามารถเขียนของคุณเองได้ตลอดเวลา เห็นได้ชัดว่าคุณจะต้องตรวจสอบให้แน่ใจว่าคำขอที่คุณส่งนั้นตรงกับตัวจัดการHandlerMapping
วัตถุที่ลงทะเบียนอย่างน้อยหนึ่งรายการ
ถ้าคุณทำไม่ได้โดยปริยายหรืออย่างชัดเจนลงทะเบียนใด ๆHandlerMapping
ถั่ว (หรือถ้าdetectAllHandlerMappings
เป็นtrue
) ที่DispatcherServlet
ลงทะเบียนบางส่วนเป็นค่าเริ่มต้น สิ่งเหล่านี้ถูกกำหนดไว้ในDispatcherServlet.properties
แพ็คเกจเดียวกับDispatcherServlet
คลาส พวกเขาเป็นBeanNameUrlHandlerMapping
และDefaultAnnotationHandlerMapping
(ซึ่งคล้ายกับRequestMappingHandlerMapping
แต่เลิกใช้แล้ว)
การแก้จุดบกพร่อง
ฤดูใบไม้ผลิ MVC RequestMappingHandlerMapping
จะเข้าสู่ระบบรถขนลงทะเบียนผ่าน ตัวอย่างเช่นก@Controller
เช่น
@Controller
public class ExampleController {
@RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
จะบันทึกสิ่งต่อไปนี้ที่ระดับ INFO
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
สิ่งนี้อธิบายถึงการทำแผนที่ที่ลงทะเบียน เมื่อคุณเห็นคำเตือนว่าไม่พบตัวจัดการให้เปรียบเทียบ URI ในข้อความกับการแมปที่แสดงที่นี่ ข้อ จำกัด ทั้งหมดที่ระบุไว้ใน@RequestMapping
ต้องตรงกับ Spring MVC เพื่อเลือกตัวจัดการ
อื่น ๆ HandlerMapping
การใช้งานบันทึกคำสั่งของตนเองที่ควรบอกใบ้ถึงการแมปและตัวจัดการที่เกี่ยวข้อง
ในทำนองเดียวกันให้เปิดใช้งาน Spring logging ที่ระดับ DEBUG เพื่อดูว่าถั่วใดที่ Spring ลงทะเบียน ควรรายงานคลาสที่มีคำอธิบายประกอบที่พบซึ่งแพ็กเกจที่สแกนและถั่วใดที่เริ่มต้น หากสิ่งที่คุณต้องการไม่ปรากฏให้ตรวจสอบApplicationContext
การกำหนดค่าของคุณ
ข้อผิดพลาดทั่วไปอื่น ๆ
A DispatcherServlet
เป็นเพียง Java EE Servlet
ทั่วไป คุณลงทะเบียนด้วยคำสั่งทั่วไป<web.xml>
<servlet-class>
และ<servlet-mapping>
คำประกาศของคุณหรือโดยตรงผ่านServletContext#addServlet
ใน a WebApplicationInitializer
หรือด้วยกลไกใดก็ตามที่ Spring boot ใช้ ดังนั้นคุณต้องอาศัยตรรกะการแมป URL ที่ระบุในข้อกำหนดของ Servletโปรดดูบทที่ 12
ด้วยเหตุนี้ข้อผิดพลาดทั่วไปคือการลงทะเบียนDispatcherServlet
ด้วยการแมป url ของการ/*
ส่งคืนชื่อมุมมองจาก@RequestMapping
เมธอดตัวจัดการและคาดว่าจะมีการแสดงผล JSP ตัวอย่างเช่นพิจารณาวิธีการจัดการเช่น
@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
ด้วย InternalResourceViewResolver
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
คุณอาจคาดหวังการร้องขอที่จะส่งต่อไปให้กับทรัพยากรที่ JSP /WEB-INF/jsps/example-view-name.jsp
เส้นทาง สิ่งนี้จะไม่เกิดขึ้น แต่สมมติว่าชื่อบริบทของExample
การDisaptcherServlet
จะรายงาน
ไม่พบการแมปสำหรับคำขอ HTTP ที่มี URI [/Example/WEB-INF/jsps/example-view-name.jsp]
ในDispatcherServlet
ชื่อ "dispatcher"
เนื่องจากDispatcherServlet
มีการแมปกับ/*
และ/*
ตรงกับทุกอย่าง (ยกเว้นการจับคู่แบบตรงทั้งหมดซึ่งมีลำดับความสำคัญสูงกว่า) จึงDispatcherServlet
จะถูกเลือกให้จัดการforward
จากJstlView
(ส่งคืนโดยInternalResourceViewResolver
) ในเกือบทุกกรณีDispatcherServlet
จะไม่มีการกำหนดค่าให้จัดการคำขอดังกล่าวจะไม่ได้รับการกำหนดค่าการจัดการการร้องขอดังกล่าว
แต่ในกรณีง่ายๆนี้คุณควรลงทะเบียนDispatcherServlet
to /
โดยทำเครื่องหมายว่าเป็น servlet เริ่มต้น servlet เริ่มต้นคือการจับคู่สุดท้ายสำหรับคำขอ สิ่งนี้จะช่วยให้คอนเทนเนอร์ servlet ทั่วไปของคุณสามารถเลือกการใช้งาน Servlet ภายในที่แมป*.jsp
เพื่อจัดการทรัพยากร JSP (ตัวอย่างเช่น Tomcat มีJspServlet
) ก่อนที่จะลองใช้ servlet เริ่มต้น
นั่นคือสิ่งที่คุณเห็นในตัวอย่างของคุณ