提示:以下是本篇文章正文内容,Java系列学习将会持续更新

@RequestMapping 简介

 在Spring MVC 中,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。

 @RequestMapping 既可修饰类,也可以修饰方法。当修饰类时,可以使该类下的方法有统一的 URL 前缀。

浅看一下源码

// Target 中这两个属性表示 @RequestMapping 注解可以用在方法和类上
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
	String name() default "";
	String[] value() default {};
	String[] path() default {};
	RequestMethod[] method() default {};
	String[] params() default {};
	String[] headers() default {};
	String[] consumes() default {};
	String[] produces() default {};
}

@RequestMapping注解中除了 name() 返回的字符串外,有七个属性。

属性名属性说明
value、path指定请求的url地址。value和path的作用相同,可以互相替换。value是默认属性,所以@RequestMapping(value=“/example”)和@RequestMapping(“/example”)是等价的。
method指定请求的method类型, GET(查)、POST(增)、PUT(改)、DELETE(删)等
params指定request中必须包含某些参数值是,才让该方法处理。
headers指定request中必须包含某些指定的header值,才能让该方法处理请求。
consumes指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

回到目录…

1. value属性

value属性通过请求的请求地址匹配请求映射。valuel属性是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求,value属性必须设置。

1-1 用法一:单纯的跳转html页面

@Controller // 必须用 Controller 注解
public class Demo1 {
    // 路由规则注册:访问页面的地址
    @RequestMapping("/test1")
    public String sayTest1() {
        // 跳转到 templates 下的 demo2.html
        return "demo2";
    }
}
// 访问地址: http://localhost:8080/test1

回到目录…

1-2 用法二:@ResponseBody 返回非视图数据

@ResponseBody 返回的值如果是字符会转换成 text/html,如果返回的是对象会转换成application/json 返回给前端。
@ResponseBody 可以用来修饰方法或者修饰类,修饰类表示类中的所有方法都会返回 html 或者json而不是视图

@Controller // 必须用 Controller 注解
@ResponseBody // 返回一个非视图文件
public class Demo2 {
    @RequestMapping("/test2")
    public String sayTest2() {
    	// 返回 HTML 文本
        return "<h1>hello,this is Test</h1>";
    }
    // URL: 127.0.0.1:8080/test2

	@RequestMapping("/test3")
    public String sayTest3() {
    	// 返回 JSON 数据
        return new Cat("小猫", 3);
    }
    // URL: 127.0.0.1:8080/test3
}

回到目录…

1-3 用法三:跳转html页面 + Model 渲染

1.首先你得创建一个数据实体类

import lombok.Data;
// @Data注解在lombok下,可以节省代码空间
// 有了@Data注解,我们就不需要手动写get、set、toString和构造方法了,它内置这些方法

@Data
public class Student {
    private final String name;
    private final String brief;
    private final String birthday;
}

2.创建一个动态模板文件(view.html),内部自定义数据对象

<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <title>仅仅是一个视图文件 | 实际上是一个模板文件</title>
</head>
<body>
    <h1 th:text="${person.name}">这里的内容会被替换</h1>
    <p th:text="${person.brief}">这里的内容会被替换</p>
    <p th:text="${person.birthday}">这里的内容会被替换</p>
</body>
</html>

3.经过Controller进行Model数据渲染

@Controller
public class DemoController {

    // 支持所有的 HTTP 方法,@RequestMapping 默认是 get方式的请求
    @RequestMapping("/hello")
    public String hello(Model model) {
        Student student = new Student("张三", "我是张三,很高兴认识大家", "2000-07-26");
		
		//往前台传数据,可以传对象,通过表达式 ${}可以获取到
        model.addAttribute("person", student);

        return "view";
    }
}
// 访问地址: http://localhost:8080/hello

回到目录…

2. method属性

@RequestMapping 中的 method 用来定义接收浏览器发来的请求,@RequestMapping 默认支持所有HTTP请求方法。

Http规范定义了多种请求资源的方式,最基本的有四种,分别为:GET(查)、POST(增)、PUT(改)、DELETE(删),而URL则用于定位网络上的资源相当于地址的作用,配合四种请求方式,可以实现对URL对应的资源的增删改查操作。

2-1 只支持 GET 请求

@Controller
public class UserController1 {
 	// 只支持 GET 方法
	@RequestMapping(value = "/login1", method=RequestMethod.GET)
	public String login1() {
		return "success";
	}
	// 可简写为
    @GetMapping("/login2")
    public String login2() {
		return "success";
	}
}
// 访问地址: http://localhost:8080/login1

这时,如果浏览器发来的请求不是GET的话,将收到浏览器返回的405错误提示,也就是得通过链接的方式。

2-2 只支持 POST 请求

@Controller
public class UserController2 {
	// 只支持 POST 方法
    @PostMapping("/login3")
	public String login3() {
		return "success";
	}
}

