我正在阅读JSF实现<h:form>
渲染。令我惊讶的是,我看到了(在Mojarra,MyFaces + Tomahawk中),他们在encodeBegin()
方法上添加了一个隐藏的输入字段。
以下是Mojarra中FormRenderer
的示例代码:
@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');
}
}
我的问题:
component.getClientId(context)
,即UIForm
组件?隐藏领域的目的是什么?id
上分配自己的<h:form>
属性,但可以在MyFaces上进行分配。在每种情况下,JSF如何处理UIForm
(例如,当MyFaces明确提供id
时)?enctype
默认为application/x-www-form-urlencoded
。它可以支持multipart/form-data
还是text/plain
?由于
答案 0 :(得分:8)
为什么有一个隐藏的输入字段被赋予id component.getClientId(context),即一个UIForm组件?隐藏领域的目的是什么?
仔细查看评论(行号来自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');
因此用于确定提交了哪个表单。这个确定依次发生在FormRenderer#decode()
,当JSF需要在应用请求值阶段确定HTTP请求参数时调用{<1}}:
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 }
换句话说,它控制UIForm#isSubmitted()
属性的结果。它可能在以下涉及页面中多个表单的用例中很有用:
在Mojarra中,您无法在
<h:form>
上分配自己的ID属性,但您可以在MyFaces上进行分配。在每种情况下,JSF如何处理UIForm
(例如,当MyFaces有明确提供的ID时)?
我不确定你在谈论什么。此,
<h:form id="formId">
在Mojarra也适合我。
Mojarra form enctype默认为application / x-www-form-urlencoded。它可以支持multipart / form-data或text / plain吗?
这符合JSF规范。是的,您可以按常规方式使用enctype
属性。
<h:form enctype="multipart/form-data">
这种表格的提交是否得到JSF的正确认可,是第二次。在JSF 2.2之前,JSF没有内置对multipart/form-data
的支持。 JSF组件库通过提供servlet过滤器及其文件上载组件来解决这个问题,通常使用Apache Commons FileUpload。 JSF 2.2只需直接委托新的Servlet 3.0 HttpServletRequest#getPart()
API,而无需使用第三方API的servlet过滤器。另见其他How to upload files to server using JSP/Servlet?