Anotaciones de Spring: @RequestMapping y sus variantes

    Introducci贸n

    Si has le铆do algo sobre Spring, desarroll贸 un proyecto, o incluso estaba interesado remotamente en c贸mo funciona, se le present贸 la @RequestMapping anotaci贸n.

    Es una de las anotaciones b谩sicas en Spring que asigna solicitudes HTTP (URL) con m茅todos:

    @RequestMapping("/")
    public void helloWorld() {
        return "Hello World!";
    }
    

    Nos permite ejecutar m茅todos y fragmentos de c贸digo cada vez que el usuario final llega a un punto final con una solicitud HTTP. En este caso, es una asignaci贸n de ra铆z simple que devuelve la cadena “隆Hola mundo!” cuando se alcanza el punto final ra铆z.

    La anotaci贸n @RequestMapping

    los @RequestMapping la anotaci贸n en s铆 ofrece m谩s de lo que se muestra en el ejemplo anterior. Cubramos brevemente algunos de los casos de uso b谩sicos de la anotaci贸n.

    @RequestMapping alcances

    El mapeo se puede asignar a nivel de clase o de m茅todo:

    @RequestMapping("/admin")
    public class AdminController() {
        @RequestMapping("/adminPanel")
        public String adminPanel() {
            return "adminPanel.html";
        }
    
        @RequestMapping("/statistics")
        public String statistics() {
            return "statistics.html";
        }
    }
    

    Aqu铆 el /admin El mapeo se asigna a nivel de clase, mientras que el /adminPanel y /statistics las asignaciones se asignan a los m茅todos. El mapeo a nivel de clase se utilizar谩 como prefijo para todos estos mapeos a nivel de m茅todo: /admin/adminPanel y /admin/statistics.

    De esta manera, podemos segregar nuestra aplicaci贸n en partes l贸gicas. Por ejemplo, toda la l贸gica relacionada con el administrador estar谩 detr谩s del /admin muro, al que solo pueden ingresar los usuarios administradores. Todos los usuarios que no sean administradores ser谩n redirigidos al lado del cliente de la aplicaci贸n.

    Varias asignaciones por m茅todo

    Si es necesario, podemos asignar m煤ltiples asignaciones a un solo m茅todo, como:

    @RequestMapping("/", "/index", "/home")
    public void helloWorld() {
        return "Hello World!";
    }
    

    Si llega a cualquiera de estos puntos finales, helloWorld() m茅todo de manejo de nuestra solicitud.

    M茅todos de solicitud

    El atributo m谩s com煤n utilizado es el method atributo que nos permite especificar y acotar el m茅todo de solicitud que maneja nuestro m茅todo (GET, POST, DELETE, etc.):

    @RequestMapping(value = "/addProduct", method = RequestMethod.POST)
    public String addProductPost(@ModelAttribute("product") Product product) {
        // some code
    }
    

    Si no especificamos un m茅todo de solicitud, el m茅todo de solicitud predeterminado es GET.

    Solicitar encabezados

    Podemos especificar a煤n m谩s el mapeo definiendo uno o m谩s encabezados. En este caso, el helloWorld() El m茅todo manejar谩 la solicitud si su content-type es text/plain o text/html:

    @RequestMapping(value = "/header", headers = {"content-type=text/plain", "content-type=text/html"})
    String helloWorld() {
        return "Hello World!";
    }
    

    Variables de ruta

    Muchos sitios web se basan en variables de ruta para mostrar un producto, p谩gina, perfil, etc. espec铆ficos al usuario final, como example.com/viewProduct/324, d贸nde 324 es el ID del producto:

    @RequestMapping("/viewProduct/{productId}")
    public String viewProduct(@PathVariable int productId, Model model) {
        Product product = productService.getProductById(productId);
        model.addAttribute("product", product);
    
        return "viewProduct";
    }
    

    Aqu铆, despu茅s del mapeo, encerramos la variable de ruta con llaves ({}) y asignar ese valor a nuestro productId. los @PathVariable la anotaci贸n se encarga de esto por nosotros. Entonces, podemos encontrar el producto a trav茅s de nuestro ProductService y mostrarlo al usuario final.

    Por supuesto, el mismo enfoque se puede utilizar para otras variables como:

    @RequestMapping("/users/{username}")
    public String viewUser(@PathVariable("username") String username) {
        Profile profile = profileService.getProfileByUsername(username);
        // rest of the code
    }
    

    Solicitar par谩metros

    Muy similar a las variables de ruta, muchas aplicaciones se basan en par谩metros de solicitud para alterar el estado de la p谩gina. Podemos usar el @RequestParam anotaci贸n para vincular un par谩metro de solicitud a una variable:

    @RequestMapping("/login")
    public String login(@RequestParam(value = "error", required = false) String error, @RequestParam(value = "logout", required = false) String logout, Model model) {
    
        if (error != null) {
            model.addAttribute("error", "Wrong username or password!");
        }
        if (logout != null) {
            model.addAttribute("msg", "You have successfully logged out!");
        }
        return "login";
    }
    

    Producible y consumible

    Utilizando la @RequestMapping anotaci贸n, tambi茅n podemos producir o consumir tipos de medios. Para producir un tipo de medio como “JSON”, puede utilizar el produces atributo junto al @ResponseBody anotaci贸n, mientras que para consumir un tipo de medio puede utilizar la consumes atributo:

    @RequestMapping("/annotations")
    public class SomeController {
        @RequestMapping(value = "/produce", produces = {"application/json"})
        @ResponseBody
        String produces() {
            return "Here's how you use the 'produces' attribute";
        }
    
        @RequestMapping(value = "/consume", consumes = {"application/JSON", "application/XML"})
        String consume() {
            return "Here's how you use a 'consume' attribute";
        }
    }
    

    Variantes de @RequestMapping compuestas

    Una 煤nica asignaci贸n puede corresponder a diferentes m茅todos si nos aseguramos de que no haya ambig眉edad en cuanto a qu茅 m茅todo debe manejar qu茅 versi贸n de la asignaci贸n.

    Podemos tener varios m茅todos con el mismo mapeo si su m茅todo de solicitud es diferente:

    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }
    
    @RequestMapping(value = "/hello", method = RequestMethod.POST)
    public String helloPost() {
        return "hello post";
    }
    
    @RequestMapping(value = "/hello", method = RequestMethod.PUT)
    public String helloGet() {
        return "hello put";
    }
    
    @RequestMapping(value = "/hello", method = RequestMethod.DELETE)
    public String helloDelete() {
        return "hello delete";
    }
    

    Este mismo m茅todo tiene 4 variaciones diferentes:

    • Predeterminado (GET)
    • ENVIAR
    • PONER
    • ELIMINAR

    Con m谩s variaciones, la legibilidad del c贸digo se reduce y, honestamente, esto ya es detallado para un mapeo simple. Las asignaciones de solicitudes en aplicaciones m谩s grandes pueden volverse muy complejas y complicadas, y queremos que sean m谩s simples y legibles.

    Para ello, se nos presentan varias anotaciones nuevas, las @RequestMapping variantes:

    • @GetMapping
    • @PostMapping
    • @DeleteMapping
    • @PutMapping
    • @PatchMapping

    Hay literalmente versiones de acceso directo para las asignaciones anteriores donde @PostMapping("/hello") es igual a @RequestMapping(value="/hello", RequestMethod.POST).

    Al observar m谩s de cerca c贸mo se definen estas anotaciones, podemos tener una idea clara de lo que hacen:

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @RequestMapping(method = RequestMethod.GET)
    public @interface GetMapping {
    
        @AliasFor(annotation = RequestMapping.class)
        String name() default "";
    
        @AliasFor(annotation = RequestMapping.class)
        String[] value() default {};
    
        @AliasFor(annotation = RequestMapping.class)
        String[] path() default {};
    
        @AliasFor(annotation = RequestMapping.class)
        String[] params() default {};
    
        @AliasFor(annotation = RequestMapping.class)
        String[] headers() default {};
    
        @AliasFor(annotation = RequestMapping.class)
        String[] produces() default {};
    }
    

    Dicho esto, podemos reescribir los ejemplos anteriores:

    @GetMapping
    public String hello() {
        return "hello";
    }
    
    @PostMapping
    public String helloPost() {
        return "hello post";
    }
    
    @PutMapping
    public String helloGet() {
        return "hello put";
    }
    
    @DeleteMapping
    public String helloDelete() {
        return "hello delete";
    }
    

    Como esta es una forma m谩s simple, m谩s legible y m谩s nueva de escribir anotaciones, generalmente se prefiere escribirlas as铆. Si es necesario, puede definir cualquier otro atributo, como el value, params, pathetc.

    Conclusi贸n

    @RequestMapping es una anotaci贸n por excelencia en el marco de Spring que nos permite mapear solicitudes HTTP con m茅todos que deseamos ejecutar.

    A partir de Spring 4.3, se recomienda y se recomienda utilizar los accesos directos creados para esta anotaci贸n para obtener una base de c贸digo m谩s legible y menos detallada.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *