Spring 3 MVC accediendo a HttpRequest desde el controlador

104

Me gustaría manejar la solicitud y los atributos de sesión yo mismo en lugar de dejarlo en primavera @SessionAttributes, por ejemplo, para iniciar sesión en el manejo de cookies.

Simplemente no puedo entender cómo podría acceder HttpRequestdesde dentro de un controlador, necesito una forma de ir a una capa por encima @RequestAttributey acceder al HttpRequestmismo. Con Stripes se usa para hacer esto implementando un ApplicationContexty llamando getAttribute().

Además, pasar el HttpServletRequestparámetro as parece no funcionar:

@RequestMapping(value="/") public String home(HttpServletRequest request){
    System.out.println(""+request.getSession().getCreationTime());
    return "home"; 
}

El método anterior no imprime nada.

¿Tiene algún consejo sobre esto?

JBoy
fuente

Respuestas:

184

Spring MVC le dará el HttpRequest si lo agrega a la firma del método de su controlador:

Por ejemplo:

/**
 * Generate a PDF report...
 */
@RequestMapping(value = "/report/{objectId}", method = RequestMethod.GET)
public @ResponseBody void generateReport(
        @PathVariable("objectId") Long objectId, 
        HttpServletRequest request, 
        HttpServletResponse response) {

    // ...
    // Here you can use the request and response objects like:
    // response.setContentType("application/pdf");
    // response.getOutputStream().write(...);

}

Como puede ver, simplemente agregar los objetos HttpServletRequesty HttpServletResponsea la firma hace que Spring MVC pase esos objetos a su método de controlador. También querrás el HttpSessionobjeto.

EDITAR: Parece que HttpServletRequest / Response no funciona para algunas personas en Spring 3. Intente usar objetos Spring WebRequest / WebResponse como señaló Eduardo Zola.

Le recomiendo encarecidamente que eche un vistazo a la lista de argumentos admitidos que Spring MVC puede inyectar automáticamente por arte de magia a sus métodos de manejo.

jjmontes
fuente
Hola, gracias por las sugerencias, no sé qué estoy haciendo mal pero esto no funciona: no imprime nada: @RequestMapping (value = "/") public String home (HttpServletRequest request) {System.out. println ("" + request.getSession (). getCreationTime ()); volver a casa"; } Esto debería pringar la cantidad actual pof millis pero no lo hace, también anotar el método con @RequestBody no cambia nada, ¿algún otro consejo? gracias por esto
JBoy
2
¡Gracias @jjmontes por el enlace a los argumentos compatibles de Spring MVC!
Barett
No sé casi nada sobre Spring, pero tuve que agregar la @Contextanotación antes del argumento para inyectarlos. Podría ser algo nuevo, no lo sé, pero pensé en mencionarlo.
ivarni
81

Sé que es una vieja pregunta, pero ...

También puedes usar esto en tu clase:

@Autowired
private HttpServletRequest context;

Y esto proporcionará la instancia actual de HttpServletRequestpara que use en su método.

Deividi Cavarzan
fuente
7
¿Hacerlo de esta manera no evita que el bean controlador sea un singleton?
jjmontes
2
Los controladores de resorte son siempre singletons.
Deividi Cavarzan
16
Esto se siente mal: ¿qué pasa si el controlador está manejando más de una solicitud en un momento dado? Entonces, ¿cuál es la solicitud "actual"?
sbk
2
Esta pregunta tiene algunas explicaciones sobre lo que está pidiendo: stackoverflow.com/questions/17235794/…
Deividi Cavarzan
1
Sería bastante útil tener algo como getThreadLocalRequest()en GWT RemoteServiceServletque siempre devuelva la solicitud correcta incluso si se ejecuta en un entorno altamente concurrente.
Yuriy Nakonechnyy
0
@RequestMapping(value="/") public String home(HttpServletRequest request){
    System.out.println("My Attribute :: "+request.getAttribute("YourAttributeName"));
    return "home"; 
}
SaiSudha HG
fuente