Spring MVC

2023-12-13 14:30:51

什么是Spring MVC

官方介绍
  1. Spring MVC是一个Web框架,具有http能力
  2. 构造在Servlet(API)之上的
什么是MVC

MVC是Model View Controller的缩写,他是一种设计模式,将软件系统分为模型,视图和控制器三部分。
image.png
Model:对请求进行处理
Controller:和用户进行交互,对用户请求合理性进行校验
View:返回一个页面给用户

MVC和Spring MVC的关系

MVC是一种设计思想,而Spring MVC是对MVC思想的具体实现。

总结:Spring MVC是一个实现了MVC模式,并继承了Servlet API的Web框架。

学习Spring MVC

学习Spring MVC重点掌握3个功能

  1. 连接功能: 将用户(浏览器)和Java程序连接起来,也就是访问一个地址就能调用我们的Spring程序
  2. 获取参数的功能: 用户访问的时候会带一些参数,在程序中想办法获取到参数
  3. 输出数据的功能: 执行业务逻辑之后,要把程序执行的结果返回给用户
Spring MVC的连接功能

在Spring MVC中使用@RequestMapping来实现URL的路由映射,也就是浏览器连接程序的作用。

@RequestMapping("/test") //一级路由地址
@Controller //让框架在启动的时候加载当前类,别人才能访问
@ResponseBody //让程序返回的是一个数据而不是页面
public class TestController {
    @RequestMapping("/hi") //二级路由地址
    public String sayHi() {
        return "hi Spring MVC";
    }
}

注意:以前没有前后端分离,所以需要Java程序员也要返回页面(也就是MVC中的视图),随着时代的进步,MVC中的视图被Spring MVC屏蔽了,使用@ResponseBody实现只返回数据的功能。
@RequestMapping既能修饰类也能修饰方法

@RequestMapping 即是get请求也是post请求

image.png
在有些公司对隐私性要求比较高,就会要求不能使用get请求,统一使用post请求,这种情况要怎么处理呢?

@RequestMapping(value = "/hi", method = RequestMethod.POST)

表示当前方法只支持post请求
image.png
除了上面方法还可以通过@PostMapping来实现

获取参数

传递基础类型参数
@RequestMapping("/test") //路由地址
@Controller //让框架在启动的时候加载当前类,别人才能访问
@ResponseBody //让程序返回的是一个数据而不是页面
public class TestController {
    //表示当前方法只支持post请求
    @RequestMapping(value = "/hi")
    public String sayHi(String name, Integer age) {
        return "hi," + name + " age: " + age;
    }
}

image.png
参数的位置不用对应,但是参数的名字要对应。

在Spring MVC中传参一定要使用包装类,而非基础类型

因为:当形参是一个基础类型,如果请求中忘记传递这个参数,使用基础类型就会报500错误,而类型包装不会报错,只是值为null
image.png
image.png

后端参数重命名@RequestParam

在某些情况下,前端传递的参数key和后端接收的key可以不一致,比如前端的命名为time,而后端要求要用createtime字段来接收。这样就会出现参数接收不到的情况,为此我们可以使用@RequestParam来重命名前后端的参数值

@RequestMapping("/test") //路由地址
@Controller //让框架在启动的时候加载当前类,别人才能访问
@ResponseBody //让程序返回的是一个数据而不是页面
public class TestController {
    @RequestMapping("/show-time")
    public String showTime(@RequestParam("t1") String start, 
                           @RequestParam("t2") String end) {
        return "开始时间:" + start + "| 结束时间:" + end;
    }
}

image.png
非必传参数设置
如果我们的业务中前端的参数是一个非必传的参数,我们就可以通过设置@RequestParam中的 required=false来避免不传递时报错。

@RequestMapping("/test") //路由地址
	@Controller //让框架在启动的时候加载当前类,别人才能访问
	@ResponseBody //让程序返回的是一个数据而不是页面
	public class TestController {
		@RequestMapping("/show-time")
		public String showTime(@RequestParam("t1", required = false) String start, 
		@RequestParam("t2") String end) {
		return "开始时间:" + start + "| 结束时间:" + end;
	}
}

image.png

传递对象

如果前端需要传递多个参数,在使用上面的方法就很麻烦要写多个参数,就算你能写多个参数,此时需求要你增加或减少参数,参数那么多就可能造成参数多或参数少,很难发现。此时就需要传递参数来解决。将前端要传的参数包装成一个对象,此时参数就只有这个对象。至于这么多参数怎么变成一个对象是框架帮你完成
image.png

接收JSON对象

使用@RequestBody接收JSON对象,在和第三方系统通讯时的常见场景(双方使用的语言不同,需要通过JSON来进行交互)

@RequestMapping("/test") //路由地址
@Controller //让框架在启动的时候加载当前类,别人才能访问
@ResponseBody //让程序返回的是一个数据而不是页面
public class TestController {
    @RequestMapping("/json")
    public String showJson(@RequestBody User user) {
        return user.toString();
    }
}

