Well finally i have a possible approach.
Thanks @Jörg_Hoh and @BrianKasingli for all your help!!
here is the filter that i created and seems to be working. And i would like to share the solution and know your opinions.
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
@Component(immediate = true)
@Service(Filter.class)
@Properties({ @Property(name = "sling.filter.scope", value = "REQUEST"),
@Property(name = "sling.filter.pattern", value = ".*\\.html"),
@Property(name = "service.ranking", value = "700") })
public class HTMLFormatterFilter extends SlingAllMethodsServlet implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// create a response wrapper to capture the original response
CharResponseWrapper wrappedResponse = new CharResponseWrapper(
(HttpServletResponse)response);
chain.doFilter(request, wrappedResponse);
// modify the response with the formatted html
byte[] bytes = wrappedResponse.getByteArray();
if (wrappedResponse.getContentType().contains("text/html")) {
String out = new String(bytes);
Document doc = Jsoup.parse(out);
response.getOutputStream().write(doc.toString().getBytes());
}
else {
response.getOutputStream().write(bytes);
}
}
@Override
public void destroy() {
// Do nothing
}
private static class ByteArrayServletStream extends ServletOutputStream
{
ByteArrayOutputStream baos;
ByteArrayServletStream(ByteArrayOutputStream baos)
{
this.baos = baos;
}
public void write(int param) throws IOException
{
baos.write(param);
}
}
private static class ByteArrayPrintWriter
{
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private PrintWriter pw = new PrintWriter(baos);
private ServletOutputStream sos = new ByteArrayServletStream(baos);
public PrintWriter getWriter()
{
return pw;
}
public ServletOutputStream getStream()
{
return sos;
}
byte[] toByteArray()
{
return baos.toByteArray();
}
}
private static class CharResponseWrapper extends HttpServletResponseWrapper
{
private ByteArrayPrintWriter output;
private boolean usingWriter;
public CharResponseWrapper(HttpServletResponse response)
{
super(response);
usingWriter = false;
output = new ByteArrayPrintWriter();
}
public byte[] getByteArray()
{
return output.toByteArray();
}
@Override
public ServletOutputStream getOutputStream() throws IOException
{
// will error out, if in use
if (usingWriter) {
super.getOutputStream();
}
usingWriter = true;
return output.getStream();
}
@Override
public PrintWriter getWriter() throws IOException
{
// will error out, if in use
if (usingWriter) {
super.getWriter();
}
usingWriter = true;
return output.getWriter();
}
public String toString()
{
return output.toString();
}
}
}