1

我在使用 fileUpload 和 JSF2 的模板机制时遇到了问题。我进行了广泛的搜索,并且还有其他类似问题的问题(例如herehere,但我的问题似乎与我对模板机制的使用直接相关,因为它在该机制之外可以正常工作。

<ui:insert>我有一个 xhtml 表单,我使用模板和<ui:composition/在表单中插入模板<ui:define>。用于文件上传的 bean 上的侦听器永远不会被调用。但是,如果我修改表单以便能够成为独立页面,则上传工作正常。因此,显然,与模板过程有关的东西正在改变我的结果。

我知道使用模板机制和下面的代码片段会产生两个嵌套的表单,但我尝试删除一个并且没有任何变化。生成的 HTML 在浏览器中看起来很合理,那么会发生什么?

我的 xhtml 表单...

<?xml version="1.0" encoding="UTF-8"?>
<!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:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:myfaces="http://myfaces.apache.org/tomahawk"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets">

    <ui:composition template="MJLSConsole.xhtml">

        <ui:param name="title" value="Sender Info" />

        <ui:define name="content"> 
            <h:form id="senderInfo">
                <h:panelGrid columns="2" >
                    <p:outputLabel for="imageId" id="icon" value="Organisation Icon"/>
                    <p:fileUpload id="imageId" value="#{senderInformationBean.file}" required="true" mode="simple"/>
                </h:panelGrid>
                <p:commandButton value="Save" action="#{senderInformationBean.save}" ajax="false" />

            </h:form>
        </ui:define>
    </ui:composition>
</html>

这是我的模板

<?xml version='1.0' encoding='UTF-8' ?>
<!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:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </h:head>

    <h:body>
        <h:form id="testpage" enctype="multipart/form-data">
            <p:growl id="messages" sticky="true" autoUpdate="true" />
            <ui:insert name="content">Content</ui:insert>
        </h:form>
    </h:body>
</html>

和我的 web.xml

<?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    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">
    <display-name>Mjls_main</display-name>
    <context-param>
        <description>Specifies the root of the spring application context</description>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/cxf-beans.xml</param-value>
    </context-param>

    <listener>
        <description>Starts spring application context</description>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <listener>
        <description>Bridges http requests to ContextLoaderListener</description>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
        <description>JSF server</description>
        <servlet-name>facesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>facesServlet</servlet-name>
    </filter-mapping>


    <servlet>
        <servlet-name>MJActionService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>MJEnvelopeService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>MJActionEventService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>SenderInformationBlockService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>MJTemplateService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>MJmlService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>Notification_Portal_SignallingService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>MJInboundMessageService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>MjogServiceImplService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>facesServlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>facesServlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <servlet>
        <description>Provides soap services via Apache CXF</description>
        <display-name>cxf</display-name>
        <servlet-name>cxf</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxf</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
    <filter>
        <description>Provides an ACL and role-based checks for associated services</description>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>restrictAccessFilter</filter-name>
        <filter-class>com.mjog.mjls.filter.RestrictAccessFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>restrictAccessFilter</filter-name>
        <url-pattern>/console/*</url-pattern>
    </filter-mapping>
    <welcome-file-list>
        <welcome-file>mjlsLogin.jsf</welcome-file>
    </welcome-file-list>
    <filter>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
        <init-param>
            <param-name>uploadMaxFileSize</param-name>
            <param-value>20m</param-value>
        </init-param>
    </filter>
    <!-- extension mapping for adding <script/>, <link/>, and other resource tags to JSF-pages  -->
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <!-- servlet-name must match the name of your javax.faces.webapp.FacesServlet entry -->
        <servlet-name>facesServlet</servlet-name>
    </filter-mapping>
    <!-- extension mapping for serving page-independent resources (javascript, stylesheets, images, etc.)  -->
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
    </filter-mapping>
    <servlet-mapping>
        <servlet-name>MJActionService</servlet-name>
        <url-pattern>/MJActionService</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MJEnvelopeService</servlet-name>
        <url-pattern>/MJEnvelopeService</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MJActionEventService</servlet-name>
        <url-pattern>/MJActionEventService</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>SenderInformationBlockService</servlet-name>
        <url-pattern>/SenderInformationBlockService</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MJTemplateService</servlet-name>
        <url-pattern>/MJTemplateService</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MJmlService</servlet-name>
        <url-pattern>/MJmlService</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Notification_Portal_SignallingService</servlet-name>
        <url-pattern>/Notification_Portal_SignallingService</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MJInboundMessageService</servlet-name>
        <url-pattern>/MJInboundMessageService</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MjogServiceImplService</servlet-name>
        <url-pattern>/MjogServiceImplService</url-pattern>
    </servlet-mapping>
    <session-config>
        <!-- logs inactive web users out after n minutes-->
        <session-timeout>20</session-timeout>
    </session-config>

    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>mjog</param-value>
    </context-param>

    <servlet>
        <servlet-name>imageServlet</servlet-name>
        <servlet-class>com.mjog.mjls.filter.ImageServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>imageServlet</servlet-name>
        <url-pattern>/file/*</url-pattern>
    </servlet-mapping>
</web-app>

最后我的豆子是

    @ManagedBean(name = "senderInformationBean")
    public class SenderInformationBean implements Serializable {

    transient private ConsoleService consoleService;
    private UploadedFile file;

    public void setConsoleService(ConsoleService consoleService) {
        this.consoleService = consoleService;
    }

    public UploadedFile getFile() {
        return file;
    }

    public void setFile(UploadedFile file) {
        this.file = file;
    }

    public String save() throws IOException {
        consoleService.save(accountName, contactAddress, contactNumber, emailId, accountUrl, file.getBytes());
        populateSenderInfo();
        return "/console/senderInformation.xhtml?faces-redirect=true";
    }
}
4

1 回答 1

1

插入模板定义后,您的组件树实际上会像这样结束:

<h:body>
    <h:form id="testpage" enctype="multipart/form-data">
        <p:growl id="messages" sticky="true" autoUpdate="true" />
        <h:form id="senderInfo">
            <h:panelGrid columns="2" >
                <p:outputLabel for="imageId" id="icon" value="Organisation Icon"/>
                <p:fileUpload id="imageId" value="#{senderInformationBean.file}" required="true" mode="simple"/>
            </h:panelGrid>
            <p:commandButton value="Save" action="#{senderInformationBean.save}" ajax="false" />
        </h:form>
    </h:form>
</h:body>

看,你最终得到了一个嵌套的表单。这在 HTML 中是非法的。提交这种嵌套表单的实际行为是未指定的,并且取决于所使用的浏览器。摆脱<h:form id="testpage">并设置enctypeon<h:form id="senderInfo">这样你的组件树有效地结束了:

<h:body>
    <p:growl id="messages" sticky="true" autoUpdate="true" />
    <h:form id="senderInfo" enctype="multipart/form-data">
        <h:panelGrid columns="2" >
            <p:outputLabel for="imageId" id="icon" value="Organisation Icon"/>
            <p:fileUpload id="imageId" value="#{senderInformationBean.file}" required="true" mode="simple"/>
        </h:panelGrid>
        <p:commandButton value="Save" action="#{senderInformationBean.save}" ajax="false" />
    </h:form>
</h:body>

也可以看看:

于 2013-03-16T15:11:10.870 回答