image.png

获取URL的参数 @PathVariable

举个例子:localhost:8080/login?username=zhangsan&password=1234获取参数是从?开始根据key值来获取value。由于?后面的键值对动态改变的,SEO效果比较差.

SEO是一种搜索引擎优化的方式,利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名。

而如果把上面的url写成localhost:8080/login/zhangsan/1234,搜索引擎就会认为这是一个固定地址,SEO效果更佳。那要怎么获取这个url的参数呢?

@RequestMapping("/login/{username}/{password}")//位置一定要正确
public String login(@PathVariable("username") String name,
					@PathVariable("password") String password) {
	return name + ": " + password;
}

image.png

上传文件 @RequestPart
@RestController
@RequestMapping("/test")
public class TestController {
	@RequestMapping("/upfile")
	public String upfile(@RequestPart("myfile")MultipartFile file) throws IOException {
		//根目录
		String path = "D:\\javaee_advanced\\Test.2023.5.30\\";
		//根目录 + 唯一的文件名(使用UUID生成随机数)
		path += UUID.randomUUID().toString().replace("-", "");
		//再加上文件的后缀
		path += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
		//保存文件
		file.transferTo(new File(path));
		return path;
	}
}

使用postman实现上传一个文件
image.png

获取Cookie

在servlet时期,我们是使用HttpServletRequest和HttpServletResponse来获取,在Spring MVC同样适用,可以直接使用。

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @RequestMapping("/getck")
    public String getCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        for (Cookie item :
                cookies) {
            //通过日志来打印
            log.error(item.getName() + ": " + item.getValue());
        }
        return "get cookie";
    }
}

如果直接输入网址访问,会报空指针异常,所以需要自己造cookie
image.png
image.png
image.png
上面的代码是获取所有的cookie,在Spring mvc中可以使用**@CookieValue **来获取单个cookie

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @RequestMapping("/getSingleCookie")
    public String getCookie(@CookieValue("zhangsan") String value) {
        return "Cookie Value: " + value;
    }
}

image.png

获取header

使用Servlet时期的HttpServletRequest来实现

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @RequestMapping("/header1")
    public String getHeader1(HttpServletRequest request) {
        String header = request.getHeader("User-Agent");
        return header;
    }
}

image.png
在Spring MVC中可以使用 @RequestHeader 实现获取header头。

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @RequestMapping("/header2")
    public String getHeader2(@RequestHeader("User-Agent") String header) {
        return header;
    }
}

image.png

获取session

使用HttpServletRequest实现session的存和取

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @RequestMapping("/setsess")
    public String setSession(HttpServletRequest request) {
        HttpSession session = request.getSession(true);//没有session就新建
        session.setAttribute("userinfo", "用户信息");//设置session的键值对
        return "set session success";
    }
}

image.png

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @RequestMapping("/getsess")
    public String getSession(HttpServletRequest request) {
        HttpSession session = request.getSession(false);//没有session不新建
        if(session != null && session.getAttribute("userinfo") != null) {
            return (String) session.getAttribute("userinfo");
        }
        return "暂无session信息";
    }
}

image.png
在Spring MVC中可以使用 @SessionAttribute获取Session

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @RequestMapping("/getsess2")
    public String getSession2(@SessionAttribute(value = "userinfo", required = false) //设置非必传,防止报500
                                      String userinfo) {
        return userinfo;
    }
}

image.png

返回数据

返回静态页面
@Controller
@RequestMapping("/resp")
//不添加@Responsebody 表示返回的是页面
public class RespController {
    @RequestMapping("/index")
    public Object index() {
        return "/index.html";
    }
}

image.png
image.png

返回JSON对象
@Controller
@RequestMapping("/resp")
public class RespController {
    @RequestMapping("/json")
    @ResponseBody //表示返回的不是页面,是数据
    public HashMap<String, String> returnJson() {
        HashMap<String, String> map = new HashMap<>();
        map.put("java", "java value");
        map.put("mysql", "mysql value");
        map.put("spring", "spring value");
        return map;
    }
}

从哈希表变成json格式的操作是框架帮我们完成的
image.png
我们使用Fiddler抓包看看,返回的格式是不是json
image.png

请求转发和请求重定向
  1. forward: 请求转发
  2. redirect: 请求重定向
@Controller
@RequestMapping("/resp")
//不添加@Responsebody 表示返回的是页面
public class RespController {
    //请求重定向
    @RequestMapping("/redirect")
    public String index1() {
        return "redirect:/index.html";
    }
	//请求转发
    @RequestMapping("/forward")
    public String index2() {
        return "forward:/index.html";
    }
}

image.png
请求转发是服务器帮你转发,转发的地址不发生改变,有可能造成外部资源不能访问的问题。
image.png
而请求重定向是重新定位访问资源,转发的地址会发生改变,和访问新地址效果一样。

文章来源:https://blog.csdn.net/weixin_61427900/article/details/134899581
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。