Skip to content

Commit 04508e1

Browse files
committed
Mas documentación
1 parent c30c974 commit 04508e1

File tree

3 files changed

+128
-9
lines changed

3 files changed

+128
-9
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ HELP.md
1818
*.ipr
1919

2020
### NetBeans ###
21-
/nbactions
21+
/nbactions.xml
2222
/nbproject/private/
2323
/nbbuild/
2424
/dist/

nbactions.xml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<actions>
33
<action>
4-
<actionName>run</actionName>
4+
<actionName>debug</actionName>
55
<packagings>
66
<packaging>jar</packaging>
77
</packagings>
@@ -10,8 +10,9 @@
1010
<goal>org.codehaus.mojo:exec-maven-plugin:1.5.0:exec</goal>
1111
</goals>
1212
<properties>
13-
<exec.args>-classpath %classpath com.profesorp.filtros.FiltrosApplication</exec.args>
13+
<exec.args>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath com.profesorp.filtros.FiltrosApplication</exec.args>
1414
<exec.executable>java</exec.executable>
15+
<jpda.listen>true</jpda.listen>
1516
</properties>
1617
</action>
1718
</actions>

readme.md

+124-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Como siempre, como mejor se entiende un concepto es realizando un programa y exp
66

77
En el programa de ejemplo tenemos un controlador para peticiones REST en la clase `PrincipalController.java` que será el encargado de gestionar todas las peticiones.
88

9-
Este es parte del código de la clase.
9+
Este es el código de la clase:
1010

1111
```java
1212
@RestController
@@ -36,11 +36,38 @@ public class PrincipalController {
3636
return "returning by function entryOne\r\n"+
3737
sillyLog.getMessage();
3838
}
39-
.....
39+
@GetMapping("two")
40+
public String entryTwo(HttpServletResponse response)
41+
{
42+
sillyLog.debug("In entryTwo");
43+
if (response.getHeader("PROFE")!=null)
44+
sillyLog.debug("Header contains PROFE: "+response.getHeader("PROFE"));
45+
return "returning by function entryTwo\r\n"+
46+
sillyLog.getMessage();
47+
}
48+
@GetMapping("three")
49+
public String entryThree()
50+
{
51+
sillyLog.debug("In entryThree");
52+
return "returning by function entryThree\n"+
53+
sillyLog.getMessage();
54+
}
55+
@GetMapping("redirected")
56+
public String entryRedirect(HttpServletRequest request)
57+
{
58+
sillyLog.debug("In redirected");
59+
return "returning by function entryRedirect\n"+
60+
sillyLog.getMessage();
61+
}
62+
}
4063
```
4164

4265
En la función `entryOther` se capturaran todas las peticiones tipo **GET** que vayan a alguna URI que no tengamos definidas explícitamente. En la función `entryOne` se procesaran las peticiones tipo **GET** que vayan a la URL http://localhost:8080/one o http://localhost:8080/
4366

67+
La clase `sillyLog` es una clase donde simplemente iremos añadiendo líneas de log para luego devolverlas en la petición, de tal manera que podremos ver por donde ha pasado nuestra petición.
68+
69+
En esta aplicación se definen dos filtros: `MyFilter.java` y `OtherFilter.java`. El primero tiene preferencia sobre el segundo, por estar así establecido en el parámetro de la etiqueta **@Order**.
70+
4471
En el fichero `MyFilter.java` definimos nuestro primer filtro.
4572

4673
```java
@@ -63,6 +90,12 @@ public class MyFilter implements Filter{
6390
chain.doFilter(httpRequest, myResponse);
6491
return;
6592
}
93+
if (httpRequest.getRequestURL().toString().endsWith("/none")) {
94+
myResponse.setStatus(HttpStatus.BAD_GATEWAY.value());
95+
myResponse.getOutputStream().flush();
96+
myResponse.getOutputStream().println("-- I don't have any to tell you --");
97+
return; // No hago nada.
98+
}
6699
if (httpRequest.getRequestURL().toString().endsWith("/redirect")) {
67100
myResponse.addHeader("PROFE", "REDIRECTED");
68101
myResponse.sendRedirect("redirected");
@@ -82,11 +115,36 @@ public class MyFilter implements Filter{
82115
}
83116
```
84117

