From aedf85725413c0e58c893b3ae187092898f11910 Mon Sep 17 00:00:00 2001
From: Bauke Scholtz
Date: Sat, 20 Jan 2024 12:40:44 -0400
Subject: [PATCH 1/4] Remove hardcoded string constant representing "UTF-8"
where possible
---
.../main/java/com/sun/faces/RIConstants.java | 4 ++-
.../ConverterPropertyEditorFactory.java | 14 ++------
.../faces/context/ExternalContextImpl.java | 32 +++----------------
.../faces/context/PartialViewContextImpl.java | 11 ++-----
.../com/sun/faces/context/flash/ELFlash.java | 22 +++----------
.../sun/faces/facelets/util/Classpath.java | 13 +++-----
.../sun/faces/lifecycle/RestoreViewPhase.java | 13 ++------
.../com/sun/faces/renderkit/StateHelper.java | 12 ++-----
.../html_basic/OutputLinkRenderer.java | 9 +++---
.../faces/context/PartialResponseWriter.java | 5 ++-
10 files changed, 35 insertions(+), 100 deletions(-)
diff --git a/impl/src/main/java/com/sun/faces/RIConstants.java b/impl/src/main/java/com/sun/faces/RIConstants.java
index 62b400c6b4..cffc4e0ec5 100644
--- a/impl/src/main/java/com/sun/faces/RIConstants.java
+++ b/impl/src/main/java/com/sun/faces/RIConstants.java
@@ -17,6 +17,8 @@
package com.sun.faces;
+import java.nio.charset.StandardCharsets;
+
import com.sun.faces.config.manager.FacesSchema;
import jakarta.faces.render.RenderKitFactory;
@@ -58,7 +60,7 @@ public class RIConstants {
public static final String APPLICATION_XML_CONTENT_TYPE = "application/xml";
public static final String TEXT_XML_CONTENT_TYPE = "text/xml";
public static final String ALL_MEDIA = "*/*";
- public static final String CHAR_ENCODING = "UTF-8";
+ public static final String CHAR_ENCODING = StandardCharsets.UTF_8.name();
public static final String FACELETS_ENCODING_KEY = "facelets.Encoding";
public static final String DEFAULT_LIFECYCLE = FACES_PREFIX + "DefaultLifecycle";
public static final String DEFAULT_STATEMANAGER = FACES_PREFIX + "DefaultStateManager";
diff --git a/impl/src/main/java/com/sun/faces/application/ConverterPropertyEditorFactory.java b/impl/src/main/java/com/sun/faces/application/ConverterPropertyEditorFactory.java
index 660e566abb..9f9d08b41d 100644
--- a/impl/src/main/java/com/sun/faces/application/ConverterPropertyEditorFactory.java
+++ b/impl/src/main/java/com/sun/faces/application/ConverterPropertyEditorFactory.java
@@ -16,6 +16,7 @@
package com.sun.faces.application;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.FINEST;
import static java.util.logging.Level.WARNING;
@@ -23,7 +24,6 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -80,7 +80,6 @@ private static class Utf8InfoRef {
int length;
public Utf8InfoRef(int index, int length) {
- super();
this.index = index;
this.length = length;
}
@@ -102,7 +101,6 @@ private static class Utf8InfoReplacement implements Comparable c) {
* @return the bytes for the UTF8Info constant pool entry, including the tag, length, and utf8 content.
*/
private static byte[] getUtf8InfoBytes(String text) {
- byte[] utf8;
- try {
- utf8 = text.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- // The DM_DEFAULT_ENCODING warning is acceptable here
- // because we explicitly *want* to use the Java runtime's
- // default encoding.
- utf8 = text.getBytes();
- }
+ byte[] utf8 = text.getBytes(UTF_8);
byte[] info = new byte[utf8.length + 3];
info[0] = 1;
info[1] = (byte) (utf8.length >> 8 & 0xff);
diff --git a/impl/src/main/java/com/sun/faces/context/ExternalContextImpl.java b/impl/src/main/java/com/sun/faces/context/ExternalContextImpl.java
index 13e505874b..935754bf91 100644
--- a/impl/src/main/java/com/sun/faces/context/ExternalContextImpl.java
+++ b/impl/src/main/java/com/sun/faces/context/ExternalContextImpl.java
@@ -654,9 +654,8 @@ public void redirect(String requestURI) throws IOException {
pwriter = ctx.getPartialViewContext().getPartialResponseWriter();
}
setResponseContentType(RIConstants.TEXT_XML_CONTENT_TYPE);
- setResponseCharacterEncoding("UTF-8");
+ setResponseCharacterEncoding(RIConstants.CHAR_ENCODING);
addResponseHeader("Cache-Control", "no-cache");
-// pwriter.writePreamble("\n");
pwriter.startDocument();
pwriter.redirect(requestURI);
pwriter.endDocument();
@@ -974,14 +973,7 @@ public boolean isSecure() {
@Override
public String encodeBookmarkableURL(String baseUrl, Map> parameters) {
- FacesContext context = FacesContext.getCurrentInstance();
- String encodingFromContext = (String) context.getAttributes().get(RIConstants.FACELETS_ENCODING_KEY);
- if (null == encodingFromContext) {
- encodingFromContext = (String) context.getViewRoot().getAttributes().get(RIConstants.FACELETS_ENCODING_KEY);
- }
-
- String currentResponseEncoding = null != encodingFromContext ? encodingFromContext : getResponseCharacterEncoding();
-
+ String currentResponseEncoding = Util.getResponseEncoding(FacesContext.getCurrentInstance());
UrlBuilder builder = new UrlBuilder(baseUrl, currentResponseEncoding);
builder.addParameters(parameters);
return builder.createUrl();
@@ -990,14 +982,7 @@ public String encodeBookmarkableURL(String baseUrl, Map> pa
@Override
public String encodeRedirectURL(String baseUrl, Map> parameters) {
- FacesContext context = FacesContext.getCurrentInstance();
- String encodingFromContext = (String) context.getAttributes().get(RIConstants.FACELETS_ENCODING_KEY);
- if (null == encodingFromContext) {
- encodingFromContext = (String) context.getViewRoot().getAttributes().get(RIConstants.FACELETS_ENCODING_KEY);
- }
-
- String currentResponseEncoding = null != encodingFromContext ? encodingFromContext : getResponseCharacterEncoding();
-
+ String currentResponseEncoding = Util.getResponseEncoding(FacesContext.getCurrentInstance());
UrlBuilder builder = new UrlBuilder(baseUrl, currentResponseEncoding);
builder.addParameters(parameters);
return builder.createUrl();
@@ -1013,14 +998,7 @@ public String encodePartialActionURL(String url) {
String message = MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "url");
throw new NullPointerException(message);
}
- FacesContext context = FacesContext.getCurrentInstance();
- String encodingFromContext = (String) context.getAttributes().get(RIConstants.FACELETS_ENCODING_KEY);
- if (null == encodingFromContext) {
- encodingFromContext = (String) context.getViewRoot().getAttributes().get(RIConstants.FACELETS_ENCODING_KEY);
- }
-
- String currentResponseEncoding = null != encodingFromContext ? encodingFromContext : getResponseCharacterEncoding();
-
+ String currentResponseEncoding = Util.getResponseEncoding(FacesContext.getCurrentInstance());
UrlBuilder builder = new UrlBuilder(url, currentResponseEncoding);
return ((HttpServletResponse) response).encodeURL(builder.createUrl());
}
@@ -1078,7 +1056,7 @@ private void pushIfPossibleAndNecessary(String result) {
private PushBuilder getPushBuilder(FacesContext context) {
ExternalContext extContext = context.getExternalContext();
-
+
if (extContext.getRequest() instanceof HttpServletRequest) {
HttpServletRequest hreq = (HttpServletRequest) extContext.getRequest();
diff --git a/impl/src/main/java/com/sun/faces/context/PartialViewContextImpl.java b/impl/src/main/java/com/sun/faces/context/PartialViewContextImpl.java
index f9b379ff53..bbf59f37c8 100644
--- a/impl/src/main/java/com/sun/faces/context/PartialViewContextImpl.java
+++ b/impl/src/main/java/com/sun/faces/context/PartialViewContextImpl.java
@@ -19,9 +19,9 @@
import static com.sun.faces.renderkit.RenderKitUtils.PredefinedPostbackParameter.PARTIAL_EXECUTE_PARAM;
import static com.sun.faces.renderkit.RenderKitUtils.PredefinedPostbackParameter.PARTIAL_RENDER_PARAM;
import static com.sun.faces.renderkit.RenderKitUtils.PredefinedPostbackParameter.PARTIAL_RESET_VALUES_PARAM;
+import static jakarta.faces.FactoryFinder.VISIT_CONTEXT_FACTORY;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.WARNING;
-import static jakarta.faces.FactoryFinder.VISIT_CONTEXT_FACTORY;
import java.io.IOException;
import java.io.Writer;
@@ -281,11 +281,6 @@ public void processPartial(PhaseId phaseId) {
exContext.setResponseContentType(RIConstants.TEXT_XML_CONTENT_TYPE);
exContext.addResponseHeader("Cache-Control", "no-cache");
-// String encoding = writer.getCharacterEncoding( );
-// if( encoding == null ) {
-// encoding = "UTF-8";
-// }
-// writer.writePreamble("\n");
writer.startDocument();
if (isResetValues()) {
@@ -322,7 +317,7 @@ public void processPartial(PhaseId phaseId) {
}
}
}
-
+
private void doFlashPostPhaseActions(FacesContext ctx) {
try {
ctx.getExternalContext().getFlash().doPostPhaseActions(ctx);
@@ -630,7 +625,7 @@ public DelayedInitPartialResponseWriter(PartialViewContextImpl ctx) {
super(null);
this.ctx = ctx;
ExternalContext extCtx = ctx.ctx.getExternalContext();
-
+
if (extCtx.isResponseCommitted()) {
LOGGER.log(WARNING, "Response is already committed - cannot reconfigure it anymore");
}
diff --git a/impl/src/main/java/com/sun/faces/context/flash/ELFlash.java b/impl/src/main/java/com/sun/faces/context/flash/ELFlash.java
index 85a728229f..c653e4627d 100644
--- a/impl/src/main/java/com/sun/faces/context/flash/ELFlash.java
+++ b/impl/src/main/java/com/sun/faces/context/flash/ELFlash.java
@@ -18,8 +18,8 @@
import static com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter.EnableDistributable;
import static com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter.ForceAlwaysWriteFlashCookie;
+import static java.nio.charset.StandardCharsets.UTF_8;
-import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
@@ -640,7 +640,7 @@ public void doPostPhaseActions(FacesContext context) {
* necessary because the call to extContext.flushBuffer() is too late, the response has already been committed by that
* point. outgoingResponseIsRedirect is false.
*
- *
+ *
* @param context the involved faces context
* @param outgoingResponseIsRedirect whether outgoing response is redirect
*/
@@ -1313,15 +1313,7 @@ void expireNext_MovePreviousToNext() {
void decode(FacesContext context, ELFlash flash, Cookie cookie) throws InvalidKeyException {
String temp;
String value;
-
- String urlDecodedValue = null;
-
- try {
- urlDecodedValue = URLDecoder.decode(cookie.getValue(), "UTF-8");
- } catch (UnsupportedEncodingException uee) {
- urlDecodedValue = cookie.getValue();
- }
-
+ String urlDecodedValue = URLDecoder.decode(cookie.getValue(), UTF_8);
value = guard.decrypt(urlDecodedValue);
try {
@@ -1390,16 +1382,10 @@ void decode(FacesContext context, ELFlash flash, Cookie cookie) throws InvalidKe
*
*/
Cookie encode() {
- Cookie result = null;
-
String value = (null != previousRequestFlashInfo ? previousRequestFlashInfo.encode() : "") + "_"
+ (null != nextRequestFlashInfo ? nextRequestFlashInfo.encode() : "");
String encryptedValue = guard.encrypt(value);
- try {
- result = new Cookie(FLASH_COOKIE_NAME, URLEncoder.encode(encryptedValue, "UTF-8"));
- } catch (UnsupportedEncodingException uee) {
- result = new Cookie(FLASH_COOKIE_NAME, encryptedValue);
- }
+ Cookie result = new Cookie(FLASH_COOKIE_NAME, URLEncoder.encode(encryptedValue, UTF_8));
if (1 == value.length()) {
result.setMaxAge(0);
diff --git a/impl/src/main/java/com/sun/faces/facelets/util/Classpath.java b/impl/src/main/java/com/sun/faces/facelets/util/Classpath.java
index ac2bbce3b3..829cf0c20f 100644
--- a/impl/src/main/java/com/sun/faces/facelets/util/Classpath.java
+++ b/impl/src/main/java/com/sun/faces/facelets/util/Classpath.java
@@ -16,6 +16,8 @@
package com.sun.faces.facelets.util;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -45,13 +47,6 @@ public final class Classpath {
private static final String[] PREFIXES_TO_EXCLUDE = { "rar:", "sar:" };
private static final String[] EXTENSIONS_TO_EXCLUDE = { ".rar", ".sar" };
- /**
- *
- */
- public Classpath() {
- super();
- }
-
public enum SearchAdvice {
FirstMatchOnly, AllMatches
}
@@ -93,7 +88,7 @@ public static URL[] search(ClassLoader cl, String prefix, String suffix, SearchA
if (jarFile != null) {
searchJar(cl, all, jarFile, prefix, suffix, advice);
} else {
- boolean searchDone = searchDir(all, new File(URLDecoder.decode(url.getFile(), "UTF-8")), suffix);
+ boolean searchDone = searchDir(all, new File(URLDecoder.decode(url.getFile(), UTF_8)), suffix);
if (!searchDone) {
searchFromURL(all, prefix, suffix, url);
}
@@ -244,7 +239,7 @@ static JarFile getAlternativeJarFile(String urlFile) throws IOException {
// And trim off any "file:" prefix.
if (jarFileUrl.startsWith("file:")) {
jarFileUrl = jarFileUrl.substring("file:".length());
- jarFileUrl = URLDecoder.decode(jarFileUrl, "UTF-8");
+ jarFileUrl = URLDecoder.decode(jarFileUrl, UTF_8);
}
boolean foundExclusion = false;
for (int i = 0; i < PREFIXES_TO_EXCLUDE.length; i++) {
diff --git a/impl/src/main/java/com/sun/faces/lifecycle/RestoreViewPhase.java b/impl/src/main/java/com/sun/faces/lifecycle/RestoreViewPhase.java
index 2e335c0190..74af50b913 100644
--- a/impl/src/main/java/com/sun/faces/lifecycle/RestoreViewPhase.java
+++ b/impl/src/main/java/com/sun/faces/lifecycle/RestoreViewPhase.java
@@ -29,10 +29,10 @@
import static jakarta.faces.event.PhaseId.RESTORE_VIEW;
import static jakarta.faces.render.ResponseStateManager.NON_POSTBACK_VIEW_TOKEN_PARAM;
import static jakarta.faces.view.ViewMetadata.hasMetadata;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.SEVERE;
-import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
@@ -249,16 +249,7 @@ private void maybeTakeProtectedViewAction(FacesContext context, ViewHandler view
String incomingSecretKeyValue = extContext.getRequestParameterMap().get(NON_POSTBACK_VIEW_TOKEN_PARAM);
if (incomingSecretKeyValue != null) {
- try {
- incomingSecretKeyValue = URLEncoder.encode(incomingSecretKeyValue, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- if (LOGGER.isLoggable(SEVERE)) {
- LOGGER.log(SEVERE,
- "Unable to re-encode value of request parameter " + NON_POSTBACK_VIEW_TOKEN_PARAM + ":"
- + incomingSecretKeyValue, e);
- }
- incomingSecretKeyValue = null;
- }
+ incomingSecretKeyValue = URLEncoder.encode(incomingSecretKeyValue, UTF_8);
}
String correctSecretKeyValue = rsm.getCryptographicallyStrongTokenFromSession(context);
diff --git a/impl/src/main/java/com/sun/faces/renderkit/StateHelper.java b/impl/src/main/java/com/sun/faces/renderkit/StateHelper.java
index 6756c4028c..43380f0db1 100644
--- a/impl/src/main/java/com/sun/faces/renderkit/StateHelper.java
+++ b/impl/src/main/java/com/sun/faces/renderkit/StateHelper.java
@@ -21,11 +21,10 @@
import static com.sun.faces.renderkit.RenderKitUtils.PredefinedPostbackParameter.CLIENT_WINDOW_PARAM;
import static com.sun.faces.renderkit.RenderKitUtils.PredefinedPostbackParameter.RENDER_KIT_ID_PARAM;
import static com.sun.faces.renderkit.RenderKitUtils.PredefinedPostbackParameter.VIEW_STATE_PARAM;
+import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
-import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.faces.RIConstants;
@@ -113,12 +112,7 @@ public static void createAndStoreCryptographicallyStrongTokenInSession(HttpSessi
ByteArrayGuardAESCTR guard = new ByteArrayGuardAESCTR();
String clearText = "" + System.currentTimeMillis();
String result = guard.encrypt(clearText);
- try {
- result = URLEncoder.encode(result, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- LOGGER.log(Level.SEVERE, "Unable to URL encode cryptographically strong token, storing clear text in session instead.", e);
- result = clearText;
- }
+ result = URLEncoder.encode(result, UTF_8);
session.setAttribute(TOKEN_NAME, result);
}
@@ -173,7 +167,7 @@ protected static String getStateParamValue(FacesContext context) {
if (pValue != null && pValue.length() == 0) {
pValue = null;
}
-
+
return pValue;
}
diff --git a/impl/src/main/java/com/sun/faces/renderkit/html_basic/OutputLinkRenderer.java b/impl/src/main/java/com/sun/faces/renderkit/html_basic/OutputLinkRenderer.java
index 2bb779516d..750b7668e4 100644
--- a/impl/src/main/java/com/sun/faces/renderkit/html_basic/OutputLinkRenderer.java
+++ b/impl/src/main/java/com/sun/faces/renderkit/html_basic/OutputLinkRenderer.java
@@ -19,6 +19,7 @@
package com.sun.faces.renderkit.html_basic;
import static com.sun.faces.util.Util.componentIsDisabled;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.logging.Level.FINE;
import java.io.IOException;
@@ -35,7 +36,7 @@
/**
* OutputLinkRenderer is a class ...
- *
+ *
* Lifetime And Scope
*
*/
@@ -133,7 +134,7 @@ protected Object getValue(UIComponent component) {
if (componentIsDisabled(component)) {
return null;
}
-
+
return ((UIOutput) component).getValue();
}
@@ -176,10 +177,10 @@ protected void renderAsActive(FacesContext context, UIComponent component) throw
if (pn != null && pn.length() != 0) {
String pv = paramList[i].value;
sb.append(paramWritten ? '&' : '?');
- sb.append(URLEncoder.encode(pn, "UTF-8"));
+ sb.append(URLEncoder.encode(pn, UTF_8));
sb.append('=');
if (pv != null && pv.length() != 0) {
- sb.append(URLEncoder.encode(pv, "UTF-8"));
+ sb.append(URLEncoder.encode(pv, UTF_8));
}
paramWritten = true;
}
diff --git a/impl/src/main/java/jakarta/faces/context/PartialResponseWriter.java b/impl/src/main/java/jakarta/faces/context/PartialResponseWriter.java
index aa4b4cf893..49a6427519 100644
--- a/impl/src/main/java/jakarta/faces/context/PartialResponseWriter.java
+++ b/impl/src/main/java/jakarta/faces/context/PartialResponseWriter.java
@@ -17,8 +17,11 @@
package jakarta.faces.context;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.Map;
+import com.sun.faces.RIConstants;
+
import jakarta.faces.component.NamingContainer;
import jakarta.faces.component.UIViewRoot;
import jakarta.faces.render.ResponseStateManager;
@@ -97,7 +100,7 @@ public void startDocument() throws IOException {
ResponseWriter writer = getWrapped();
String encoding = writer.getCharacterEncoding();
if (encoding == null) {
- encoding = "utf-8";
+ encoding = RIConstants.CHAR_ENCODING;
}
writer.writePreamble("\n");
writer.startElement("partial-response", null);
From 84f890583e94b9b6780417313fb134b7ada13854 Mon Sep 17 00:00:00 2001
From: Bauke Scholtz
Date: Sat, 20 Jan 2024 15:40:45 -0400
Subject: [PATCH 2/4] Review/cleanup Facelets/Request/Response encoding
implementation https://github.com/eclipse-ee4j/mojarra/issues/5383
---
.../view/FaceletViewHandlingStrategy.java | 71 +++--------------
.../application/view/MultiViewHandler.java | 22 +-----
.../com/sun/faces/context/UrlBuilder.java | 5 +-
.../main/java/com/sun/faces/util/Util.java | 77 ++++++++++++++++++-
.../faces/application/ViewHandler.java | 13 +++-
5 files changed, 100 insertions(+), 88 deletions(-)
diff --git a/impl/src/main/java/com/sun/faces/application/view/FaceletViewHandlingStrategy.java b/impl/src/main/java/com/sun/faces/application/view/FaceletViewHandlingStrategy.java
index 4075ffb474..444082f30b 100644
--- a/impl/src/main/java/com/sun/faces/application/view/FaceletViewHandlingStrategy.java
+++ b/impl/src/main/java/com/sun/faces/application/view/FaceletViewHandlingStrategy.java
@@ -43,7 +43,6 @@
import static jakarta.faces.application.Resource.COMPONENT_RESOURCE_KEY;
import static jakarta.faces.application.StateManager.IS_BUILDING_INITIAL_STATE;
import static jakarta.faces.application.StateManager.STATE_SAVING_METHOD_SERVER;
-import static jakarta.faces.application.ViewHandler.CHARACTER_ENCODING_KEY;
import static jakarta.faces.application.ViewHandler.DEFAULT_FACELETS_SUFFIX;
import static jakarta.faces.application.ViewVisitOption.RETURN_AS_MINIMAL_IMPLICIT_OUTCOME;
import static jakarta.faces.component.UIComponent.BEANINFO_KEY;
@@ -72,6 +71,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
@@ -904,26 +904,29 @@ protected ResponseWriter createResponseWriter(FacesContext context) throws IOExc
// get our content type
String contentType = (String) context.getAttributes().get("facelets.ContentType");
- // get the encoding
+ // get the last calculated encoding
String encoding = (String) context.getAttributes().get(FACELETS_ENCODING_KEY);
// Create a dummy ResponseWriter with a bogus writer,
- // so we can figure out what content type the ReponseWriter
+ // so we can figure out what content type and encoding the ReponseWriter
// is really going to ask for
- ResponseWriter writer = renderKit.createResponseWriter(NullWriter.INSTANCE, contentType, encoding);
+ ResponseWriter initWriter = renderKit.createResponseWriter(NullWriter.INSTANCE, contentType, encoding);
- contentType = getResponseContentType(context, writer.getContentType());
- encoding = getResponseEncoding(context, writer.getCharacterEncoding());
+ contentType = getResponseContentType(context, initWriter.getContentType());
+ encoding = Util.getResponseEncoding(context, Optional.ofNullable(initWriter.getCharacterEncoding()));
// apply them to the response
char[] buffer = new char[1028];
- HtmlUtils.writeTextForXML(writer, contentType, buffer);
+ HtmlUtils.writeTextForXML(initWriter, contentType, buffer);
String str = String.valueOf(buffer).trim();
extContext.setResponseContentType(str);
extContext.setResponseCharacterEncoding(encoding);
+ // Save encoding in UIViewRoot for faster consult when Util#getResponseEncoding() is invoked again elsewhere.
+ context.getViewRoot().getAttributes().put(FACELETS_ENCODING_KEY, encoding);
+
// Now, clone with the real writer
- writer = writer.cloneWithWriter(extContext.getResponseOutputWriter());
+ ResponseWriter writer = initWriter.cloneWithWriter(extContext.getResponseOutputWriter());
return writer;
}
@@ -974,58 +977,6 @@ protected void handleFaceletNotFound(FacesContext context, String viewId, String
context.responseComplete();
}
- /**
- * @param context the {@link FacesContext} for the current request
- * @param orig the original encoding
- * @return the encoding to be used for this response
- */
- protected String getResponseEncoding(FacesContext context, String orig) {
- String encoding = orig;
-
- // 1. get it from request
- encoding = context.getExternalContext().getRequestCharacterEncoding();
-
- // 2. get it from the session
- if (encoding == null) {
- if (context.getExternalContext().getSession(false) != null) {
- Map sessionMap = context.getExternalContext().getSessionMap();
- encoding = (String) sessionMap.get(CHARACTER_ENCODING_KEY);
- if (LOGGER.isLoggable(FINEST)) {
- LOGGER.log(FINEST, "Session specified alternate encoding {0}", encoding);
- }
- }
- }
-
- // see if we need to override the encoding
- Map