Why does <h: form> renderer add a hidden field with form id as name and value

I read the implementation of the JSF implementation <h:form> . To my surprise, I see that (in Mojarra, MyFaces + Tomahawk) they add a hidden input field using the 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 to which the component id component.getClientId(context) is assigned, i.e. a UIForm ? What is the purpose of the hidden field?
  • In Mojarra, you have no way to assign your own id attribute to <h:form> , but you can to MyFaces. How does JSF handle UIForm in each case (for example, when MyFaces has an explicitly provided id )?
  • The default enctype enctype form is application/x-www-form-urlencoded . Can it support multipart/form-data or text/plain ?

thanks

+4
source share
1 answer

Why is there a hidden input field that is assigned the id component.getClientId (context), i.e. UIForm component? What is the purpose of the hidden field?

Look closer to the comment (line numbers from Mojarra 2.1.19 ):

 153 // this hidden field will be checked in the decode method to 154 // determine if this form has been submitted. 155 writer.startElement("input", component); 156 writer.writeAttribute("type", "hidden", "type"); 157 writer.writeAttribute("name", clientId, 158 "clientId"); 159 writer.writeAttribute("value", clientId, "value"); 160 writer.endElement("input"); 161 writer.write('\n'); 

This is thus used to determine the form in which it was submitted. This definition occurs, in turn, in FormRenderer#decode() , which is called when the JSF needs to determine the parameters of the HTTP request during the request phase of the request:

 96 // Was our form the one that was submitted? If so, we need to set 97 // the indicator accordingly.. 98 Map<String, String> requestParameterMap = context.getExternalContext() 99 .getRequestParameterMap(); 100 if (requestParameterMap.containsKey(clientId)) { 101 if (logger.isLoggable(Level.FINE)) { 102 logger.log(Level.FINE, 103 "UIForm with client ID {0}, submitted", 104 clientId); 105 } 106 ((UIForm) component).setSubmitted(true); 107 } else { 108 ((UIForm) component).setSubmitted(false); 109 } 

In other words, it controls the result of the UIForm#isSubmitted() property. This can be useful in the following cases of using multiple forms per page:


In Mojarra you have no way to assign your own id attribute to <h:form> , but you can to MyFaces. How does JSF handle UIForm in each case (for example, when MyFaces has its explicit id provided)?

I'm not sure what you're talking about. It,

 <h:form id="formId"> 

works great for me in mojarra.


The Mojarra form annotation form applies by default to the / x -www-form-urlencoded application. Can it support multipart / form-data or text / plain?

It complies with the JSF specification. And yes, you can just use the enctype attribute enctype usual way.

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

Whether the submission of such a form is duly recognized by the JSF is second. Prior to JSF 2.2, JSF did not have built-in support for multipart/form-data . JSF component libraries solve this by providing a servlet filter along with file upload components, usually using Apache Commons FileUpload under covers. JSF 2.2 simply passes directly to the new 3.0 servlet 3.0 HttpServletRequest#getPart() API without the need for a servlet filter using a third-party API. See Also, among others. How to upload files to a server using JSP / Servlet?

+8
source

Source: https://habr.com/ru/post/1490581/


All Articles