这时,必须通过表单的方式发送请求,否则将收到浏览器返回的405错误提示。

<form action="user/login" method="post">
    <input type="submit" value="使用Post发送请求"/>
</form>

2-3 只支持 GET 和 POST 请求

@Controller
public class UserController3 {
    // 支持 HTTP GET 和 POST 方法
    @RequestMapping(value = "/login4", method = {RequestMethod.GET, RequestMethod.POST})
    public String login4() {
		return "success";
	}
}

回到目录…

3. 获取请求参数:params

params 属性表示请求参数,也就是追加在URL上的键值对(queryString),多个请求参数以&隔开。
设置请求参数使用 @RequestParam 注解,也可以省略不写。

定义实体类:

@Data
public class Cat {
	public final String name;
	public final int age;
}

不设置请求参数的情况:

@Controller
public class ParamsController {

    @GetMapping("/cat1")
    @ResponseBody // 用来返回JSON数据
    public Cat createCat() {
    	// 返回对象会被 JSON 序列后输出
        return new Cat("小猫", 3);
    }
}
// 访问地址: http://localhost:8080/cat1
// 网页结果:{"name":"小猫","age":3}

回到目录…

3-1 @RequestParam 获取属性值

以下是省略 @RequestParam 的写法:省略条件是 queryString中的请求参数名 === 方法中的形参 ,一般情况下都满足条件。

@Controller
public class ParamsController {
    
    @GetMapping("/cat2")
    @ResponseBody
    public Cat createCat2(String name, Integer age) {
        return new Cat(name, age);
    }
    // 127.0.0.1:8080/cat2?name=李白&age=6
    // URL必须加 queryString, 属性值任意

    @GetMapping(value = "cat3", params={"name=小米","age=4"})
    @ResponseBody
    public Cat createCat3(String name, Integer age) {
        return new Cat(name, age);
    }
    // 127.0.0.1:8080/cat3?name=小米&age=4
    // URL必须加 queryString, 且属性值必须和 params 中一致
}

不省略就这么写, @RequestParam 还可以设置默认值。

@Controller
public class ParamsController {
    
    @GetMapping("/cat4")
    @ResponseBody
    public Cat createCat4(@RequestParam(value = "name", defaultValue = "小黑") String name, 
    					  @RequestParam(value = "age", defaultValue = "20") int age) {
        return new Cat(name, age);
    }
}
// 127.0.0.1:8080/cat4
// 网页结果: {"name":"小黑","age":20}
// 127.0.0.1:8080/cat4?name=小白&age=18
// 网页结果: {"name":"小白","age":18}

回到目录…

3-2 请求参数为对象

@Controller
public class ParamsController {
    @GetMapping("/cat5")
    @ResponseBody
    public Cat createCat5(Cat cat) {
        // 可以直接用对象请求。只要能正确传参,Spring内部会构造对象
        return cat;
    }
}
// 键入地址: http://127.0.0.1:8080/cat5?name=一诺&age=20
// 网页结果: {"name":"一诺","age":20}

回到目录…

3-3 @RequestBody 接收JSON对象

send-json.html 前端发送POST请求,携带请求体中是JSON数据:

<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <title>通过 ajax + JSON 格式的请求体发送数据</title>
</head>
<body>
    <button>点一次,发送一次请求</button>
    <script>
        document.querySelector('button').onclick = send
        function send() {
            var person = {
                pid: 1993,
                name: '葫芦娃',
                gender: '男'
            }
            var personJsonText = JSON.stringify(person)

            var xhr = new XMLHttpRequest();
            xhr.open('post', '/send-json')
            xhr.onload = function() {
                alert('响应状态: ' + this.status)
                alert('响应正文: ' + this.responseText)
            }
            xhr.setRequestHeader('Content-Type', 'application/json')
            xhr.send(personJsonText)
        }
    </script>
</body>
</html>

后端获取请求数据:

@Controller
public class TestController {
    // 前端请求的要求:
    // 1. 有请求体,肯定是 POST 请求
    // 2. 请求体格式是 JSON 格式
    @PostMapping("/send-json")
    @ResponseBody // 不写 @ResponseBody 的话,Spring 尝试去找 "成功" view,由于找不到会404
    public String getPerson(@RequestBody Person person) {
        log.info("请求体中的参数: " + person);
        return "成功";
    }
}
// 在浏览器访问 127.0.0.1:8080/send-json.html , 控制发送POST请求
// 在控制台可以看到后端接收到的JSON数据

回到目录…

3-4 @PathVariable 获取URL中参数

PathVariable:路径变量。目前这种URL的设计是主流的,类似于CSDN中文章的URL。
固定格式:https://blog.csdn.net/作者用户名/article/details/文章ID号
我的文章:https://blog.csdn.net/qq15035899256/article/details/126555706

