目录
初始Spring MVC
Spring MVC的定义
Spring MVC是基于Servlet API构建的一种Web框架.Spring MVC可以分成两部分Spring和MVC,其中Spring说明Spring MVC是Spring的一部分.而什么是MVC
MVC是三个单词的首字母的拼接:Model,View,Controller,译为模型,视图和控制器.其中模型主要用于处理数据逻辑,负责在数据库中存储数据,视图即为数据的显示,而控制器则是应用程序与用户交互的部分,负责从视图中获取数据,并向Model发送数据.
因此Spring MVC就是MVC思想的一种具体实现,是Spring中的核心.
Spring MVC的使用
Spring MVC的使用大致可以分成3个部分:连接,获取参数和数据的输出
连接:将用户(浏览器)与程序联系起来,通过一个url来调用Spring程序
获取参数:获取到用户输入的一些参数
数据输出:将请求对应的响应输出给用户
Spring MVC的创建和连接
- 创建Spring MVC项目
Spring MVC项目的创建就是在Spring Boot项目的基础上添加Spring Web的依赖
- 在创建好Spring MVC项目后,创建一个UserController类实现用户和程序的联系
在浏览器上输入"http://localhost:8080/user/sayhi"即可在浏览器上展现出程序中输出的内容
在UserController类中,我们添加了很多个注解.其中@RestMapping注解是Spring MVC最常使用的几个核心注解之一.它用来注册接口的路由映射@RestMapping中的值即为url中对应的文件路径(某个类的方法映射)
@RestMapping既可以修饰类,也可以修饰方法.访问的地址是 类+方法
@RestMapping注解默认的请求方式是get.当然如果我们想要使用post请求,也可以指定RestMapping的method参数为"RequestMethod.POST",也可以使用@PostMapping注解
@RequestMapping(value="/h",method=RequestMethod.POST)
@PostMapping("/h")
//二者等价
Spring MVC的获取参数
获取单个参数
@RequestMapping("/single")
public void func(String p){
//输出用户传来的参数p
System.out.println(p);
}
获取对象
@RequestMapping("/single")
public void func(User user){
//输出用户传来的参数p
System.out.println(user.getUsername());
System.out.println(user.getAge());
}
@Data
public class User {
private int id;
private String username;
private String password;
private int age;
}
//@Data注解可以实现Getter和Setter方法的重写
获取多个参数
@RequestMapping("/multiple")
public void func(String username,String password){
//输出用户传来的参数p
System.out.println(username);
System.out.println(password);
}
参数格式的设置
-
后端参数重命名(@RequestParam)
在设置后端的参数名称时,要保证和前端输入的参数名一致,但实际上前后端是分离的,因此为了保证前后端的参数能够相匹配,后端通过使用@RequestParam注解来指定前端的参数名@RequestMapping("/login") public String login( @RequestParam("name") String username, String password){ return "用户名:" + username + " | 密码:" + password; }
上述方法的username参数前端对应的参数名为name.
使用@RequestParam时要注意一个细节.当参数名添加了@RequestParam时,前端必须给对应的参数传值.如果不传值,程序会报错.原因是因为@RequestParam注解默认required为true,也就是参数必须有值
当然,有时候参数没有值也是有一定的意义的,比如当你在一个歌曲搜索栏中不输入任何字符然后点击搜索,那么搜索到的就应该是当前界面显示的歌曲,而不是搜索到0首歌曲或者报错.因此我们可以通过设置@RequestParam中的required的参数为false,即支持无值传参@RequestMapping("/login") public String login( @RequestParam(value = "name",required = false) String username, String password){ return "用户名:" + username + " | 密码:" + password; }
-
接收JSON对象(@RequestBody)
当前端使用Post方法从请求体中传来参数时,参数的形式一般是JSON格式,使用**@RequestBody注解可以将JSON对象转换为Java中的类对象**.注意:当参数有多个参数时,只能有1个参数被@RequestBody注解修饰@RequestMapping("/login") public String login( @RequestParam(value = "name") @RequestBody String username, String password){ return "用户名:" + username + " | 密码:" + password; }
-
获取URL中参数(@PathVariable)
当想要获取一个url中的参数时,可以使用@PathVariable注解.在使用该注解时,@RequestMapping注解中必须有对应的参数值//"{id}/{name}必须写" @RequestMapping("/hero/{id}/{name}") public String getHeroInfo(@PathVariable int id, @PathVariable String name){ return "id:" + id + "| name:" + name; }
上传文件
当我们想通过Post方法上传文件时,可以使用@RequestPart注解和MultipartFile类实现
@RequestMapping("/upimg")
public boolean upImg(Integer id, @RequestPart("img")MultipartFile file){
boolean result = false;
//得到文件的原始名称
String fileName = file.getOriginalFilename();
//获取文件的格式
fileName = fileName.substring(fileName.lastIndexOf('.'));
//利用UUID生成一个唯一的随机id
fileName = UUID.randomUUID()+fileName;
try {
file.transferTo(new File("F:/"+fileName));
result = true;
} catch (Exception e) {
log.error("上传图片失败" + e.getMessage());
}
return result;
}
其中@RequestPart注解中的值是前端传递的参数名.UUID可以实现生成一个唯一的字符串,保证上传位置不重复
获取cookie/session/header
-
获取cookie——使用@CookieValue注解
@RequestMapping("/cookie2") public String getCookie2(@CookieValue("user") String cookie){ return "Cookie Value:" + cookie; }
-
获取session——使用@SessionAttribute注解
@RequestMapping("/gets") public String getSession2(@SessionAttribute(value = "userinfo",required = false) String userInfo){ return "Session:" + userInfo; }
-
获取header——使用@RequestHeader注解
@RequestMapping("/header2")
public String getHeader2(@RequestHeader("User-Agent") String header){
//@RequestHeader的value值是字段的key
return "Header:" + header;
}
Spring MVC的输出数据
返回静态页面
当不使用@ResponseBody注解时,默认返回的是一个视图(页面)
@Controller
public class TestController {
@RequestMapping("/sayhi")
public String sayHi(){
return "hello.html";
}
}
返回text/html
使用@ResponseBody然后返回类型设置为字符串
@RequestMapping(value = "/sayhi2")
@ResponseBody
public String sayHi2(String username){
return "username: " + username;
}
返回JSON对象
使用@ResponseBody然后返回类型设置成Java的对象
@ResponseBody
@RequestMapping("/getuserbyid")
public User getUserById(Integer id){
User user = new User();
user.setId(id);
user.setUsername("zhagnsan");
//user.setPassword("123");
user.setAge(11);
return user;
}
总结:在使用@ResponseBody修饰时,如果返回的类型是字符串,那么会转换成text/html格式返回给前端;如果返回的类型是Java对象,那么会转换成application/json格式返回给前端;当不使用@ResponseBody时,会返回视图给前端
@Controller和@ResponseBody可以用注解@RestController代替
请求转发和重定向
-
请求转发——不添加@ResponseBody注解,在返回的字符串前加上"forward"
@Controller public class TestController { @RequestMapping("/fw") public String forward(){ return "forward:/hello.html"; } }
-
请求重定向——不添加@ResponseBody注解,再返回的字符串前加上"redirect"
@Controller public class TestController { @RequestMapping("redi") public String redirect(){ return "redirect:/hello.html"; } }
-
请求转发和请求重定向的区别
- 请求转发的发送方是服务器,请求重定向的发送方是客户端.
客户端发送get请求url访问某个资源,服务器发现该资源的url发生了改变.请求转发就是服务器用新的url获取到资源后将资源返回给客户端,而请求重定向是服务器返回重定向的响应信息给客户端,客户端用新的url去访问该资源. - 请求转发访问地址不发生变化,请求重定向访问地址发生变化
- 请求转发的发送方是服务器,请求重定向的发送方是客户端.