diff --git a/CLAUDE.md b/CLAUDE.md
index 3710f03544..408f7c02da 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -148,6 +148,7 @@ Each plugin is a separate Maven module with:
### Important Notes
- **Version**: Currently 6.7.5-SNAPSHOT (release branch: `release/struts-6-7-x`)
- **Java Compatibility**: Compiled for Java 8, tested through Java 21
+- **Servlet API**: Uses javax.servlet (Java EE), NOT Jakarta EE (jakarta.servlet)
- **Security**: Always validate inputs and follow OWASP guidelines
- **Performance**: Leverage built-in caching (OGNL expressions, templates)
- **Deprecation**: Some legacy XWork components marked for removal
diff --git a/core/src/main/java/org/apache/struts2/result/StreamResult.java b/core/src/main/java/org/apache/struts2/result/StreamResult.java
index 9324d5bb55..235152e984 100644
--- a/core/src/main/java/org/apache/struts2/result/StreamResult.java
+++ b/core/src/main/java/org/apache/struts2/result/StreamResult.java
@@ -21,6 +21,7 @@
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.security.NotExcludedAcceptedPatternsChecker;
+import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -223,7 +224,7 @@ protected void doExecute(String finalLocation, ActionInvocation invocation) thro
if (inputStream == null) {
String msg = ("Can not find a java.io.InputStream with the name [" + parsedInputName + "] in the invocation stack. " +
- "Check the tag specified for this action is correct, not excluded and accepted.");
+ "Check the tag specified for this action is correct, not excluded and accepted.");
LOG.error(msg);
throw new IllegalArgumentException(msg);
}
@@ -231,11 +232,12 @@ protected void doExecute(String finalLocation, ActionInvocation invocation) thro
HttpServletResponse oResponse = invocation.getInvocationContext().getServletResponse();
- LOG.debug("Set the content type: {};charset{}", contentType, contentCharSet);
- if (contentCharSet != null && !contentCharSet.equals("")) {
- oResponse.setContentType(conditionalParse(contentType, invocation) + ";charset=" + conditionalParse(contentCharSet, invocation));
- } else {
- oResponse.setContentType(conditionalParse(contentType, invocation));
+ LOG.debug("Set the content type: {};charset={}", contentType, contentCharSet);
+ String parsedContentType = conditionalParse(contentType, invocation);
+ String parsedContentCharSet = conditionalParse(contentCharSet, invocation);
+ oResponse.setContentType(parsedContentType);
+ if (StringUtils.isNotEmpty(parsedContentCharSet)) {
+ oResponse.setCharacterEncoding(parsedContentCharSet);
}
LOG.debug("Set the content length: {}", contentLength);
@@ -267,7 +269,7 @@ protected void doExecute(String finalLocation, ActionInvocation invocation) thro
oOutput = oResponse.getOutputStream();
LOG.debug("Streaming result [{}] type=[{}] length=[{}] content-disposition=[{}] charset=[{}]",
- inputName, contentType, contentLength, contentDisposition, contentCharSet);
+ inputName, contentType, contentLength, contentDisposition, contentCharSet);
LOG.debug("Streaming to output buffer +++ START +++");
byte[] oBuff = new byte[bufferSize];
diff --git a/core/src/test/java/org/apache/struts2/result/StreamResultTest.java b/core/src/test/java/org/apache/struts2/result/StreamResultTest.java
index a02781812f..a7621e8e94 100644
--- a/core/src/test/java/org/apache/struts2/result/StreamResultTest.java
+++ b/core/src/test/java/org/apache/struts2/result/StreamResultTest.java
@@ -120,6 +120,16 @@ public void testStreamResultWithCharSet2() throws Exception {
assertEquals("inline", response.getHeader("Content-disposition"));
}
+ public void testStreamResultWithNullCharSetExpression() throws Exception {
+ result.setParse(true);
+ result.setInputName("streamForImage");
+ result.setContentCharSet("${nullCharSetMethod}");
+
+ result.doExecute("helloworld", mai);
+
+ assertEquals("text/plain", response.getContentType());
+ }
+
public void testAllowCacheDefault() throws Exception {
result.setInputName("streamForImage");
@@ -310,6 +320,10 @@ public String getStreamForImageAsExpression() {
public String getContentCharSetMethod() {
return "UTF-8";
}
+
+ public String getNullCharSetMethod() {
+ return null;
+ }
}
}