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的使用大致可以分成3个部分:连接,获取参数和数据的输出
连接:将用户(浏览器)与程序联系起来,通过一个url来调用Spring程序
获取参数:获取到用户输入的一些参数
数据输出:将请求对应的响应输出给用户



@RequestMapping(value="/h",method=RequestMethod.POST)
@PostMapping("/h")
//二者等价
@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——使用@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;
}
当不使用@ResponseBody注解时,默认返回的是一个视图(页面)
@Controller
public class TestController {
@RequestMapping("/sayhi")
public String sayHi(){
return "hello.html";
}
}
使用@ResponseBody然后返回类型设置为字符串
@RequestMapping(value = "/sayhi2")
@ResponseBody
public String sayHi2(String username){
return "username: " + username;
}
使用@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";
}
}
请求转发和请求重定向的区别