24-springMvc注解开发-常用注解(一)

1 @Controller

此注解用用于修饰表现层控制器的注解,本质就是@Component 注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

	// 用于指定存入IOC容器是Bean的唯一标识
	@AliasFor(annotation = Component.class)
	String value() default "";

}

2 @RequestMapping

2.1 介绍

  • 作用:用于建立请求URL和处理请求方法之间的对应关系。
  • 位置:类上和方法上
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {

	/***
	 name:给请求URL提供一个名称。
	*/
	String name() default "";

	/**
	 value:用于指定请求的URL。它和path属性的作用是一样的。
	 */
	@AliasFor("path")
	String[] value() default {};

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

	/**
		method:用于指定请求的方式。它支持以下这些类型:
		GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.
	 */
	RequestMethod[] method() default {};

	/**
	params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样。
	 */
	String[] params() default {};

	/**
	 * headers:用于指定限制请求消息头的条件。
	 * eg:
	 * 		RequestMapping(value = "/something", headers = "content-type=text/*")
	 */
	String[] headers() default {};

	/**
		consumes:用于指定可以接收的请求正文类型(MIME类型)
		eg:
			consumes = "text/plain"
			consumes = {"text/plain", "application/*"}
	 */
	String[] consumes() default {};

	/**
		produces:用于指定可以生成的响应正文类型。(MIME类型)
		eg:
			produces = "text/plain"
			produces = {"text/plain", "application/*"}
			produces = MediaType.APPLICATION_JSON_UTF8_VALUE
	 */
	String[] produces() default {};

}

2.2 demo

  1. 搞一个controller
package study.wyy.spring.anno.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * @author by wyaoyao
 * @Description  RequestMapping注解测试
 * @Date 2021/2/14 12:56 下午
 */
// RequestMapping可以放在类上
@RequestMapping("requestMapping")
@Controller
public class RequestMappingTestController {

    /****
     * 对应的请求路径:requestMapping/test01
     * 并且请求方式是get请求
     * 比如带有name参数:requestMapping/test01?name
     *
     */
    @RequestMapping(path = "/test01",method = RequestMethod.GET,params = {"name"})
    public String test01(){
        return "success";
    }
}
  1. 搞个页面发送请求测试
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>1 get请求:</h1>
    <a href="${pageContext.request.contextPath}/requestMapping/test01">url:requestMapping/test01</a>
    <br>
    <!--携带了name参数-->
    <a href="${pageContext.request.contextPath}/requestMapping/test01?name">url:requestMapping/test01?name</a>

    <h1>2 post请求:</h1>
    <form action="${pageContext.request.contextPath}/requestMapping/test01" method="post">
        <input type="submit" value="post请求">
    </form>

</body>
</html>
  1. 部署测试
    第一个请求,没有携带name参数,直接400错误,Parameter conditions “name” not met for actual request parameters:
    第二个请求,携带name参数,请求成功,返回到success页面
    第三个请求,是个post请求,而我们限制了请求只能是get请求,405错误,Request method ‘POST’ not supported

2.3 衍生注解

对应不同的请求方式

  • @GetMapping:指定为get请求
  • @PostMapping:指定为post请求
  • @PutMapping:指定为put请求
  • @DeleteMapping:指定为delete请求

3 @RequestParam

3.1 介绍

  • 作用:此注解是从请求正文中获取请求参数,给控制器方法形参赋值的。 当请求参数的名称和控制器方法形参变量名称一致时,无须使用此注解。 同时,当没有获取到请求参数时,此注解还可以给控制器方法形参提供默认值。
  • 只能出现在形参上
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

	/**
	 * Alias for {@link #name}.
	 */
	@AliasFor("name")
	String value() default "";

	/**
	 * The name of the request parameter to bind to.
	 * @since 4.2
	 */
	@AliasFor("value")
	String name() default "";

	/**
		指定参数是否必须有值。当为true时,参数没有值会报错。
	 */
	boolean required() default true;

	/**
	在参数没有值时的默认值。
	 */
	String defaultValue() default ValueConstants.DEFAULT_NONE;

}

3.2 demo

  1. 控制器
package study.wyy.spring.anno.web;

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

@RequestMapping("requestParam")
@Controller
public class RequestParamTestController {


