Reputation: 11
I have a servlet response filter. My response body is not modified for successful requests. Exceptions are successful wrapped and response body is modified. My code is mere copy/paste from the book O'Reilly Learning Java 4th edition code found at https://learning.oreilly.com/library/view/learning-java-4th/9781449372477/ch15s04.html#:-:text=Filtering%20the%20Servlet%20Response
Here is the code from the book with minor modifications for my requirement-
public class LinkResponseFilter implements Filter {
FilterConfig filterConfig;
public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
WrappedResponse wrappedResponse = new WrappedResponse((HttpServletResponse) res);
chain.doFilter(req, wrappedResponse);
wrappedResponse.close();
}
public void destroy() {
}
static class WrappedResponse extends HttpServletResponseWrapper {
boolean linkText;
PrintWriter client;
WrappedResponse(HttpServletResponse res) {
super(res);
}
public void setContentType(String mime) {
super.setContentType(mime);
if (mime.startsWith("application/fhir+json")) { //BOOK CODE CHECKS FOR html
linkText = true;
}
}
public PrintWriter getWriter() throws IOException {
if (client == null) {
if (linkText) {
client = new LinkWriter(super.getWriter(), new ByteArrayOutputStream());
} else {
client = super.getWriter();
}
}
return client;
}
void close() {
if (client != null) {
client.close();
}
}
}
static class LinkWriter extends PrintWriter {
ByteArrayOutputStream buffer;
Writer client;
LinkWriter(Writer client, ByteArrayOutputStream buffer) {
super(buffer);
this.buffer = buffer;
this.client = client;
}
public void close() {
try {
flush();
client.write(linkText(buffer.toString()));
client.close();
} catch (IOException e) {
setError();
}
}
String linkText(String text) {
text = text.replaceAll( "resourceType", "None");//BOOK HAS DIFFERENT LOGIC
return text;
}
}
}
Upvotes: 0
Views: 136
Reputation: 100
From the book itself it clearly mentioned
That was a bit longer than our previous examples, but the basics are the same. We wrapped the HttpServletResponse object with our own WrappedResponse class using the HttpServletResponseWrapper helper class. Our WrappedResponse overrides two methods: getWriter() and setContentType(). We override setContentType() in order to set a flag that indicates whether the output is of type “text/html” (an HTML document). We don’t want to be performing regular-expression replacements on binary data such as images, for example, should they happen to match our filter. We also override getWriter() to provide our substitute writer stream, LinkWriter. Our LinkWriter class is a PrintStream that takes as arguments the client PrintWriter and a ByteArrayOutputStream that serves as a buffer for storing output data before it is written. We are careful to substitute our LinkWriter only if the linkText Boolean set by setContent() is true. When we do use our LinkWriter, we cache the stream so that any subsequent calls to getWriter() return the same object. Finally, we have added one method to the response object: close(). A normal HttpServletResponse does not have a close() method. We use ours on the return trip to the client to indicate that the LinkWriter should complete its processing and write the actual data to the client. We do this in case the client does not explicitly close the output stream before exiting the servlet service methods.
which means when we set the linkText = true
for the contentType "application/fhir+json"
then the getWriter()
method will return the same object which means the WrappedResponse will not happen to the successful responses which has the contentType "application/fhir+json"
.
As I asked previously have you gone through the debug mode for successful and failure .
linkText
is the culprit in your case . Do the debug and you will came to a conclusionUpvotes: 0