Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save xexes/7fe17ad78b7a45a89757c68509065bf5 to your computer and use it in GitHub Desktop.
Save xexes/7fe17ad78b7a45a89757c68509065bf5 to your computer and use it in GitHub Desktop.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.WriteListener;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
class CapturingResponseWrapper extends HttpServletResponseWrapper {
private final ByteArrayOutputStream capture;
private ServletOutputStream output;
private PrintWriter writer;
public CapturingResponseWrapper(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) {
output = new ServletOutputStream() {
@Override public boolean isReady() {
return true;
}
@Override public void setWriteListener(WriteListener writeListener) {
}
@Override
public void write(int b) throws IOException {
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 {
if (writer != null) {
writer.close();
} else if (output != null) {
output.close();
}
return capture.toByteArray();
}
public String getCaptureAsString() throws IOException {
return new String(getCaptureAsBytes(), getCharacterEncoding());
}
}
package com.maciejwalkowiak.just.spring.boot.livereload.jakarta;
import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
class LiveReloadScriptFilter implements Filter {
private final String scriptSnippet;
LiveReloadScriptFilter(int liveReloadPort, int justServerPort) {
this.scriptSnippet = String.format(
"<script src=\"http://localhost:%d/livereload/livereload.js?port=%d&host=localhost\"></script>", justServerPort,
liveReloadPort);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
CapturingResponseWrapper capturingResponseWrapper = new CapturingResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(request, capturingResponseWrapper);
String contentType = capturingResponseWrapper.getContentType();
String content = capturingResponseWrapper.getCaptureAsString();
if ((contentType != null) && MediaType.TEXT_HTML.isCompatibleWith(MediaType.parseMediaType(contentType))) {
String alreadyFilteredAttributeName = this.getAlreadyFilteredAttributeName();
boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null;
if (!hasAlreadyFilteredAttribute) {
request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
response.getWriter().write(content + this.scriptSnippet);
} else {
response.getWriter().write(content);
}
} else {
response.getWriter().write(content);
}
}
protected String getAlreadyFilteredAttributeName() {
String name = this.getClass().getName();
return name + ".FILTERED";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment