Olá,
Descrição;
Estou procurando melhorar a performance de meu web site, a principio implemente uma forma que monto dinamicamente varios css e gero um cada controller do vraptor atravez de uma anotação, junto todos os css e o comprimo usando o YUI Compressor até ai esta funcionando, faço isso em um interceptor…
isso fica legal porque após criado o arquivo não recrio ele apenas o utilizo o arquivo que esta criado gerando performance…
O meu problema
Preciso que seja cacheado em browser o css e o js, encontrei algumas coisas como por exemplo esta classe q esta abaixo, porém estou usando vraptor 3 e gostaria de saber se tem alguma coisa que posso usar para retornar no response as informações de cache para o browser e ganhar performance na app;
// codigo que encontrei na internet
package control.cache;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.servlets.DefaultServlet;
public class CustomFileServlet extends DefaultServlet {
private static final long serialVersionUID = 1L;
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
processRequest(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
processRequest(request, response);
}
public boolean processRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String requestURI = request.getRequestURI();
String contextPath = request.getContextPath();
String fileURI = "";
if (requestURI.indexOf(contextPath) != -1) {
// Request URI is CONTEXTPATH + RESOURCE URI
fileURI = requestURI.substring(requestURI.indexOf(contextPath) + contextPath.length());
}
File file = new File(request.getSession().getServletContext().getRealPath(fileURI));
String lowerfile = file.getAbsolutePath().toLowerCase();
boolean isBasePath = "/".equalsIgnoreCase(fileURI);
boolean isJSFile = lowerfile.endsWith(".js");
boolean isCSSFile = lowerfile.endsWith(".css");
boolean customServing = (!isBasePath) && (isJSFile || isCSSFile);
if(customServing) {
String mimetype = request.getSession().getServletContext().getMimeType(fileURI);
response.setContentType(mimetype);
// Required Cache Control Headers
String maxage = "86400"; // One day in Seconds
response.setHeader("Cache-Control", "max-age="+ maxage);
long relExpiresInMillis = System.currentTimeMillis() + (1000 * Long.parseLong(maxage));
response.setHeader("Expires", getGMTTimeString(relExpiresInMillis));
response.setHeader("Last-Modified", getGMTTimeString(file.lastModified()));
// Serve the file content
FileInputStream fis = new FileInputStream(file);
OutputStream ostream = response.getOutputStream();
streamIO(fis, ostream);
fis.close();
ostream.flush();
ostream.close();
return false; // We have taken care of file serving.
}
return true; // Let DefaultServlet handle file serving
}
public static String getGMTTimeString(long milliSeconds) {
SimpleDateFormat sdf = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'");
return sdf.format(new Date(milliSeconds));
}
public static void streamIO(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[2048];
int readlen = -1;
while ((readlen = is.read(bytes)) != -1) {
os.write(bytes, 0, readlen);
os.flush(); // Let us flush after bluk write
}
}
}
Se puderem me ajudar desde ja agradeço…
Cara fiz um esquema meio que manual e funcionou…
Caso alguem tenha solução melhor posta ai…
Resolução
no web.xml adicionei o filter
[code]
<filter>
<filter-name>filtro</filter-name>
<filter-class>control.cache.FiltrosResources</filter-class>
</filter>
<filter-mapping>
<filter-name>filtro</filter-name>
<url-pattern>/resource/css/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>filtro</filter-name>
<url-pattern>/resource/js/*</url-pattern>
</filter-mapping>
<!-- fim monitoramento -->[/code]
criei o filter dessa forma
package control.cache;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FiltrosResources implements Filter {
public void destroy() {
//System.out.println("--- > destroy");
}
public void init(FilterConfig config) throws ServletException {
//System.out.println("--- > init");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
String requestURI = request.getRequestURI();
String contextPath = request.getContextPath();
String fileURI = "";
if (requestURI.indexOf(contextPath) != -1) {
// Request URI is CONTEXTPATH + RESOURCE URI
fileURI = requestURI.substring(requestURI.indexOf(contextPath) + contextPath.length());
}
File file = new File(request.getSession().getServletContext().getRealPath(fileURI));
String lowerfile = file.getAbsolutePath().toLowerCase();
boolean isBasePath = "/".equalsIgnoreCase(fileURI);
boolean isJSFile = lowerfile.endsWith(".js");
boolean isCSSFile = lowerfile.endsWith(".css");
boolean customServing = (!isBasePath) && (isJSFile || isCSSFile);
if(customServing) {
String mimetype = request.getSession().getServletContext().getMimeType(fileURI);
response.setContentType(mimetype);
// Required Cache Control Headers
String maxage = "86400"; // One day in Seconds
response.setHeader("Cache-Control", "max-age="+ maxage);
long relExpiresInMillis = System.currentTimeMillis() + (1000 * Long.parseLong(maxage));
response.setHeader("Expires", getGMTTimeString(relExpiresInMillis));
response.setHeader("Last-Modified", getGMTTimeString(file.lastModified()));
// Serve the file content
FileInputStream fis = new FileInputStream(file);
OutputStream ostream = response.getOutputStream();
streamIO(fis, ostream);
fis.close();
ostream.flush();
ostream.close();
}
// Aqui é feito o redirecionamento normal, caso seja um arquivo
chain.doFilter(req,resp);
}
public static String getGMTTimeString(long milliSeconds) {
SimpleDateFormat sdf = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'");
return sdf.format(new Date(milliSeconds));
}
public static void streamIO(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[2048];
int readlen = -1;
while ((readlen = is.read(bytes)) != -1) {
os.write(bytes, 0, readlen);
os.flush(); // Let us flush after bluk write
}
}
}
Cara isso intercepta os arquivos e altera o response para retornar fazendo o que eu preciso, não interferio na funcionalidade do vraptor 3 nos testes iniciais…
caso alguem saiba de alguma forma melhor por favor posta ai!!!
vou deixar o topico em aberto por mais um tempo, valew…
Essa é uma boa forma sim…
a geração e compressão dos css e js não tem a ver com as funcionalidades do VRaptor, então implementar num filtro é ok.
Na verdade fiz assim…
Criei uma anotação onde eu digo quais os arquivos quero que envie para aquela view, esta anotação coloco sobre cada metodo e passo um array com os css e outro com os js.
Ai entra um interceptor que retornar para a view um link com cada um o css fica no topo para evitar o efeito flash na pagina e o js coloquei no final da pagina…
nesse interceptor ele também cria um arquivo unico com todos os css passados no array da anotação e outr com os js… e compressiona este arquivo sempre faz isso caso ele não exista…
O papel do Filter é apenas retornar no response o controle de cache dos arquivos retornados, a meta é tentar deixar a performance quanto melhor possivel…
Esta funcionando… acredito que seja uma boa pratica… caso eu estiver fazendo algo de errado por favor me avise kk…
Abraço e obrigado Lucas…