Emilio Ponce
Spring consulta web.xml donde está definido el DispatcherServlet y le hace llegar la petición entrante.
Spring empieza a ejecutar la cadena de Interceptores. Métodos preHandle.
Pasa luego a controlador correspondiente.
Ejecuta métodos postHandle de interceptores.
Encuentra vista correspondiente con View Resolver, envía el modelo a la vista y la renderiza.
Cadena!
Parte de Spring MVC
Intercepta una petición HTTP (req, res)
org.springframework.web.servlet.HandlerInterceptor
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
En contexto de Spring MVC (nombreAplicacion-servlet.xml):
Implementando la interfaz:
Extendiendo la clase abstracta:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean id="profileInterceptor"
class="cat.meteo.webescriptori.controller.ProfileInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
Implementando la interfaz:
javax.servlet.Filter
Y sobreescribiendo método doFilter() que se ejecuta con cada petición
Para tareas parecidas a los interceptores
<filter>
<filter-name>AutenticacionFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>AutenticacionFilter</filter-name>
<url-pattern>/usuarios/*</url-pattern>
</filter-mapping>
<bean id="AutenticacionFilter"
class="cat.meteo.webescriptori.controller.AutenticacionFilter">
I1
I2
I3
I3
I2
I1
preHandle
preHandle
preHandle
postHandle
postHandle
postHandle
Controller
D
I
S
P
A
T
C
H
E
R
S
E
R
V
L
E
T
C
H
A
I
N
Filter
Request
Chain
Chain
Service ...
Filter
Response
Aplicación fija max-age para Varnish:
Cómo detectar un error de componente dentro de una sección?
Código de error dentro de HTML de respuesta, para que un FILTRO lo pueda detectar.
<filter>
<filter-name>MaxAgeFilter</filter-name>
<!-- delega en el MaxAgeFilter definit al context de l'aplicació -->
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!-- especifiquem per a que urls s'executa filtre que baixa MaxAge -->
<filter-mapping>
<filter-name>MaxAgeFilter</filter-name>
<url-pattern>/</url-pattern>
<url-pattern>/observacions/*</url-pattern>
<url-pattern>/prediccio/*</url-pattern>
</filter-mapping>
web.xml
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean id="webContentInterceptor"
class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<property name="cacheSeconds" value="600" />
<property name="useExpiresHeader" value="false" />
<property name="useCacheControlHeader" value="true" />
<property name="useCacheControlNoStore" value="false" />
<property name="cacheMappings">
<props>
<prop key="/*">600</prop>
</props>
</property>
</bean>
</mvc:interceptor>
webescriptori-servlet.xml
<!-- Afegim filtre al Context -->
<bean id="MaxAgeFilter" class="cat.meteo.webescriptori.controller.MaxAgeFilter">
<property name="errorCacheTime" value="120"/>
<property name="cadenaError" value="(╯°□°)╯︵ ┻━┻ error!"/>
</bean>
applicationContext.xml
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!--(╯°□°)╯︵ ┻━┻ error!-->
<div class="errorpage">
<h1>Uups! S'ha produït un error</h1>
<p>En aquests moments no podem mostrar la informació
sol·licitada. Torna-ho a intentar d'aquí a uns minuts.</p>
<p>Disculpa les molèsties.</p>
</div>
errorcomponent.jsp
// FILTER
public class MaxAgeFilter implements Filter {
...
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
// fiquem response a un wrapper i apliquem filtre per poder extreure html
HttpServletResponse response = (HttpServletResponse) res;
MyHttpServletResponseWrapper wrapper = new MyHttpServletResponseWrapper(response);
// ejecuta filtro que almacena respuesta en wrapper, que tiene el método
// toString sobreescrito
chain.doFilter(req, wrapper);
// si a la resposta hi ha algun error canviem capçalera MaxAge
String contingut = wrapper.toString();
if (contingut.contains(cadenaError)) {
response.setHeader("Cache-Control", "max-age=" + errorCacheTime);
}
// escribimos output de res en navegador (renderizamos con PrintWriter original)
try (PrintWriter out = response.getWriter()) {
out.println(contingut);
} catch (IOException ex) {
log.error("error a filtre MaxAgeFilter", ex);
}
}
}
MaxAgeFilter.java
class MyHttpServletResponseWrapper extends HttpServletResponseWrapper {
private final StringWriter sw = new StringWriter();
...
@Override
public PrintWriter getWriter() throws IOException {
// sobreescribimos printWriter para que guarde en String
// y no en ouputStream (no renderiza! en navegador)
return new PrintWriter(sw);
}
...
@Override
public String toString() {
return sw.toString();
}
}
MaxAgeFilter.java