@Controller
public class TestController {
    @GetMapping("/{username}/article/details/{aid}")
    @ResponseBody
    public String articleDetails(@PathVariable("username") String name, @PathVariable("aid") String aid) {
        log.info("username = {}, aid = {}", name, aid);
        return "关于从数据库中找到的文章的详情";
    }
}
// URL: 127.0.0.1:8080/zhangsan/article/details/123

回到目录…

3-5 @RequestPart 上传文件

upload.html 前端上传文件:

<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
</head>
<body>
    <form method="post" action="/upload" enctype="multipart/form-data">
        文件名:<input type="text" name="name">
        文件类型:<input type="text" name="type">
        <input type="file" name="some-file">
        <button>提交</button>
    </form>
</body>
</html>

后端获取文件信息:

@Controller
public class TestController {
	@PostMapping("/upload")
    @ResponseBody
    public String upload(String name, String type, @RequestPart("some-file") MultipartFile file) throws IOException {
        log.info("name = {}, type = {}", name, type);
        log.info("some-file 的信息: name = {}, 原始文件名= {}, content-Type = {}, size = {}", file.getName(), file.getOriginalFilename(), file.getContentType(), file.getSize());

        // 获取文件后缀名
        String fileName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        // 文件保存地址: target下的static包下 + 随机文件名.源文件后缀
        String filePath = ClassUtils.getDefaultClassLoader().getResource("static").getPath() + "/" + UUID.randomUUID() + fileName;
        // 由于路径中的 空格 被替换成 %20 了,所以我们需要换回去
        String filePathTrue = filePath.replaceAll("%20", " ");
        log.info(filePathTrue);
        // 保存文件
        file.transferTo(new File(filePathTrue));
        return filePath + " 上传成功.";
    }
}

回到目录…

3-6 获取Cookie/Session

传统获取 cookie

@Controller
public class CookieController {
	@RequestMapping("/cookie1")
	@ResponseBody
	public String cookie1(HttpServletRequest request) {
		String name = request.getParameter("name");
		// 获取所有 cookie 信息
		Cookie[] cookies = request.getCookies();
		return "成功";
	}
}

简洁的获取 Cookie—@CookieValue

@Controller
public class CookieController {
	@RequestMapping("/cookie2")
	@ResponseBody
	public String cookie2(@CookieValue("bite") String bite) {
		return "cookie:" + bite;
	}
}

回到目录…

Session 存储和获取

@Controller
@ResponseBody
public class SessionController {

	@RequestMapping("/session1")
	public String session1(HttpServletRequest request) {
		// 获取 HttpSession 对象,参数设置为 true 表示如果没有 session 对象就创建一个 session
		User user = new User("zhangsan", "123456");
		HttpSession session = request.getSession(true);
		session.setAttribute("currentUser", user);
		return "session 会话成功";
	}

	@RequestMapping("/session2")
	public String session2(HttpServletRequest request) {
		// 如果 session 不存在,不会自动创建
		HttpSession session = request.getSession(false);
		User user = null;
		if(session != null && session.getAttribute("currentUser") != null){
			user = (User) session.getAttribute("currentUser");
		}
		return user;
	}
}

获取 Session 更简洁的方式: @SessionAttribute

@Controller
public class SessionController {
	@RequestMapping("/session3")
	@ResponseBody
	public String session3(@SessionAttribute(value = "currentUser",required = false) User currentUser) {
		return "user: " + currentUser;
	}
}

回到目录…

4. headers属性

通过 @RequestMapping 中的 headers 属性,可以限制客户端发来的请求

@Controller
public class HeadersController {
	// 表示只接收本机发来的请求
	@RequestMapping(path = "/login", headers="Host=localhost:8080")
	public String login() {
		return "success";
	}
}

回到目录…

5. produces属性

produces属性指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。

public class DemoController {
	// 指定输出格式为text,字库为utf-8; 也就是响应头中的 Content-Type
	@RequestMapping(value = "/sayhello", produces = "text/plain; charset=utf-8")
    @ResponseBody
    public String sayHello(String target) {
        return "你好, " + target;
    }
}
// 键入地址: http://localhost:8080/sayhello
// 输出结果: 你好,null
// 键入地址: http://localhost:8080/sayhello?target=小米
// 输出结果: 你好,小米

回到目录…

总结

 开始学习Spring已经有一周了,给我的感觉就是起步比较难。框架这种东西你不需要知道原理就可以使用,这对于开发来说确实省事儿了不少。但是对于初学者来说,确实有不小的难度,因为这里面的东西太多了,如果没有时间的积累,你很难在短期内认识那么多的工具,更别说搞懂原理了。
 不过也会正常,“万事开头难”。我们能做的只有慢慢努力了。这篇文章仅仅是初学的总结,后续还需要不断的补充和改进!!!

回到目录…


总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文是SpringMVC的学习,又认识了一个注解@RequestMapping,并且学习了它的各种用法。之后的学习内容将持续更新!!!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