    /**
        1. 请求提交的参数名username,会被赋值到形参的name中
        2. 形参age指定使用RequestParam注解,所以如果请求参数中带有age参数,就会被赋值到形参age中
        3. 并且username参数是必须要带的,如果没有username参数,默认位置wyy
     总而言之:RequestParam作用就是
        1. 当请求参数和控制器中形参不一致时,可以使用该注解进行映射: name属性
        2. 为请求参数设置默认值: defaultValue属性
        3. 设置请求参数是否必须有值: required属性
     */
    @RequestMapping(path = "/test01")
    public String test01(@RequestParam(name = "username",defaultValue = "wyy",required = true) String name, Integer age) {
        System.out.println("name: " + name + ";age: " + age);
        return "success";
    }

}
  1. 准备页面发送请求
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <span>没有携带任何参数</span><a href="${pageContext.request.contextPath}/requestParam/test01">url:requestParam/test01</a>
    <br>
    <span>携带了username和age参数</span><a href="${pageContext.request.contextPath}/requestParam/test01?username=韦德&age=18">url: requestParam/test01?username=韦德&age=18</a>
    <br>
    <span>携带了name和age参数</span><a href="${pageContext.request.contextPath}/requestParam/test01?name=韦德&age=18">url: requestParam/test01?name=韦德&age=18</a>

</body>
</html>
  1. 测试结果 name: wyy;age: 18
    • 没有携带任何参数:
      • name: wyy;age: null;
      • name通过RequestParam注解指定了默认值是wyy,而age没有默认值所以是null
    • 携带了username和age参数:
      • name: 韦德;age: 18
    • 携带了name和age参数
      • name: wyy;age: 18
      • 携带的是name参数,而非username参数,所以形参中依然使用的是默认值wyy

4 @InitBinder(不常用)

4.1 介绍

  • 作用:用于初始化表单请求参数的数据绑定器,处理参数转换的
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InitBinder {

	/**
	 指定给哪些参数进行绑定操作。
	 */
	String[] value() default {};

}

4.2 demo

  1. 准备controller
package study.wyy.spring.anno.web;

import org.springframework.format.datetime.DateFormatter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import study.wyy.spring.anno.model.User;

@Controller
@RequestMapping("initBinder")
public class InitBinderTestContoller {

    @RequestMapping("/test01")
    public String test01(User user){
        System.out.println(user);
        return "success";
    }

    //@InitBinder
    //public void dateBinder(WebDataBinder dataBinder){
    //	dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
    //}
}
  1. user,主要这里封装了一个Date类型的数据
@Data
@ToString
public class User implements Serializable {
    private String username;
    private Integer age;
    private Date  birthday;
}
  1. 页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <form action="${pageContext.request.contextPath}/initBinder/test01" method="post">
        <label>用户名:</label><input type="text" name="username">
        <br>
        <label>年龄:</label><input type="text" name="age">
        <br>
        <label>生日:</label><input type="text" name="birthday">
        <br>
        <input type="submit">
    </form>
</body>
</html>
  1. 测试请求
  • 发现会报400的错误,400是客户端错误,一般是由于请求参数格式有问题导致服务器无法处理当前请求
  • 放开注释的代码,再次测试,请求正常,数据映射成功,控制台输出:User(username=wyy, age=12, birthday=Sat Dec 12 00:00:00 CST 2020)

InitBinder注解用来处理参数类型转换的

4.3 补充一个注解:@DateTimeFormat

处理时间格式化的注解,使用该注解就不需要刚刚的这段代码了:

 @InitBinder
 public void dateBinder(WebDataBinder dataBinder){
     dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
 }

