【问题标题】:Spring and IceFaces: unexpected error 404 on `http://<hostname>/<projectname>/WEB-INF/views/<filename>.xhtml`Spring 和 IceFaces:`http://<hostname>/<projectname>/WEB-INF/views/<filename>.xhtml` 上出现意外错误 404
【发布时间】:2012-08-13 16:15:23
【问题描述】:

我正在开发基于 Spring 和 ICEFaces 的软件。
我在&lt;project directory&gt;/src/main/webapp/WEB-INF/views/&lt;filename&gt;.xhtml 有一个文件,可以使用以下 URL 正确访问:http://&lt;hostname&gt;/&lt;projectname&gt;/&lt;filename&gt;.xhtml

该文件包含一个&lt;h:form id="formId"&gt;,它被呈现为&lt;form action="/&lt;projectname&gt;/WEB-INF/views/&lt;filename&gt;.xhtml" [.. some other stuff ..]&gt;

这意味着,当我单击表单中包含的 input submit 时,浏览器会尝试打开 URL http://&lt;hostname&gt;/&lt;projectname&gt;/WEB-INF/views/&lt;filename&gt;.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>

让我指出,这个配置仍然不允许我成功打开 shorter URL。事实上,我必须在 @Controller 中创建一个合适的控制器,或者更好的是,一个合适的 @RequestMapping

@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 的值是"&lt;filename&gt;",没有.xhtml 扩展名。通过反复试验,我已经确定这种映射对于 GET 成功是必要的。另一方面,我意识到这样的配置真的很脆弱。为了使&lt;filename&gt;.xhtml 也可以使用 longer URL 访问,我应该在我的配置文件中进行哪些更改?

提前感谢您的关注。

【问题讨论】:

  • 感谢您的回答。我的应用程序部署在“VMware vFabric tc Server Developer Edition v2.6”上。使用 Servlet 3.0 时,它也不会加载描述符。使用 Servlet 2.5 时,应用程序被加载到服务器上,但仍然按照我在原始帖子中描述的方式运行。不管怎样,我会用新的 web.xml 更新我的帖子
  • 没问题。这只是一个评论,而不是一个答案。我已经删除了它现在你已经解决了你的问题以排除可能的原因。
  • 尝试将 更改为

标签: spring-mvc jsf-2 icefaces-3


【解决方案1】:

经过一些研究,我得出的结论是,我并没有按照它们应有的方式使用这些技术。如果您在相同的上下文中遇到同样的问题,您可能会犯同样的错误,因此您必须稍微修改您的应用程序架构来解决它。实际上,使用 JSF/ICEFaces 和 Spring MVC 结合 Spring WebFlow 似乎是最舒适和直接的方法。

我会尽力解释原因。
您的站点/用户主页上充满了指向可以通过他/她的权限激活的用例(或者,更好的是流程)的链接。这些链接看起来像http://&lt;page-url&gt;?&lt;flow-id&gt;。 Spring WebFlow 中的流被定义为 xml 文件中的状态图。状态之间的转换由字符串、名为 actions 或条件标记。一些状态是 view-state s,这意味着当达到这种状态时有一些东西要显示给用户。因此,对于每个名为&lt;state-id&gt;view-state,应该有一个名为&lt;state-id&gt;.xhtml 的.xhtml 文件。

JSF 和ICEFaces 提供的按钮将始终呈现为&lt;input type="submit" [..]&gt;,并且包含表单的操作将始终指向与包含页面相同的URL(即http://&lt;page-url&gt;?&lt;flow-id&gt;)。这是事实。
不同之处在于,在这种情况下,这样的 URL 不是由真实文件支持的(就像我的问题一样),但是,如果应用程序配置正确,flow-handler 将回答并管理所有xml 文件中定义的状态和转换,选择要显示的正确视图。

除此之外,JSF 和ICEFaces 提供的按钮还有一个action 属性。可以想象,它们对应于流定义文件中定义的动作:因此,单击具有特定 action 属性值的按钮将触发从当前状态的转换那个字符串。
更具体地说,如果您单击按钮,浏览器会向 http://&lt;page-url&gt;?&lt;flow-id&gt; 发送一个 POST 请求,其正文包含所有必要的参数。流处理程序接收该 POST 请求并计算下一个状态,可能选择必须向用户显示哪个视图。

如果您仍在阅读此答案,我想您需要一个具体的示例来参考。我将为您提供我曾经在这里学习过的所有内容:http://wiki.icesoft.org/display/ICE/Spring+Web+Flow+2.3.1 这是一个很棒的起点,因为它简单但详尽。

【讨论】:

    猜你喜欢
    • 2016-07-28
    • 2017-11-20
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 2019-01-13
    • 2016-06-22
    • 2017-02-24
    相关资源
    最近更新 更多