Spring และ IceFaces: ข้อผิดพลาดที่ไม่คาดคิด 404 ใน `http://‹hostname›/‹projectname›/WEB-INF/views/‹filename›.xhtml`

ฉันกำลังพัฒนาซอฟต์แวร์โดยใช้ Spring และ ICEFaces
ฉันมีไฟล์ที่ <project directory>/src/main/webapp/WEB-INF/views/<filename>.xhtml ซึ่งเข้าถึงได้อย่างถูกต้องโดยใช้ URL ต่อไปนี้: http://<hostname>/<projectname>/<filename>.xhtml

ไฟล์นี้มี <h:form id="formId"> ซึ่งแสดงผลเป็น <form action="/<projectname>/WEB-INF/views/<filename>.xhtml" [.. some other stuff ..]>

หมายความว่าเมื่อฉันคลิกที่ input send ที่มีอยู่ในแบบฟอร์ม เบราว์เซอร์จะพยายามเปิด URL http://<hostname>/<projectname>/WEB-INF/views/<filename>.xhtml และอย่างที่ฉันบอกไปแล้วในชื่อเรื่อง มันแสดงหน้าข้อผิดพลาด 404

ฉันต้องการให้สามารถเข้าถึงไฟล์ .xhtml ได้โดยใช้ URL "ยาวกว่า" เช่นกัน ฉันค่อนข้างแน่ใจว่าขณะนี้ฉันไม่สามารถบรรลุเป้าหมายได้เนื่องจากข้อผิดพลาดในการกำหนดค่า

นี่คือ web.xml ของฉัน:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5">

<web-app>
    <display-name>SIGLO</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

นี่คือ applicationContext.xml ที่อ้างอิงในไฟล์ก่อนหน้า:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                        http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                        http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" >

    <context:component-scan base-package="com.infoone.siglo" />
    <!--
         map all requests to /resources/** to the container default servlet 
        (ie, don't let Spring handle them)
    -->
    <bean id="defaultServletHttpRequestHandler" class="org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler" />
    <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >
        <property name="urlMap" >
            <map>
                <entry key="/resources/**" value-ref="defaultServletHttpRequestHandler" />
            </map>
        </property>
    </bean>
    <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
    <mvc:annotation-driven />

    <!-- JSF for representation layer. All JSF files under /WEB-INF/views directory -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver" >
        <property name="cache" value="false" />
        <property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean name="icefacesResourceHandler" class="org.springframework.faces.webflow.JsfResourceRequestHandler" />

    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
      <property name="order" value="0" />
      <property name="mappings">
        <value>
          /javax.faces.resource/**=icefacesResourceHandler
        </value>
      </property>
    </bean>
    </beans>

และท้ายที่สุด นี่คือ faces-config.xml ของฉัน:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                        http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
        <locale-config></locale-config>
        <resource-bundle>
            <base-name>MessageResources</base-name>
            <var>msg</var>
        </resource-bundle>
    </application>
</faces-config>

ฉันขอชี้ให้เห็นว่าการกำหนดค่านี้ยังไม่อนุญาตให้ฉันเปิด URL ที่สั้นกว่า ได้สำเร็จ อันที่จริง ฉันต้องสร้างคอนโทรลเลอร์ที่เหมาะสมหรือดีกว่า @RequestMapping ที่เหมาะสมภายใน @Controller:

@RequestMapping(value = "<filename>", method = RequestMethod.GET)
public String creaBlocco()
{
    return "<filename>";
}

@RequestMapping(value = "<filename>", method = RequestMethod.POST)
public String creaBlocco([.. parameters ..]) {
    [.. stuff ..]
    return "<filename>";
}

ใช่ ค่าของ @RequestMapping คือ "<filename>" โดยไม่มีส่วนขยาย .xhtml ฉันได้ทำให้แน่ใจว่าโดยการลองผิดลองถูกแล้วว่าการแมปดังกล่าวจำเป็นสำหรับ GET ที่จะประสบความสำเร็จ ในทางกลับกัน ฉันตระหนักดีว่าการกำหนดค่าดังกล่าวเปราะบางมาก ฉันควรเปลี่ยนแปลงอะไรในไฟล์กำหนดค่าของฉัน เพื่อให้ <filename>.xhtml สามารถเข้าถึงได้โดยใช้ URL ยาวขึ้น ด้วย

ขอขอบคุณล่วงหน้าสำหรับความสนใจของคุณ


person iccuta    schedule 13.08.2012    source แหล่งที่มา
comment
ขอบคุณสำหรับคำตอบ. แอปพลิเคชันของฉันถูกปรับใช้บน VMware vFabric tc Server Developer Edition v2.6 เมื่อใช้ Servlet 3.0 จะไม่โหลด descriptor เมื่อใช้ Servlet 2.5 แอปพลิเคชันจะถูกโหลดบนเซิร์ฟเวอร์ แต่ยังคงทำงานในลักษณะที่ฉันอธิบายไว้ในโพสต์ดั้งเดิมของฉัน อย่างไรก็ตาม ฉันจะอัปเดตโพสต์ของฉันด้วย web.xml ใหม่   -  person iccuta    schedule 13.08.2012
comment
ไม่มีปัญหา. มันเป็นเพียงความคิดเห็นไม่ใช่คำตอบ ฉันได้ลบมันไปแล้ว ตอนนี้คุณได้แก้ไขคำถามของคุณเพื่อยกเว้นสาเหตุที่เป็นไปได้แล้ว   -  person BalusC    schedule 13.08.2012
comment
ลองเปลี่ยน ‹property name=suffix value=.jsp /› เป็น ‹property name=suffix value=.xhtml /›   -  person Ravi Kadaboina    schedule 14.08.2012


คำตอบ (1)


หลังจากการค้นคว้าข้อมูล ฉันได้ข้อสรุปว่าฉันไม่ได้ใช้เทคโนโลยีเหล่านั้นในแบบที่ควรจะใช้ หากคุณกำลังประสบปัญหาเดียวกันของฉัน ในบริบทเดียวกัน คุณอาจกำลังทำข้อผิดพลาดแบบเดียวกัน ดังนั้นคุณต้องแก้ไขสถาปัตยกรรมแอปพลิเคชันของคุณเล็กน้อยเพื่อแก้ไข จริงๆ แล้ว ดูเหมือนว่า การใช้ JSF/ICEFaces และ Spring MVC ร่วมกับ Spring WebFlow เป็นแนวทางที่สะดวกสบายและตรงไปตรงมาที่สุด

ฉันจะพยายามอธิบายเหตุผล
หน้าแรกของเว็บไซต์/ผู้ใช้ของคุณเต็มไปด้วยลิงก์ไปยังกรณีการใช้งาน (หรือที่ดีกว่าคือโฟลว์) ที่สามารถเปิดใช้งานได้ด้วยสิทธิพิเศษของเขา/เธอ ลิงก์เหล่านั้นดูเหมือน http://<page-url>?<flow-id> โฟลว์ใน Spring WebFlow ถูกกำหนดให้เป็นกราฟสถานะภายในไฟล์ xml การเปลี่ยนระหว่างสถานะจะมีป้ายกำกับด้วยสตริง ชื่อ การกระทำ หรือเงื่อนไข บางสถานะคือ view-state ซึ่งหมายความว่ามีบางอย่างที่จะแสดงให้ผู้ใช้เห็นเมื่อถึงสถานะดังกล่าว ดังนั้น สำหรับแต่ละ view-state ชื่อ <state-id> จะต้องมีไฟล์ .xhtml ชื่อ <state-id>.xhtml

ปุ่มที่ JSF และ ICEFaces มอบให้จะแสดงผลเป็น <input type="submit" [..]> เสมอ และการทำงานของแบบฟอร์มที่มีจะชี้ไปที่ URL เดียวกันกับหน้าที่มีเนื้อหาเสมอ (เช่น http://<page-url>?<flow-id>) นั่นคือข้อเท็จจริง
ข้อแตกต่างคือในกรณีนี้ URL ดังกล่าวไม่ได้รับการสำรองโดยไฟล์จริง (เช่นในคำถามของฉัน) แต่หากแอปได้รับการกำหนดค่าอย่างเหมาะสม flow-handler จะตอบและจัดการสถานะทั้งหมดและช่วงการเปลี่ยนภาพที่กำหนดไว้ในไฟล์ xml โดยเลือกมุมมองที่เหมาะสมที่จะแสดง

นอกจากนั้น ปุ่มที่ JSF และ ICEFaces มอบให้ยังมีแอตทริบิวต์ action ดังที่คุณคงจินตนาการได้ สิ่งเหล่านี้สอดคล้องกับการกระทำที่กำหนดไว้ในไฟล์คำจำกัดความของโฟลว์ ดังนั้น การคลิกปุ่มที่มีค่าหนึ่งของแอตทริบิวต์ action จะทำให้เกิดการเปลี่ยนแปลงจากสถานะปัจจุบันที่มีป้ายกำกับว่า สตริงนั้น
พูดให้ชัดเจนยิ่งขึ้น หากคุณคลิกที่ปุ่ม เบราว์เซอร์จะส่งคำขอ POST ไปที่ http://<page-url>?<flow-id> ซึ่งเนื้อหามีพารามิเตอร์ที่จำเป็นทั้งหมด ตัวจัดการโฟลว์ได้รับคำขอ POST และคำนวณสถานะถัดไป ซึ่งอาจเลือกได้ว่าจะแสดงมุมมองใดแก่ผู้ใช้

หากคุณยังคงอ่านคำตอบนี้อยู่ ฉันคิดว่าคุณต้องมีตัวอย่างที่ชัดเจนในการอ้างอิง ฉันจะให้อันที่ฉันเคยเรียนรู้ทุกสิ่งที่ฉันเขียนที่นี่: http://wiki.icesoft.org/display/ICE/Spring+Web+Flow+2.3.1 เป็นจุดเริ่มต้นที่ยอดเยี่ยม เพราะมันง่ายแต่ครบถ้วนสมบูรณ์

person iccuta    schedule 17.08.2012