85-
Lo primero que tenemos que hacer para definir un filtro *general* es etiquetar la clase con **@Component** . Después deberemos implementar el interface `Filter` . También podríamos extender de la clase `OncePerRequestFilter` la cual implementa el interface `Filter` pero añade ciertas funcionalidades para que un filtro solo se ejecute una vez por ejecución. En este ejemplo vamos a simplificarlo al maximo y directamente implementaremos el interface `Filter`.
118+
La clase `OtherFilter` es más simple:
86119

87-
El interface `Filter` define tres funciones.
120+
```java
121+
@Component
122+
@Order(2)
123+
public class OtherFilter implements Filter{
124+
@Autowired
125+
SillyLog sillyLog;
126+
127+
@Override
128+
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
129+
HttpServletRequest httpRequest= (HttpServletRequest) request;
130+
HttpServletResponse myResponse= (HttpServletResponse) response;
131+
sillyLog.debug("OtherFilter: URL"
132+
+ " called: "+httpRequest.getRequestURL().toString());
133+
if (myResponse.getHeader("PROFE")!=null)
134+
{
135+
sillyLog.debug("OtherFilter: Header contains PROFE: "+myResponse.getHeader("PROFE"));
136+
}
137+
chain.doFilter(request, response);
138+
}
88139

89-
- `void init(FilterConfig filterConfig) throws ServletException`
140+
}
141+
```
142+
143+
Lo primero que tenemos que hacer para definir un filtro *general* es etiquetar la clase con **@Component** . Después deberemos implementar el interface `Filter` . También podríamos extender de la clase `OncePerRequestFilter` la cual implementa el interface `Filter` pero añade ciertas funcionalidades para que un filtro solo se ejecute una vez por ejecución. En este ejemplo vamos a simplificarlo al máximo y directamente implementaremos el interface `Filter`.
144+
145+
El interface `Filter` tiene tres funciones.
146+
147+
- `void init(FilterConfig filterConfig) throws ServletException`
90148

91149
Esta función será ejecutada por el contenedor web. En otras palabras: esta función solo es ejecutada una vez, cuando el componente es instanciado por **Spring**.
92150

@@ -98,7 +156,67 @@ El interface `Filter` define tres funciones.
98156

99157
Esta función es llamada por el contenedor web de Spring para indicarle al filtro, que va a dejar de estar activo.
100158

