07【SpringMVC常用注解】


一、SpringMVC常用注解

搭建项目,引入Maven依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-api</artifactId>
        <version>8.5.41</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.18</version>
    </dependency>
</dependencies>
  • 实体类:
package com.dfbz.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class City {
    private Integer id;         // 城市id
    private String cityName;    // 城市名称
    private Double GDP;         // 城市GDP,单位亿元
    private Boolean capital;    // 是否省会城市
}
  • web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<filter>
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<!--拦截所有的请求,统一处理乱码问题-->
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--spring核心(前端控制器)-->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!--配置springmvc配置文件的位置-->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<!--只有*.form后缀的请求才会进入springmvc-->
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>
  • springmvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--扫描包-->
    <context:component-scan base-package="com.dfbz"/>
    
    <!--静态资源放行-->
    <mvc:default-servlet-handler/>
    
    <!--开启注解驱动-->
    <mvc:annotation-driven />
</beans>

1.1 @PathVariable

作用:用于接收Rest风格请求的路径参数;将方法形参和url 的占位符进行绑定;

  • 源码:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;
}
  • name/value:当url中的占位符和方法形参名称不一致时,可以使用name/value属性进行绑定;
  • required:是否必须提供占位符,默认为true;

  • 测试:
package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author lscl
 * @version 1.0
 * @intro: @PathVariable注解
 */
@Controller
@RequestMapping("/demo01")
public class Demo01Controller_PathVariable {

    @GetMapping("/{id}/{name}")
    public void test(
            @PathVariable Integer id,
            @PathVariable(value = "name") String cityName,                  // 把url上的name值赋值给cityName
            HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("id: "+id+"<hr />");
        response.getWriter().write("cityName: "+cityName+"<hr />");
    }

    @GetMapping("/{id}")
    public void test2(
            @PathVariable Integer id,
            @PathVariable(value = "aaa",required = false) String cityName,                  // 没有aaa占位符也没关系
            HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("id: "+id+"<hr />");
        response.getWriter().write("cityName: "+cityName+"<hr />");
    }

}

1.2 @RequestParam

作用:接收前端提交的参数(POST/GET提价都可以接收);当接收的参数的变量名与表单的name属性不一样时可以使用@RequestParam来绑定,同时可以封装其他类型的对象,如List、Set、Map

  • 源码:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
  • name/value:当前端传递的参数名称和方法形参名称不一致时,可以使用name/value属性进行绑定;
  • required:是否必须提供传递此参数,默认为true;
  • defaultValue:如果前端没有传递此参数,默认为defaultValue的值;

  • 测试:
package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @author lscl
 * @version 1.0
 * @intro: @RequestParam注解
 */
@Controller
@RequestMapping("/demo02")
public class Demo02Controller_RequestParam {

    @GetMapping("/demo01")
    public void demo01(Integer id,
                       @RequestParam("name") String cityName,                  // 将前端传递的name参数与cityName进行绑定(name参数必须传递)
                       HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("id: " + id + "<hr />");
        response.getWriter().write("cityName: " + cityName + "<hr />");
    }


    @GetMapping("/demo02")
    public void demo02(@RequestParam(required = false) Integer id,                       // id可以不传递
                       @RequestParam(defaultValue = "guangzhou") String cityName,        // cityName参数如果没有传递默认为guangzhou
                       HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("id: " + id + "<hr />");
        response.getWriter().write("cityName: " + cityName + "<hr />");
    }


    /**
     * map类型
     * @param maps
     * @param response
     * @throws IOException
     */
    @GetMapping("/demo03")
    public void demo03(@RequestParam Map<String, Object> maps,
                       HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("id: " + maps.get("id") + "<hr />");
        response.getWriter().write("cityName: " + maps.get("cityName") + "<hr />");
    }

    /**
     * List类型
     * @param ids
     * @param response
     * @throws IOException
     */
    @PostMapping("/demo04")
    public void demo04(@RequestParam("ids") List<Integer> ids,
                       HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("id: " + ids.toString() + "<hr />");
    }
}

1.3 @CookieValue

