SpringMVC学习笔记【part3】常用注解

SpringMVC 学习笔记 Part3

1. @RequestMapping 注解

@RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系。

@RequestMapping注解可以作用在方法和类上。作用在类上时,为第一级的访问目录,作用在方法上时,为第二级的访问目录。

@Controller
@RequestMapping("account")
public class HelloController {

    @RequestMapping("hello")
    public String sayHello(){
        System.out.println("Hello SpringMVC!");
        return "success";
    }

}

细节:路径可以不编写 / 表示应用的根目录开始,且在jsp中的虚拟路径${ pageContext.request.contextPath }也可以省略不写,但是路径上不能写 /

如上编写后,该请求方法的路径就变为/account/hello了。用多级目录可以方便模块化管理,如:账户模块/account/add、/account/update、/account/delete,而订单模块就是/order/add、/order/update、/order/delete。分别在类和方法上写 @RequestMapping 能使我们的URL更加精细。

属性

value: 用于指定请求的 URL。它和 path 属性的作用是一样的(互为别名)。
method: 用于指定请求的方式。
params: 用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的 key 和 value 必须和配置的一模一样。
	例如:
		params = {"accountName"},表示请求参数必须有 accountName
		params = {"moeny=100"},表示请求参数中有 money 且值必须是 100。
		params = {"moeny!100"},表示请求参数中 money 不能是 100。
headers: 用于指定限制请求消息头的条件。

以上四个属性只要出现 2 个或以上时,他们的关系是与的关系。

一般只会用到value和method两个属性,另外两个不常用,代码如下。

@RequestMapping(value = "hello",method = {RequestMethod.POST,RequestMethod.GET})
    public String sayHello(){
        System.out.println("Hello SpringMVC!");
        return "success";
    }

2. @RequestParam 注解

@RequestParam 注解的作用是把请求中的指定名称的参数传递给控制器中的形参赋值。

属性

value:请求参数中的名称
required:请求参数中是否必须提供此参数,默认值是true,必须提供

通常情况下,我们的表单name属性名和方法形参名相同,则可以spring会为我们自动赋值。

<form action="anno/hello">
    名称:<input type="text" name="username"/>
    <input type="submit" value="提交"/>
</form>
	@RequestMapping("hello")
    public String myAnnoMVC(String username){
        System.out.println(username);
        return "success";
    }

但如果表单name属性名和方法形参名不一样,则我们需要用 @RequestParam 来给建立映射关系。

表单中的name属性名更改为了uuname,这时在方法形参前加入注解,即可完成映射。

<form action="anno/hello">
    名称:<input type="text" name="uuname"/>
    <input type="submit" value="提交"/>
</form>
	@RequestMapping("hello")
    public String myAnnoMVC(@RequestParam("name") String username){
        System.out.println(username);
        return "success";
    }

3. @RequestBody 注解

@RequestBody 注解的作用是获取请求体内容。post请求方式时使用得到是 key=value&key=value…结构的数据,get 请求方式不适用。

属性:

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

我们如果要获取请求体内容,就加入一个字符串类型的形参并在前面添加@RequestBody。

	@RequestMapping("hello")
    public String myAnnoMVC(@RequestBody String body){
        System.out.println(body);
        return "success";
    }

当我们在有两个input标签,且它们的name属性分别为username和password的表单中键入zhangsan和123时,那么请求体打印出来的信息将会是

username=zhangsan&password=123

这些key-value我们其实可以用声明形参直接获取到,这显得@RequestBody这个注解没什么卵用,其实它的使用更多的是在之后学习的异步和json中。

4. @PathVariable 注解

@PathVariable 注解的作用是绑定url中的占位符。例如:url中有/delete/{id},{id}就是占位符。url支持占位符是 springmvc 支持 rest 风格 URL 的一个重要标志。

属性

value:指定url中的占位符名称

Restful风格的URL简介

url请求路径一样,但可以根据不同的请求方式去执行后台的不同方法。具有结构清晰、符合标准、易于理解、扩展方便的优点。

原来方式:
    UserController类
    
    path="/user/save"
    save
    
    path="/user/update"
    update
    
    path="/user/findAll"
    findAll
    
restful方式:
	UserController类
    
    path="/user" POST
    save
    
    path="/user" PUT
    update
    
    path="/user" GET
    findAll
    
    path="/user/{id}" GET
    findById(id)

