Alexander Shalin
Alexander Shalin

Reputation: 7

ui:composition hides h:form parameter enctype

I have a problem with ui:composition and h:form parameter enctype="multipart/form-data".

When h:form is nested in ui:compostion, h:inputFile throws:

javax.servlet.ServletException: The request content-type is not a multipart/form-data

When I place h:inputFile on JSF page without ui:composition it works fine.

<?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:h="http://xmlns.jcp.org/jsf/html"
  xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
    <title>Power Consumption</title>
</h:head>
<h:body>
    <ui:composition template="./resources/templates/dashboardTemplate.xhtml">
        <ui:define name="content">
            <h:form id="pcForm" enctype="multipart/form-data">
                <h2>
                    Power Consumption
                </h2>
                <br/>
                <h:outputLabel value="Upload CSV"/>
                <h:inputFile id="file" value="#{powerConsumption.file}"/>
                <h:commandButton value="Upload" action="#{powerConsumption.upload()}"/>
                <br/>
                <h:inputTextarea value="#{powerConsumption.fileContent}" rows="30" cols="80"/>
            </h:form>
        </ui:define>
    </ui:composition>
</h:body>

dashboardTemplate.xhtml

<h:body>

    <div id="top">
        <ui:insert name="top">Welcome to Information Resource Manager 2</ui:insert>
    </div>

    <div id="content" class="center_content">
        <ui:insert name="content">Content</ui:insert>
    </div>

    <div id="bottom">
        <ui:insert name="bottom">Powered by Java</ui:insert>
    </div>

</h:body>

Upvotes: 0

Views: 995

Answers (1)

BalusC
BalusC

Reputation: 1108722

When h:form is nested in ui:compostion, h:inputFile throws:

javax.servlet.ServletException: The request content-type is not a multipart/form-data

This code snippet is not in MVCE flavor, so the cause of the problem is not visible in the information posted so far, but the symptoms at least strongly suggest that the master template has another <h:form> around the <ui:insert>. This in turn means that your JSF component tree is ultimately composed as below after Facelets templating has done its job (i.e. when you think away all those <ui:xxx> templating tags which are actually irrelevant in this regard):

<h:form>
    <h:form enctype="multipart/form-data">
        <h:inputFile />
    </h:form>
</h:form>

A nested form thus. Nesting forms is illegal in HTML. The browser behavior is unspecified. In your particular case, the browser apparently used the outer form to process the POST request. This is not a JSF/Facelets problem. You're yourself responsible that you write JSF code in such way that it produces legal HTML output (which can be seen via rightclick, View source in browser). E.g.

<h:form enctype="multipart/form-data">
    <h:inputFile />
</h:form>
<h:form>
    [another content here which requires a form]
</h:form>

Upvotes: 1

Related Questions