如何使用:要使用DateTimeFormat注解,需要开启springmvc注解驱动的(就是这个注解@EnableWebMvc

@Data
@ToString
public class User implements Serializable {
    private String username;
    private Integer age;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date  birthday;
}

5 @ControllerAdvice注解

5.1 介绍

用于给控制器提供一个增强的通知。 以保证可以在多个控制器之间实现增强共享。
它可以配合以下三个注解来用:

  • @exceptionhandler
  • @initbinder
  • @modeltattribute

比如上面的InitBinder注解,写在某个controller,只对这个controller有效,不能在每个controller中加这么一个注解吧
这个时候就可以结合ControllerAdvice注解,为每一个controller增强这么一个数据绑定器:

@ControllerAdvice
public class DataFormatAdvice {
    
    @InitBinder
    public void dateBinder(WebDataBinder dataBinder){
        dataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
    }
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {

	/**
	用于指定对哪些包下的控制器进行增强
	 */
	@AliasFor("basePackages")
	String[] value() default {};

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

	/**
	 可以通过指定类的字节码的方式来指定增强作用范围。指定类所在的包下的controller
	 */
	Class<?>[] basePackageClasses() default {};

	/**
	用于指定特定的类型提供增强。
	 */
	Class<?>[] assignableTypes() default {};

	/**
	,用于指定给特定注解提供增强。 
	 */
	Class<? extends Annotation>[] annotations() default {};

}

6 @RequestHeader和@CookieValue

6.1 介绍

RequestHeader: 此注解是从请求消息头中获取消息头的值,并把值赋给控制器方法形参。
CookieValue: 此注解是从请求消息头中获取Cookie的值,并把值赋给控制器方法形参。

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestHeader {

	/**
	 * 用于指定请求消息头的名称。它和name属性作用一样
	 */
	@AliasFor("name")
	String value() default "";

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

	/**
		用于指定是否必须有此消息头。
	 */
	boolean required() default true;

	/**
	 用于指定消息头的默认值。
	 */
	String defaultValue() default ValueConstants.DEFAULT_NONE;

}
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CookieValue {

	/**
	 *用于指定cookie的名称
	 */
	@AliasFor("name")
	String value() default "";

	@AliasFor("value")
	String name() default "";
	
	boolean required() default true;
	
	String defaultValue() default ValueConstants.DEFAULT_NONE;

}

6.2 示例

 @RequestMapping("test")
 public String test(@RequestHeader("Accept-Language") String head, @CookieValue("JSESSIONID") String cookie){
     System.out.println(head);
     System.out.println(cookie);
     return "success";
 }

7 @ModelAttribute

7.1 介绍

它可以用于修饰方法,或者是参数。

  • 当修饰方法时,表示执行控制器方法之前,被此注解修饰的方法都会执行。
  • 当修饰参数时,用于获取指定的数据给参数赋值。。
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {

	/**
	 * 当注解写在方法上,则表示存入时的名称。(值是方法的返回值)
	 * 当注解写在参数上,可以从ModelMap,Model,Map中的获取数据。(前提是之前存入过)
	 * 指定的是存入时的key。
	 */
	@AliasFor("name")
	String value() default "";


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

	/**
	用于指定是否支持数据绑定。它是4.3版本中新加入的属性。
	 */
	boolean binding() default true;

}

7.2 测试

测试一:修饰在方法上

package study.wyy.spring.anno.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
@RequestMapping("modelAttribute")
public class ModelAttributeController {

    /****
     * 修饰在方法上,会在当前控制器的方法执行前执行
     * 可以对控制器进行一些前置处理
     * @param name
     */
    @ModelAttribute
    public void modelAttribute(String name){
        System.out.println("modelAttribute:" + name);
    }

    @RequestMapping("test01")
    public String test01(String name){
        System.out.println("controller: " + name);
        return "success";
    }
}

方法当前的url:modelAttribute/test01?name=wyy
发现modelAttribute方法先执行

modelAttribute:wyy
controller: wyy
测试二:如何存取值

方式一:

  /****
     * 修饰在方法上,会在当前控制器的方法执行前执行
     * 可以对控制器进行一些前置处理
     * @param name
     */
    @ModelAttribute
    public void modelAttribute(String name, Model model){
        System.out.println("modelAttribute:" + name);
        // 比如把name 给拼接上123
        model.addAttribute("username",name + "123");
    }

    @RequestMapping("test01")
    public String test01(String name, ModelMap model){
        System.out.println("controller: " + name);
        System.out.println("username:" + model.get("username"));
        return "success";
    }
modelAttribute:wyy
controller: wyy
username:wyy123

方式二:

  /****
     * 修饰在方法上,会在当前控制器的方法执行前执行
     * 可以对控制器进行一些前置处理
     * @param name
     */
    // name属性或者value属性指定key
    @ModelAttribute("username")
    public String modelAttribute(String name, Model model){
        System.out.println("modelAttribute:" + name);
        // 通过返回值存数据
        return name + "123";
    }

    @RequestMapping("test01")
    public String test01(String name, @ModelAttribute("username") String username){
        System.out.println("controller: " + name);
        System.out.println("username:" + username);
        return "success";
    }
modelAttribute:wyy
controller: wyy
username:wyy123
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值