调用findAll方法的url为localhost:8080/user GET,调用findById的url为localhost:8080/user/10 GET,这就是 restful 设计风格。

@PathVariable 注解的注意事项是,@RequestMapping 注解里的 path 后的占位符 {id} 要和 @PathVariable 中 value 一样,才能完成映射。例如 @RequestMapping(“hello/{uid}”) 和 @PathVariable(“uid”) 。使用方法如下。

    @RequestMapping("hello/{id}")
    public String myAnnoMVC(@PathVariable("id")Integer id){
        System.out.println(id);
        return "success";
    }

切记占位符语法是 url/param 而不是 url?param,正确 url 代码如下。

	<a href="anno/hello/10">点击跳转</a>

5. @RequestHeader 注解

@RequestHeader注解的作用是获取指定请求头的值。在实际开发中一般不怎么用。

属性

value:请求头的名称

代码格式如下。(形同@RequestBody的使用方法)

	@RequestMapping("hello")
    public String myAnnoMVC(@RequestHeader("Accept") String header){
        System.out.println(header);
        return "success";
    }
	<a href="anno/hello">点击获取RequestHeader</a>

打印内容:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9

6. @CookieValue 注解

@CookieValue注解的作用是把指定 cookie 名称的值传入控制器方法参数。

属性:

value:指定 cookie 的名称。

代码格式如下。(形同@RequestBody的使用方法)

	@RequestMapping("hello")
    public String myAnnoMVC(@CookieValue("JSESSIONID") String cookie){
        System.out.println(cookie);
        return "success";
    }
	<a href="anno/hello">点击获取CookieValue</a>

补充知识—jsessionid:jsessionid是一个Cookie,可以通过在URL后面加上“;jsessionid=xxx”来传递“session id”。当我们创建会话时会自动创建,Servlet容器(如tomcat)用jsessionid来记录用户的访问记录。

打印结果:

AA6C190F2D2AB8B97EE9B75294D1CBF1

7. @ModelAttribute 注解

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

@ModelAttribute 注解的应用场景是当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。通俗的说呢,比如我们在编辑一个用户时,用户有一个关于创建信息的字段(比如password),该字段的值是不允许被修改的。在提交表单数据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。

出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。

出现在参数上,获取指定的数据给参数赋值。

属性:

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

方法一:修饰的方法有返回值

    <form action="anno/hello">
        <h3>修改用户信息</h3>
        用户名:<input type="text" name="username"/>
        年龄:<input type="text" name="age"/>
        <input type="submit" value="提交"/>
    </form>

当在表单进行提交修改的信息,这时如果直接封装的话,会造成那些没出现在表单上、且不允许修改的字段变成 null 值,如 id , password 等字段。这时我们需要新建一个方法并加上 @ModelAttribute 注解。被 @ModelAttribute 贴上的方法将在请求方法前先执行。我们这时可以调用 service 层的业务,找到完整的对象信息,将它作为返回值返回。回到请求方法中,我们需要设置形参来接受这个返回值。

	//先执行
    @ModelAttribute
    public User showAccount(String username){
        User user = service.findByName(username);
        System.out.println(user); //数据库里查出来的数据 User{username='zhangsan', password='123456', age=18}
        return user;
    }

    //后执行
    @RequestMapping("hello")
    public String myAnnoMVC(User user){
        System.out.println(user); //提交表单进行更新后的数据 User{username='zhangsan', password='123456', age=123}
        return "success";
    }

如上的 password 可以发现,这时就实现了当提交表单数据不是完整的实体数据时,没有提交的字段会使用数据库原来的数据。

方法二:修饰的方法无返回值(需用到Map)

在 @ModelAttribute 注解的方法形参中加入Map<E,T>集合,spring会为我们自动创建该对象进容器。无返回值的方法即是把 return 语句更换成了 map.put() 。

在请求方法中,参数前使用 @ModelAttribute 并在注解的 value 属性中填入相应的 key 值,即可完成映射自动取出我们要的 User 对象。

	//先执行
    @ModelAttribute
    public void showAccount(String username,Map<String,User> map){
        User user = service.findByName(username);
        System.out.println(user);
        map.put("one",user);
    }

    //后执行
    @RequestMapping("hello")
    public String myAnnoMVC(@ModelAttribute("one")User user){
        System.out.println(user);
        return "success";
    }

8. @SessionAttributes 注解

@SessionAttributes 注解的作用是用于多次执行控制器方法间的参数共享。

属性:

