0

我正在尝试将 Spring MVC 与 Java Server Faces 混合使用。我有一个 Spring 3.2@Controller类,它返回一个ModelAndView解析为 JSF 视图的。该视图包含一个<h:form>标签。我遇到的问题是,在呈现的 HTML 上,表单action属性将原始请求 URL 与名称相结合以解析视图,从而创建了一个奇怪的无意义 URL,将表单发布到该 URL。我想要的只是视图名称,没有原始请求 URL。

这是我的控制器类(org.my.test.MainController):

@Controller
@RequestMapping("/items")
public class MainController
{
  @RequestMapping(value="/{itemId}", method=RequestMethod.GET)
  public ModelAndView retrieveItem( @PathVariable long itemId ) {

    /* Retrieve item */

    ModelAndView mav = new ModelAndView();
    mav.addObject ("itemName", "A retrieved item");
    mav.addObject ("itemId", itemId);
    mav.setViewName ("/items");
    return mav;
  }
}

这是我的 JSF 模板 ( /items.xhtml)

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Edit item</title>
</h:head>
<h:body>
    <h:form>
        <h3>Edit item</h3>
        <p>
            Item name: <h:inputText name="itemName" value="#{itemName}" />
        </p>
        <p>
            Item id: <h:inputText name="itemId" value="#{itemId}" />
        </p>
        <p>
            <h:commandButton value="Submit" />
        </p>
    </h:form>
</h:body>
</html>

当我请求页面http://localhost:8081/items/12345时,提供的是:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml"><head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Edit item</title></head><body><form id="j_id_6" name="j_id_6" method="post" action="/items/12345/items.xhtml" enctype="application/x-www-form-urlencoded">
        <h3>Edit item</h3>
        <p>
            Item name: <input id="j_id_6:j_id_8" name="j_id_6:j_id_8" type="text" value="A retrieved item" />
        </p>
        <p>
            Item id: <input id="j_id_6:j_id_a" name="j_id_6:j_id_a" type="text" value="12345" />
        </p>
        <p><input id="j_id_6:j_id_c" name="j_id_6:j_id_c" type="submit" value="Submit" />
        </p><input type="hidden" name="j_id_6_SUBMIT" value="1" /><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="oyc7wGGKZrPGinPPmrv9PmTDy0GBlI3c+pjWpdK0KuY69faJ" /></form></body>
</html>

我的问题是说action="/items/12345/items.xhtml"我想要的是action="/items"action="/items.xhtml"

我的问题有两个部分:为什么我的设置会像这样将请求 URL 与视图 ID 结合起来,以及如何让它停止?

这里是web.xml

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

    <display-name>Minimal JSF + Spring test</display-name>

    <!-- - Location of the XML file that defines the root application context. 
        - Applied by ContextLoaderListener. -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/spring/application-config.xml</param-value>
    </context-param>

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

    <listener>
        <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
    </listener>


    <!-- - Servlet that dispatches request to registered handlers (Controller 
        implementations). -->
    <servlet>
        <servlet-name>ui</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/ui-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>ui</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- Just here so the JSF implementation can initialize, *not* used at runtime -->
    <servlet>
        <servlet-name>faces</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Just here so the JSF implementation can initialize -->
    <servlet-mapping>
        <servlet-name>faces</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>

</web-app>

这是Spring配置ui-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:faces="http://www.springframework.org/schema/faces"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:component-scan base-package="org.my.test" />
    <mvc:annotation-driven />
    <bean id="faceletsViewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
        <property name="prefix" value="" />
        <property name="suffix" value=".xhtml" />
    </bean>

</beans>

这是主要的Spring配置application-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:faces="http://www.springframework.org/schema/faces"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:component-scan base-package="org.my.test" />
</beans>

这是faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config 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"
        version="2.0">

    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>

</faces-config>

这一切都在嵌入式 Jetty 9.0.4 中运行。我尝试了两种不同的 JSF 实现,Apache My-Faces 2.1.11 和 Mojarra 2.2.1,两者都具有相同的效果。春季版本是 3.2.3。

4

1 回答 1

0

url-mapping将输入从“/”更改web.xml为“/*”更正了问题。

事实上,一切都根据 Servlet 规范(Java Servlet 规范版本 3.0 Rev a,第 12.2 节,第 116 页):

  • 以字符开头/并以后缀结尾的字符串/*用于路径映射。

    ...

  • 仅包含字符的字符串/表示应用程序的“默认”servlet。在这种情况下,servlet 路径是请求 URI 减去上下文路径,并且路径信息为空。

(感谢 Coderanch 上的这篇文章:http: //www.coderanch.com/t/366340/Servlets/java/servlet-mapping-url-pattern

(Java Servlet 3.0 规范可在http://download.oracle.com/otndocs/jcp/servlet-3.0-mrel-eval-oth-JSpec/ 获得

于 2013-07-26T21:59:45.440 回答