[
https://issues.apache.org/jira/browse/WW-5496?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17906112#comment-17906112
]
Günter Paul commented on WW-5496:
---------------------------------
Filter-class
{code:java}
package de.guenterpaul.servlet;import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import java.util.StringTokenizer;
public class BlankFilter
implements Filter
{
@Override
public void init(FilterConfig pFilterConfig)
{
setTrimOnly(pFilterConfig.getInitParameter("trimOnly"));
if (m_Logger.isDebugEnabled()) m_Logger.debug("init filter: " + this);
} @Override
public void doFilter(ServletRequest pServletRequest,
ServletResponse pServletResponse,
FilterChain pFilterChain)
{
HttpServletRequest lHttpServletRequest = (HttpServletRequest)
pServletRequest;
if (m_Logger.isInfoEnabled()) m_Logger.info("Start Blank-Filter >" +
lHttpServletRequest.getRequestURI() + "< " + this); try
{
HttpServletResponse lHttpServletResponse = (HttpServletResponse)
pServletResponse;
StringResponseWrapper lResponseWrapper = new
StringResponseWrapper(lHttpServletResponse);
pFilterChain.doFilter(pServletRequest,lResponseWrapper); if
(m_Logger.isDebugEnabled()) m_Logger.debug("ContentType >" +
lResponseWrapper.getContentType() + "<");
if ( (lResponseWrapper.getContentType() != null) &&
(lResponseWrapper.getContentType().startsWith("text/html")) )
{
if (m_Logger.isInfoEnabled())
{
m_Logger.info("BlankFilter Text >" +
lResponseWrapper.getContentType() + "< Size: " +
lResponseWrapper.getBufferSize());
}
StringBuilder lStringBuffer = new StringBuilder(); String
lsResponse = lResponseWrapper.toString().trim();
if (m_Logger.isDebugEnabled())
{
m_Logger.debug("Response >" + lsResponse + "<");
}
lsResponse = lsResponse.replaceAll("\r\n", "\n");
StringTokenizer lStringTokenizer = new StringTokenizer(lsResponse, "\n");
while (lStringTokenizer.hasMoreTokens())
{
String lsZeile = lStringTokenizer.nextToken().trim();
if (m_Logger.isDebugEnabled()) m_Logger.debug("Zeile >" + lsZeile +
"<");
if (lsZeile.isEmpty() == false)
{
lStringBuffer.append(lsZeile.trim());
if (isTrimOnly() == true)
{
lStringBuffer.append("\r\n");
}
}
} if (m_Logger.isInfoEnabled()) m_Logger.info("Laenge Ausgabe: "
+ lStringBuffer.toString().length());
if (m_Logger.isDebugEnabled())
{
m_Logger.debug(lStringBuffer);
}
lHttpServletResponse.setContentType(lResponseWrapper.getContentType());
lHttpServletResponse.setContentLength(lStringBuffer.toString().length());
lHttpServletResponse.getWriter().print(lStringBuffer);
}
else
{
m_Logger.debug("Standard Ausgabe: " + lResponseWrapper.getBufferSize());
if ( (lResponseWrapper.getBufferSize() > 0) &&
(lResponseWrapper.toString() != null) )
{
pServletResponse.getOutputStream().write(lResponseWrapper.toString().getBytes());
}
}
if (m_Logger.isDebugEnabled())
{
m_Logger.debug("Ende Request BlankFilter >" +
lHttpServletRequest.getRequestURI() + "<");
}
}
catch (Exception ex)
{
m_Logger.error("Fehler: " + ex.getMessage(), ex);
} if (m_Logger.isDebugEnabled()) m_Logger.debug("Ende Blank-Filter");
} @Override
public void destroy()
{
if (m_Logger.isDebugEnabled()) m_Logger.debug("destroy filter");
} public boolean isTrimOnly()
{
return m_bTrimOnly;
} public void setTrimOnly(boolean pbTrimOnly)
{
if (m_Logger.isDebugEnabled()) m_Logger.debug("B: TrimOnly: " + pbTrimOnly);
this.m_bTrimOnly = pbTrimOnly;
} public void setTrimOnly(String psTrimOnly)
{
boolean lbTrimOnly = isTrimOnly();
if ((psTrimOnly != null) && (psTrimOnly.isEmpty() == false) )
{
if (psTrimOnly.toLowerCase().equals(Boolean.TRUE.toString()))
{
lbTrimOnly = true;
}
else if (psTrimOnly.toLowerCase().equals(Boolean.FALSE.toString()))
{
lbTrimOnly = false;
}
}
if (m_Logger.isDebugEnabled()) m_Logger.debug("S: TrimOnly >" + psTrimOnly
+ "< : " + lbTrimOnly);
setTrimOnly(lbTrimOnly);
} @Override
public String toString()
{
return "BlankFilter{" + "m_bTrimOnly=" + m_bTrimOnly + '}';
} private static final Logger m_Logger =
LogManager.getLogger(BlankFilter.class.getName()); private boolean m_bTrimOnly
= false;
}
{code}
ResponseWrapper-class
{code:java}
package de.guenterpaul.servlet;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.WriteListener;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;import
java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;public class StringResponseWrapper extends
HttpServletResponseWrapper
{
private final ByteArrayOutputStream capture;
private ServletOutputStream output;
private PrintWriter writer; public StringResponseWrapper(HttpServletResponse
response) { super(response);
capture = new ByteArrayOutputStream(response.getBufferSize());
} @Override
public ServletOutputStream getOutputStream() { if (writer != null) {
throw new IllegalStateException("getWriter() has already been called on
this response.");
} if (output == null) {
// inner class - lets the wrapper manipulate the response
output = new ServletOutputStream()
{
@Override
public boolean isReady()
{
return true;
} @Override
public void setWriteListener(WriteListener writeListener)
{ } @Override
public void write(int b)
{ capture.write(b);
} @Override
public void flush() throws IOException { capture.flush();
} @Override
public void close() throws IOException { capture.close();
}
};
} return output;
} @Override
public PrintWriter getWriter() throws IOException { if (output != null) {
throw new IllegalStateException("getOutputStream() has already been
called on this response.");
} if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(capture,
getCharacterEncoding()));
} return writer;
} @Override
public void flushBuffer() throws IOException { super.flushBuffer(); if
(writer != null) {
writer.flush();
} else if (output != null) {
output.flush();
}
} public byte[] getCaptureAsBytes() throws IOException
{
flushBuffer();
if (writer != null) {
writer.close();
} else if (output != null) {
output.close();
} return capture.toByteArray();
} public String getCaptureAsString() throws IOException { return new
String(getCaptureAsBytes(), getCharacterEncoding());
} @Override
public String toString()
{
try
{
return getCaptureAsString();
}
catch (IOException e)
{
return super.toString();
}
}
}
{code}
> Struts filter and HttpServletResponseWrapper
> --------------------------------------------
>
> Key: WW-5496
> URL: https://issues.apache.org/jira/browse/WW-5496
> Project: Struts 2
> Issue Type: Bug
> Components: Core
> Affects Versions: 7.0.0
> Reporter: Günter Paul
> Priority: Minor
> Fix For: 7.1.0
>
>
> I've been using a servlet filter for a long time. It removes spaces in the
> lines (trim()) and line breaks (only for *.action requests).
> The filter is installed in the web.xml before the struts filter. It works
> very well so far, even with the current Struts 7.0.0-M10 version.
> Until now I was using Tomcat 10. After switching to Tomcat 11, only blank
> pages are displayed.
> If I use a web-application without struts, the filter works fine. Only when
> the Struts filter (StrutsPrepareAndExecuteFilter) is installed does the
> output of the wrapper appear to no longer be included in the output stream.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)