目录
一. 认识 springMVC
spring,springBoot,springMVC的关系
二. springMVC 的连接和获取参数
1. 注解分析(不带参数)
2. 获取参数
3. 获取对象参数
4. 重命名功能
5. 获取 JSON 对象
6. 通过 path 文件路径来传递参数
7. 上传文件
9. 获取 session 和存储 session
一. 认识 springMVC
springMVC 是基于 servlet API 构造的原始 Web 框架。
所谓 MVC,也就是 model,view,controller,把软件系统分为模型,视图,控制器三个基本部分;
1. 模型:使应用程序中处理数据逻辑的部分,通常会在数据库中存取数据;
2. 试图:是应用程序中处理数据显示的部分;
3. 控制器:是应用程序中处理用户交互的部分;
MVC就是一种思想,而 springMVC 就是针对思想的具体实现。
spring,springBoot,springMVC的关系
spring 指的是 core 框架,是spring中的最核心基础的框架,他不包含其他的模块,只包含一些核心基础的功能,不具备 http 通信功能;
springBoot 就是 快速开发 spring框架 的脚手架;
springMVC 就是 spring 整个体系中的 web 框架,可以进行 http 通信;
所以说对于 springMVC 的学习,就主要有三个方向:建立连接,获取参数,输出数据;
二. springMVC 的连接和获取参数
1. 注解分析(不带参数)
1. @ResponseBody:表示返回非页面数据;
@ResponseBody 通常和 @Controller 合并为 @RestController ;
2. @RequestMapping:表示注册接口的路由映射;
这个注解支持 GET,也支持 POST,也可以通过 method = RequestMethod.GET 来限制只能用 GET 请求(POST同理);
路由映射通过 value="hello" ,value通常省略;
此注解的路由映射方式既可以加在 类上 ,也可以加在 方法上 ;
3. @GetMapping 和 @PostMapping :表示只支持 GET 或者 POST 请求;
2. 获取参数
在 springMVC 框架中,获取参数很方便,一般直接在方法的参数中进行体现就行了。
但要求查询字符串中的 key 值要和方法中的参数值一一对应!!!
此处还有一个注意点:参数一般选择包装类型,不用基础数据类型,例如 int,当使用 Integer 的时候,它是一个对象,如果不传递参数的话,会以 null 作为代替,但是如果为 int ,会直接报错。所以一般建议使用包装类型进行接收。
springMVC 是基于 servlet API 实现的,显然 servlet 的那套获取参数的方式依然是成立的;
HttpServletRequest 和 HttpServletResponse 就作为 springMVC 中隐藏的参数对象,可以使用。
3. 获取对象参数
当前端传递表单的时候,此时有两种方案去获取:
1. 以上述讲解的方式,采取多个参数获取;
2. 将表单封装成一个对象,来获取对象,此时框架会自动填充对象中的值;
例如:发送请求,并针对以下这个对象来进行接收:
@RequestMapping("/reg")public Object register(Userinfo userinfo){ System.out.println(userinfo);return userinfo; }
此处的返回类型定为 Object,返回时在系统中会进行判定,如果是一个自定义对象,那么会转换为 application/json 的形式进行返回,如果是 String 类型,且有 html 标签,那么会以 html 形式进行打印返回;
也就是框架会实现自动的参数映射;
@RequestMapping("/h1")public Object getH1(){return "<h1>我是h1</h1>"; // 此时经过识别后,Content-Type:text/html;}
4. 重命名功能
当出现前端的命名和后端接口使用的命名不一样的时候,要用重命名来解决;
使用 @RequestParam(value="前端传过来的名字",require="boolean") String name
此时前端传递的参数为 username 也是可以被接收的,也就是接收 username 来代替 name;
在@RequestParam中还有一个require方法,其值默认为 true,true的时候就表示前端必须传入 username 参数,否则会报错,也可以设为 false,也就会避免报错;
// 重命名的功能:例如前端和后端接口使用的命名不一样,如何解决?@RequestMapping("/reg2")// 非必须传的参数的时候,required可以为falsepublic Object register2(@RequestParam(value = "username",required = false) String name , String password){ // 此时前端传递的参数名称为username也是可以的,@RequestParam中还有一个默认方法(默认为true):true的时候必须传入该参数(username),否则报错,也可以设为false,就可以避免这种情况了,但此时也拿不到name值了,因为name已经默认被usernamee替代了,只认username了return name + " : " + password;}
5. 获取 JSON 对象
当传递过来的是一个 JSON 对象的时候,此时需要进行额外的注解说明;
使用 @RequestBody 注解;
@RequestMapping("/reg3")public Object register3(@RequestBody Userinfo userinfo){return userinfo;}
6. 通过 path 文件路径来传递参数
使用 path 文件路径传递参数会让 url 更加简洁,适用于参数少的情况,且搜索引擎抓取关键字的权重更高;
需要在路由映射中对要传递参数的 key 值进行配置:
@RequestMapping("/reg4/{key}/{key}/{key}")
对参数进行注解配置:
@PathVariable,这个注解同样有 重命名 的方法,也有 require 方法
// 通过 path(url) 来传参 -> /user/12345 = /user?uid=12345@RequestMapping("/reg4/{name}/{password}/{id}") // 顺序要依次对应public Object register4(@PathVariable("password") String password1,@PathVariable String name,@PathVariable(required = false) Integer id){ //一样有上述的(required = false)限制return "name: "+name+" password: "+password1+" id: "+id;}
7. 上传文件
在参数中要使用注解:@RequestPart("key值") 然后使用 MultipartFile 类型来接收;
可以创建一个新的文件,然后使用 transferTo 方法来进行存储;
@RequestMapping("/myupload")public Object upload(@RequestPart("myimg2")MultipartFile file){ // 要用 MultipartFile 接收File saveFile = new File("D:\\test\\myimg.png");try {file.transferTo(saveFile);return true;} catch (IOException e) {e.printStackTrace();}return false;}
但是这种上传文件的方式并不符合生产环境,因为在每一次的上传中,都会覆盖上一次生成的文件,所以要解决文件覆盖的问题。可以从文件名上去解决问题,每一次存储的文件名都不一致的时候,就不会有文件覆盖的问题。
使用 UUID.randomUUID() 方法获取唯一名(UUID可以保证每一次获取到的文件名都是不重复的,指定文件名是根据网卡信息+时间戳+随机数),再用 file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") ) 来获取到 .后缀
@RequestMapping("/myupload2")public Object upload2(@RequestPart("myfile")MultipartFile file){String fileName = UUID.randomUUID()+ // 文件名 + 原文件名后缀名 -> 拼一起就是文件名file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); // 包含 .File saveFile = new File("D:\\test\\"+fileName);try {file.transferTo(saveFile);return true;} catch (IOException e) {e.printStackTrace();}return false;}
此时进行三次文件传送,获取并存储的三个文件就不会有覆盖问题了,符合生产环境。
补充: 可以通过配置文件来设置文件的最大容量;
spring:servlet:multipart:max-file-size: 100MB
8. 获取 cookie 和 header 中的某个信息
获取 cookie 使用 @CookieValue(value="要获取的cookie名") 注解;
获取 header 中的信息使用 @RequestHeader(value="要获取的属性名") 注解;
两个注解同样都有 require 方法;
@RequestMapping("/getck")public Object getck(@CookieValue(value = "java",required = false) String java){ // @CookieValue 参数为 cookie 名称return java;}
@RequestMapping("/gethd")public Object getHeader(@RequestHeader(value = "Host",required = false) String host){ // @CookieValue 参数为 cookie 名称return host;}
此处也可以使用 servlet 的方式来进行:
获取cookie:Cookie[] cookies = request.getCookies();
获取header属性:String userAgent = request.getHeader("User-Agent");
9. 获取 session 和存储 session
此处获取 session 的方式和 servlet 的方式是一致的;
private static final String SESSION_KEY = "USERINFO_SESSION_KEY";@RequestMapping("/setsess")public void setSession(HttpServletRequest request){HttpSession session = request.getSession(true); // 没有 session 则创建一个session.setAttribute(SESSION_KEY,"zhangsan");}
获取 session 的时候使用注解 @SessionAttribute(key值)
也可以使用 servlet 的方式:session.getAttribute("key值");
@RequestMapping("/getsess")public Object getSession(@SessionAttribute(SESSION_KEY) String name){return name;}