0

我正在开发基于 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 ..]>

这意味着,当我单击表单中包含的输入提交时,浏览器会尝试打开 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。事实上,我必须创建一个合适的控制器,或者更好的是,在@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的值是"<filename>",没有.xhtml扩展名。通过反复试验,我已经确定这种映射对于 GET 成功是必要的。另一方面,我意识到这样的配置真的很脆弱。我应该在我的配置文件中进行哪些更改,以便使用更长的URL<filename>.xhtml也可以访问?

提前感谢您的关注。

4

1 回答 1

1

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

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

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

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

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

于 2012-08-17T12:27:15.090 回答