I was reading the JSF implementation <h:form> rendering. To my surprise, I see that (in Mojarra, MyFaces + Tomahawk), they add a hidden input field on an encodeBegin() method.
Here is the sample code for FormRenderer in Mojarra:
@Override
public void encodeBegin(FacesContext context, UIComponent component)
      throws IOException {
    rendererParamsNotNull(context, component);
    if (!shouldEncode(component)) {
        return;
    }
    ResponseWriter writer = context.getResponseWriter();
    assert(writer != null);
    String clientId = component.getClientId(context);
    // since method and action are rendered here they are not added
    // to the pass through attributes in Util class.
    writer.write('\n');
    writer.startElement("form", component);
    writer.writeAttribute("id", clientId, "clientId");
    writer.writeAttribute("name", clientId, "name");
    writer.writeAttribute("method", "post", null);
    writer.writeAttribute("action", getActionStr(context), null);
    String styleClass =
          (String) component.getAttributes().get("styleClass");
    if (styleClass != null) {
        writer.writeAttribute("class", styleClass, "styleClass");
    }
    String acceptcharset = (String)
          component.getAttributes().get("acceptcharset");
    if (acceptcharset != null) {
        writer.writeAttribute("accept-charset", acceptcharset,
                              "acceptcharset");
    }
    RenderKitUtils.renderPassThruAttributes(context,
                                            writer,
                                            component,
                                            ATTRIBUTES);
    writer.writeText("\n", component, null);
    // this hidden field will be checked in the decode method to
    // determine if this form has been submitted.         
    writer.startElement("input", component);
    writer.writeAttribute("type", "hidden", "type");
    writer.writeAttribute("name", clientId,
                          "clientId");
    writer.writeAttribute("value", clientId, "value");
    writer.endElement("input");
    writer.write('\n');
    // Write out special hhidden field for partial submits
    String viewId = context.getViewRoot().getViewId();
    String actionURL =
        context.getApplication().getViewHandler().getActionURL(context, viewId);
    ExternalContext externalContext = context.getExternalContext();
    String encodedActionURL = externalContext.encodeActionURL(actionURL);
    String encodedPartialActionURL = externalContext.encodePartialActionURL(actionURL);
    if (encodedPartialActionURL != null) {
        if (!encodedPartialActionURL.equals(encodedActionURL)) {
            writer.startElement("input", component);
            writer.writeAttribute("type", "hidden", "type");
            writer.writeAttribute("name", "javax.faces.encodedURL", null);
            writer.writeAttribute("value", encodedPartialActionURL, "value");
            writer.endElement("input");
            writer.write('\n');
        }
    }
    if (!writeStateAtEnd) {
        context.getApplication().getViewHandler().writeState(context);
        writer.write('\n');
    }
}
My Questions:
- Why is there a hidden input field that gets assigned the id component.getClientId(context), i.e., aUIFormcomponent? What's the purpose of the hidden field?
- In Mojarra, you don't have the option to assign your own idattribute on<h:form>but you can on MyFaces. How does JSF treatUIFormin each cases (e.g. when MyFaces has its an explicit providedid)?
- Mojarra form enctypeis defaulted toapplication/x-www-form-urlencoded. Can it supportmultipart/form-dataortext/plain?
Thanks
 
     
    