101-
En el código del ejemplo nosotros solo utilizaremos la función `doFilter`
159+
Como he comentado anteriormente, la etiqueta **@Order** nos permitirá especificar el orden en que los filtros serán ejecutados. En este caso, este filtro tendrá el valor 1 y el siguiente tendrá el valor 2, por lo cual `MyFilter` se ejecutara antes que `OtherFilter`
160+
161+
La clase `MyFilter` realiza diferentes acciones según la URL llamada. La clase `OtherFilter `solamente añade un log cuando pasa por ella.
162+
163+
En el código del ejemplo nosotros solo utilizamos la función `doFilter`. En ella, lo primero, convertimos la clase `ServletResponse` a `HttpServletResponse` y la clase `ServletRequest` a `HttpServletRequest`. Esto es necesario para poder acceder a ciertas propiedades de los objetos que de otra manera no estarían disponibles.
164+
165+
Voy a explicar paso a paso los diferentes casos contemplados en la clase `MyFilter`, dependiendo de la URL invocada.
166+
167+
- **/one**: Añadimos una cabecera **PROFE** con el valor **FILTERED**. Después ejecutamos la función `doFilter`de la clase `chain` con lo cual se continuara el flujo de la petición. Es decir, se ejecutaría el segundo filtro y después llegaría a la función `entryOne` del controlador, donde podríamos ver que existe un *header* con el valor PROFE, por lo cual se llama a la función entryTwo.
168+
169+
Una llamada a esta URL nos devolvería lo siguiente:
170+
171+
```
172+
> curl -s http://localhost:8080/one
173+
returning by function entryTwo
174+
SillyLog: 15eb34c2-cfac-4a27-9450-b3b07f44cb50/1 Filter: URL called: http://localhost:8080/one
175+
SillyLog: 15eb34c2-cfac-4a27-9450-b3b07f44cb50/2 OtherFilter: URL called: http://localhost:8080/one
176+
SillyLog: 15eb34c2-cfac-4a27-9450-b3b07f44cb50/3 OtherFilter: Header contains PROFE: FILTERED
177+
SillyLog: 15eb34c2-cfac-4a27-9450-b3b07f44cb50/4 In entryOne
178+
SillyLog: 15eb34c2-cfac-4a27-9450-b3b07f44cb50/5 Header contains PROFE: FILTERED
179+
SillyLog: 15eb34c2-cfac-4a27-9450-b3b07f44cb50/6 In entryTwo
180+
SillyLog: 15eb34c2-cfac-4a27-9450-b3b07f44cb50/7 Header contains PROFE: FILTERED
181+
182+
```
183+
184+
La primera línea es devuelta por la función `entryTwo`. A continuación se muestran los logs añadidos.
185+
186+
Creo que si se mira el código se ve claro el flujo.
187+
188+
- **/redirect** Añadimos una cabecera **PROFE** con el valor **REDIRECTED**. Después especificamos que se debe incluir una redireción a la URL `redirected` con la instrucción `sendRedirect`. Después ejecutamos la función `doFilter` por lo cual se procesara el segundo filtro y se llamara a la función `entryOther` ya que no tenemos ningún punto de entrada definido para */cancel*.
189+
190+
191+
192+
- **/none** . Establezco el código HTTP a devolver a BAD_GATEWAY y en el cuerpo pongo el texto *"I don't have any to tell you"*. No ejecuto la función `doFilter` por lo cual ni será llamado el segundo filtro, ni seria invocada ninguna llamada del Controlador en caso de que existiera alguno.
193+
194+
```curl
195+
> curl -s http://localhost:8080/none
196+
-- I don't have any to tell you --
197+
```
198+
199+
- **/cancel** . Establezco el código HTTP a devolver a BAD_REQUEST y en el cuerpo pongo el texto *"Output by filter error"*. Ejecuto la función `doFilter` por lo cual será ejecutado el filtro `OtherFilter` y se pasara por la función `entryOther` ya que no tenemos ningún punto de entrada definido para */cancel*
200+
201+
```curl
202+
> curl -s http://localhost:8080/cancel
203+
-- Output by filter error --
204+
returning by function entryOther
205+
SillyLog: 1cf7f7f9-1a9b-46a0-9b97-b8d5caf734bd/1 Filter: URL called: http://localhost:8080/cancel
206+
SillyLog: 1cf7f7f9-1a9b-46a0-9b97-b8d5caf734bd/2 OtherFilter: URL called: http://localhost:8080/cancel
207+
SillyLog: 1cf7f7f9-1a9b-46a0-9b97-b8d5caf734bd/3 OtherFilter: Header contains PROFE: CANCEL
208+
SillyLog: 1cf7f7f9-1a9b-46a0-9b97-b8d5caf734bd/4 In entryOther
209+
SillyLog: 1cf7f7f9-1a9b-46a0-9b97-b8d5caf734bd/5 Header contains PROFE: CANCEL
210+
211+
```
212+
213+
Observar que el cuerpo añadido en el filtro es anterior a lo devuelto por el controlador.
214+
215+
-
216+
217+
218+
219+
102220

103221

104222

0 commit comments

Comments
 (0)