value:用于指定存入的属性名称
type:用于指定存入的数据类型
8.1 值存入request域

把数据存入 request域 将用到Model类型的形参和它的addAttribute方法,示例如下。

声明Model类型的形参,调用addAttribute方法把一个key-value形式的值存入model。

 	@RequestMapping("putRequest")
    public String myAnnoMVC(Model model){
        model.addAttribute("msg","你好!SpringMVC!");
        return "success";
    }

在跳转页success.jsp中可以通过request域拿到这个msg值。

	<h3>${requestScope.msg}</h3>

在使用EL表达式时,需要在顶部page指令中加入 isELIgnored=“false” 属性来开启EL表达式。

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
8.2 值存入session域

把数据存入 session域 ,需要在8.1的基础上再加上我们这小节学习的**@SessionAttributes**注解,示例如下。

@SessionAttributes注解只能贴在方法上,value 中填入变量名(或者 type 中填入数据类型String.class)来把刚刚只存放在 request 域中的值也存入session域中。

@Controller
@RequestMapping("anno")
@SessionAttributes({"msg"})
public class AnnoController {
    
    @RequestMapping("putSession")
    public String myAnnoMVC(Model model){
        model.addAttribute("msg","你好!SpringMVC!"); //添加一对key-value值
        return "success";
    }   
}

在跳转页success.jsp中可以通过session域拿到这个msg值。

    <h3>${sessionScope.msg}</h3>
8.3 获取session域的值

从session域中获取值要用到 ModelMap 类型的形参和 get() 方法,示例如下。

	@RequestMapping("getSession")
    public String myAnno1(ModelMap map){
        String  msg = (String) map.get("msg"); //通过键获取值
        System.out.println(msg);
        return "success";
    }
8.4 删除session域的值

从session域中删除值需要用到 SessionStatus 类型的形参和 setComplete() 方法,示例如下。

	@RequestMapping("cleanSession")
    public String myAnno2(SessionStatus status,ModelMap map){
        status.setComplete(); //将session中的内容全部清空
        return "success";
    }

9. HiddentHttpMethodFilter过滤器(了解)

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

使用方法:

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

源码分析:

在这里插入图片描述

jsp代码示例:

    <!-- 保存 --> 
    <form action="springmvc/testRestPOST" method="post">
        用户名称:<input type="text" name="username"><br/>
        <!-- <input type="hidden" name="_method" value="POST"> --> 
        <input type="submit" value="保存">
    </form> 
    <hr/>

    <!-- 更新 -->
    <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>
    <hr/>

    <!-- 删除 --> 
    <form action="springmvc/testRestDELETE/1" method="post"> 
        <input type="hidden" name="_method" value="DELETE"> 
        <input type="submit" value="删除">
    </form> 
    <hr/>

    <!-- 查询一个 --> 
    <form action="springmvc/testRestGET/1" method="post"> 
        <input type="hidden" name="_method" value="GET"> 
        <input type="submit" value="查询">
    </form>

控制器代码示例:

    /**
    * post 请求:保存
    * @param username
    * @return
    */
    @RequestMapping(value="/testRestPOST",method=RequestMethod.POST)
    public String testRestfulURLPOST(User user){
        System.out.println("rest post"+user);
        return "success"; 
    }

    /**
    * put 请求:更新
    * @param username
    * @return
    */
    @RequestMapping(value="/testRestPUT/{id}",method=RequestMethod.PUT)
    public String testRestfulURLPUT(@PathVariable("id")Integer id,User user){
        System.out.println("rest put "+id+","+user);
        return "success"; 
    }

    /**
    * post 请求:删除
    * @param username
    * @return
    */
    @RequestMapping(value="/testRestDELETE/{id}",method=RequestMethod.DELETE)
    public String testRestfulURLDELETE(@PathVariable("id")Integer id){
        System.out.println("rest delete "+id);
        return "success"; 
    }

    /**
    * post 请求:查询
    * @param username
    * @return
    */
    @RequestMapping(value="/testRestGET/{id}",method=RequestMethod.GET)
    public String testRestfulURLGET(@PathVariable("id")Integer id){
        System.out.println("rest get "+id);
        return "success"; 
    }

这个实现起来挺繁琐,如果之后有学习webservice技术的话,有个webclient类可以更方便的帮我们实现模拟各种http请求,所以这节内容仅作了解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Parker7

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

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

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

打赏作者

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

抵扣说明:

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

余额充值