目录

常用注解

常用注解

RequestMapping注解

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";

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

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

    RequestMethod[] method() default {};

    String[] params() default {}; // 必须要传入哪些参数和值,否则报400

    String[] headers() default {}; // 发送的请求中必须包括这些请求头

    String[] consumes() default {};

    String[] produces() default {};
}

RequestParam

作用:把请求中指定名称的参数给控制器中的形参赋值。

属性

  • value:请求参数中的名称。
  • required:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。

演示

1
2
3
4
5
6
@RequestMapping("/useRequestParam")
public String useRequestParam(@RequestParam("name") String username,
                              @RequestParam(value = "age", required = false) Integer age) {
    System.out.println(username + "," + age);
    return "success";
}

RequestBody

作用:用于获取请求体内容。直接使用得到是 key=value&key=value…结构的数据。注意get 请求方式不适用。

属性

  • required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false,get 请求得到是 null。

演示

1
2
3
4
5
@RequestMapping("/useRequestBody")
public String useRequestBody(@RequestBody(required=false) String body){
    System.out.println(body);
    return "success";
}

PathVariable

作用:用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。

属性

  • value:用于指定 url 中占位符名称。
  • required:是否必须提供占位符。

演示

1
2
3
4
5
@RequestMapping("/usePathVariable/{id}")
public String usePathVariable(@PathVariable("id") Integer id){
    System.out.println(id);
    return "success";
}

HiddenHttpMethodFilter

作用:由于浏览器 form 表单只支持 GET 与 POST 请求,而 DELETE 、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器, 可以将浏览器请求改为指定的请求方式,发送给我们的控制器方法 ,使得支持 GET 、POST 、PUT与 DELETE 请求。

使用方法:

  1. 在 web.xml 中配置该过滤器。
  2. 请求方式必须使用 post 请求。
  3. 按照要求提供_method 请求参数,该参数的取值就是我们需要的请求方式。

源码分析:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class HiddenHttpMethodFilter extends OncePerRequestFilter {
    private static final List<String> ALLOWED_METHODS;
    public static final String DEFAULT_METHOD_PARAM = "_method";
    private String methodParam = "_method"; // 隐藏属性名

    public HiddenHttpMethodFilter() {
    }

    public void setMethodParam(String methodParam) {
        Assert.hasText(methodParam, "'methodParam' must not be empty");
        this.methodParam = methodParam;
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest requestToUse = request;
        if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
            String paramValue = request.getParameter(this.methodParam); // 获取隐藏属性值,进行转换
            if (StringUtils.hasLength(paramValue)) {
                String method = paramValue.toUpperCase(Locale.ENGLISH);
                if (ALLOWED_METHODS.contains(method)) {
                    requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                }
            }
        }

        filterChain.doFilter((ServletRequest)requestToUse, response);
    }

在jsp中使用:

1
2
3
4
5
6
<!-- 更新 -->
<form action="springmvc/testRestPUT/1" method="post">
    用户名称:<input type="text" name="username"><br/>
    <input type="hidden" name="_method" value="PUT">
    <input type="submit" value="更新">
</form>

RequestHeader

作用:用于获取请求消息头。

属性

  • value:提供消息头名称
  • required:是否必须有此消息头

:在实际开发中一般不怎么用。

演示

1
2
3
4
5
@RequestMapping("/useRequestHeader")
public String useRequestHeader(@RequestHeader(value = "Accept-Language", required = false) String requestHeader) {
    System.out.println(requestHeader);
    return "success";
}

CookieValue

作用:用于把指定 cookie 名称的值传入控制器方法参数。

属性

  • value:指定 cookie 的名称。
  • required:是否必须有此 cookie。

演示

1
2
3
4
5
@RequestMapping("/useCookieValue")
public String useCookieValue(@CookieValue(value = "JSESSIONID", required = false) String cookieValue) {
    System.out.println(cookieValue);
    return "ok";
}

ModelAttribute

作用:该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。

  • 出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
  • 出现在参数上,获取指定的数据给参数赋值。

属性:value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。

应用场景:当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。

演示

演示一:基于 POJO 属性的基本使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@ModelAttribute
public void showModel(Account account) {
    System.out.println("执行了 showModel 方法" + account.getUsername());
}

@RequestMapping("/testModelAttribute")
public String testModelAttribute(Account account) {
    System.out.println("执行了控制器的方法" + account.getUsername());
    return "ok";
}
1
<a href="param/testModelAttribute?username=张三">testModelAttribute</a>
1
2
执行了 showModel 方法张三
执行了控制器的方法张三

演示二:基于 pojo 的应用场景示例:ModelAttribute 修饰方法带返回值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@ModelAttribute
public Account showModel(String username) {
    // 模拟去数据库查询
    Account account = new Account();
    account.setUsername(username);
    Course course = new Course();
    course.setName("英语");
    account.setCourse(course);
    logger.info("从数据库查询:{}", account);
    return account;
}

@RequestMapping("/testModelAttribute")
public String testModelAttribute(Account account) {
    logger.info("account:{}", account);
    return "ok";
}
1
2
20201016 15:20:36 [http-nio-8080-exec-2] INFO  com.eh.eden.springmvc.controller.ParamController - 从数据库查询:Account(username=张三, course=Course(name=英语), list=null, map=null)
20201016 15:20:36 [http-nio-8080-exec-2] INFO  com.eh.eden.springmvc.controller.ParamController - account:Account(username=张三, course=Course(name=英语), list=null, map=null)

演示三:基于 Map 的应用场景示例:ModelAttribute 修饰方法 不带返回值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@ModelAttribute
public void showModel(String username, Map<String, Account> map) {
    // 模拟去数据库查询
    Account account = new Account();
    account.setUsername(username);
    Course course = new Course();
    course.setName("英语");
    account.setCourse(course);
    logger.info("从数据库查询:{}", account);
    map.put("account", account);
}

@RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("account") Account account) {
    logger.info("account:{}", account);
    return "ok";
}

SessionAttribute

Model接口

Model接口的实现类是个Map,Model会存放到request域对象中,示例程序如下:

1
2
3
4
5
@RequestMapping("/testModel")
public String testModelAttribute(Model model) {
    model.addAttribute("abc", "ABC");
    return "ok";
}

ok.jsp

1
2
3
4
5
6
7
ok
<hr>

${abc}
<hr>

${requestScope}

测试结果:

http://img.cana.space/picStore/20201016153944.png

SessionAttribute

作用:用于多次执行控制器方法间的参数共享。

属性

  • value:用于指定存入的属性名称
  • type:用于指定存入的数据类型。
  • value和type之间是并集关系

演示

index.jsp

1
2
3
<a href="param/testPut">testPut</a>
<a href="param/testGet">testGet</a>
<a href="param/testClean">testClean</a>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.eh.eden.springmvc.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

@Controller
@RequestMapping("/param")
@SessionAttributes(value = {"username", "password"}, types = {Integer.class})
public class ParamController {
    private static final Logger logger = LoggerFactory.getLogger(ParamController.class);

    @RequestMapping("/testPut")
    public String testPut(Model model) {
        model.addAttribute("username", "张三");
        model.addAttribute("password", "123");
        model.addAttribute("age", 20);
        return "ok";
    }

    @RequestMapping("/testGet")
    public String testGet(Model model) {
        logger.info("model:{}", model);
        return "ok";
    }

    @RequestMapping("/testClean")
    public String testClean(SessionStatus sessionStatus) {
        sessionStatus.setComplete();
        return "ok";
    }
}