作用:获取Cookie中的数据

  • 源码:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CookieValue {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
  • name/value:Cookie中的参数名称和方法形参名称不一致时,可以使用name/value属性进行绑定;
  • required:是否必须提供此参数Cookie参数,默认为true;
  • defaultValue:如果Cookie中没有此参数,默认为defaultValue的值;

  • 测试:
package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author lscl
 * @version 1.0
 * @intro: @CookieValue
 */
@Controller
@RequestMapping("/demo03")
public class Demo03Controller_CookieValue {

    @GetMapping("/demo01")
    public void demo01(@CookieValue String JSESSIONID,
                       HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("JSESSIONID: " + JSESSIONID + "<hr />");
    }
}

1.4 @RequestHeader

作用:获取请求头中的数据

  • 源码:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestHeader {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
  • 测试代码:
package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author lscl
 * @version 1.0
 * @intro: @RequestHeader
 */
@Controller
@RequestMapping("/demo04")
public class Demo04Controller_RequestHeader {

    @GetMapping("/demo01")
    public void demo01(@RequestHeader String Host,
                       HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("Host: " + Host + "<hr />");
    }
}

1.5 @SessionAttribute

作用:从session中获取一个值封装到参数中

  • 源码:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SessionAttribute {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;
}
  • 测试代码:
package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttribute;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author lscl
 * @version 1.0
 * @intro: @SessionAttribute
 */
@Controller
@RequestMapping("/demo05")
public class Demo05Controller_SessionAttribute {

    @GetMapping("/demo01")
    public String demo01(HttpSession session) throws IOException {

        session.setAttribute("loginUser", "zhangsan");

        return "/demo05/demo02";
    }

    /**
     * 从session中取出loginUser(必须要有这个属性)
     * @param loginUser
     * @param response
     * @throws IOException
     */
    @GetMapping("/demo02")
    public void demo02(@SessionAttribute String loginUser,
                       HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");
        response.getWriter().write("loginUser: " + loginUser + "<hr />");
    }
}

1.6 @SessionAttributes

作用:把BindingAwareModelMap中的指定的key或者指定的属性的值也存入一份进session域

tips:@SessionAttributes注解并不能把存入request域的值也存入session中

  • 源码:
@Target({ElementType.TYPE})		// 标注在类上的
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SessionAttributes {
    @AliasFor("names")
    String[] value() default {};

    @AliasFor("value")
    String[] names() default {};

    Class<?>[] types() default {};
}
  • 测试代码:
package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

/**
 * @author lscl
 * @version 1.0
 * @intro: @SessionAttributes
 */

// 把BindingAwareModelMap中的username属性和所有的Integer类型的属性都存入一份在session中
@SessionAttributes(value = {"username"}, types = {Integer.class})
@Controller
@RequestMapping("/demo06")
public class Demo06Controller_SessionAttributes {

    @GetMapping("/demo01")
    public String demo01(Map<String, Object> map, HttpServletRequest request) throws IOException {

        map.put("username", "admin");
        map.put("password", "123");
        map.put("age", 23);
        map.put("tall", 1.78);

        // 存入request域的值不能被存入session
        request.setAttribute("test",111);

        return "/demo06/demo02";
    }


    @GetMapping("/demo02")
    public void demo02(HttpSession session, HttpServletResponse response) throws IOException {

        response.setContentType("text/html;charset=utf8");

        response.getWriter().write("username: " + session.getAttribute("username") + "<hr />");
        response.getWriter().write("password: " + session.getAttribute("password") + "<hr />");
        response.getWriter().write("age: " + session.getAttribute("age") + "<hr />");
        response.getWriter().write("tall: " + session.getAttribute("tall") + "<hr />");
        response.getWriter().write("test: " + session.getAttribute("test") + "<hr />");
    }
}

1.7 @RequestAttribute

作用:获取request域中的数据;

测试代码:

package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
@Controller
@RequestMapping("/demo07")
public class Demo07Controller_RequestAttribute {


    @GetMapping("/demo01")
    public String demo01(Model model) throws IOException {

        // 在请求域中添加几个属性
        model.addAttribute("username", "zhangsan");
        model.addAttribute("password", "123");

        return "/demo07/demo02";
    }

    @GetMapping("/demo02")
    public void demo02(
                        @RequestAttribute("username") String name,      // 获取请求域中的username属性值
                        @RequestAttribute String password,              // 获取请求域中password属性值
                        HttpServletResponse response
    ) throws IOException {

        response.getWriter().println("username: "+name);
        response.getWriter().println("password: "+password);
    }
}

1.8 @ModelAttribute

作用:@ModelAttribute注解可以作用于方法和参数上

  • 作用于方法上:在执行Controller其他所有方法之前执行@ModelAttribute注解标注的方法

  • 作用于参数上:获取ModelAttribute标注的方法中BingMap中的某个值到某个属性到形参上,并且此次的BingMap会传递到下一个handler方法;BingMap中的值以前端传递的为准,如果前端传递了参数则以前端为准,如果没有传递参数则保持@ModelAttribute标注方法中的默认值;

  • 源码:

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean binding() default true;
}
  • 测试代码:
package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @author lscl
 * @version 1.0
 * @intro: @ModelAttribute注解作用与方法上
 */
@Controller
@RequestMapping("/demo08")
public class Demo08Controller_ModelAttribute {
    @ModelAttribute
    public void model(Model model, ModelMap modelMap, Map map) {
        model.addAttribute("username", "zhangsan");
        modelMap.addAttribute("password", "admin");
        map.put("email","zhangsan@qq.com");
    }

    @RequestMapping("/demo01")
    public void demo01(
            @ModelAttribute("username") String username,            // 注意: 形参名和BindingMap中的key一样也要写
            @ModelAttribute("password") String password,
            @ModelAttribute("email") String email,
            HttpServletResponse response
    ) throws Exception {

        response.getWriter().println("username: " + username);
        response.getWriter().println("password: " + password);
        response.getWriter().println("email: " + email);
    }
}

Tips:@ModelAttribute只能获取BingMap中的数据,不能获取request中的数据;

应用场景:现在需要修改一个City信息,有某些应用信息前端不提交(默认为null),

  • 表单:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/demo08/demo01">
    城市ID:<input type="text" name="id">
    城市名称:<input type="text" name="cityName">
    GDP:<input type="text" name="GDP">
    是否省会:<input type="text" name="capital">

    <input type="submit">
</form>
</body>
</html>

  • Controller:
package com.dfbz.controller;

import com.dfbz.entity.City;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.IOException;
import java.util.Map;

/**
 * @author lscl
 * @version 1.0
 * @intro: @ModelAttribute注解作用与方法上
 */
@Controller
@RequestMapping("/demo09")
public class Demo09Controller_ModelAttribute02 {
    /**
     * ModelAttribute标注的方法在所有的handler方法之前执行
     *
     * @param maps
     * @throws IOException
     */
    @ModelAttribute
    public void model(Map<String, Object> maps) throws IOException {

        maps.put("city", new City(1, "南宁", 4700.00, true));
        System.out.println("model方法执行了...");
    }

    @RequestMapping("/demo01")
    public void demo01(@ModelAttribute("city") City city, HttpServletResponse response) throws Exception{        // 如果前端没有传递则以@ModelAttribute标注的为准,如果传递了则以前端参数为准

        response.setContentType("text/html;charset=utf8");
        response.getWriter().println(city);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

緑水長流*z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值