小玉非常难过,昨天想着把1024那天写的博客继续编辑完成,结果不知道CSDN上编辑已经发布的文章没有自动保存的功能,然后上了个厕所,edge浏览器自动关闭了,5000多字的文章全没了.......昨天哭成泪人了,今天小玉调整好心情继续编辑,跟着小玉一起来学习吧~~~
目录
3.8获取Session @SessionAttribute
3.SpringBoot MVC如何获取参数?
*参数重命名@RequestParam
在这里小玉也要补充一下:在前一篇我们讨论了如何获取多个参数,有一种情况是前端传来的参数,后端不想继续使用这个变量名的话是可以对参数重命名的(因为前端传来的参数需要根据名字匹配后端才能继续使用),那么如何重命名参数呢?这里用到了一个注解:
@RequesrParam("待重命名的参数")+重命名之后的参数类型和新名称
此处以name参数为例:
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Created with IntelliJ IDEA.
* Description:传递多个参数
* User: yyx
* Date: 2023-10-25
* Time: 14:06
*/
@RestController
@RequestMapping("/test3")
public class TestContorller3 {
@RequestMapping("/getparams")
public String getParams(@RequestParam("n")String name, int id, String password){
return "name"+name+"id"+id+"password"+password;
}
}
此时我们键入URL或使用postman验证:
这里需要注意一下的是:后端获取前端参数的时候是根据名字匹配的,与参数传递的顺序无关!!
但是同时我们也发现了一个问题:重命名参数之后,之前的参数名称还能使用吗?我们还用name为例验证:
好像不能使用了(因为现在是钮祜禄·name),但是我们不希望这样的事情发生,有没有不报错的设置呢?
这里就要用到一个@RequestParam注解当中的属性了:required 我们按住ctrl建鼠标点击这个注解看源码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
里面有个布尔类型的属性叫required 默认是TRUE,代表着重命名之后原名字不可使用,必须传入一个次名称的参数,不然就会报错400,将required=false 来避免不传递时报错,演示如下:
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Created with IntelliJ IDEA.
* Description:传递多个参数
* User: yyx
* Date: 2023-10-25
* Time: 14:06
*/
@RestController
@RequestMapping("/test3")
public class TestContorller3 {
@RequestMapping("/getparams")
public String getParams(@RequestParam(value = "n",required = false)String name, int id, String password){
return "name"+name+"id"+id+"password"+password;
}
}
(输入required属性的时候前面会自动匹配value属性) ,再次键入URL验证:
我们发现不报错了,但是代价是这个参数拿不到了.......
3.4获取Json对象@RequestBody
有的码友会问:我们前面不是已经讨论了传入对象的情况了吗?这里这么又讨论ne?小玉想澄清一下: 对象和json对象是完全不一样的存在!!我们利用代码来验证一下:这里需要用到一个注解@RequestBody
我们还是利用model包里面的user类,然后再创建一个TestController类验证如下:
package com.example.demo.model;
import lombok.Data;
/**
* Created with IntelliJ IDEA.
* Description:
* User: yyx
* Date: 2023-10-24
* Time: 22:04
*/
@Data
public class User {
private int id;
private String name;
private String password;
}
package com.example.demo;
import com.example.demo.model.User;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created with IntelliJ IDEA.
* Description:接受json对象
* User: yyx
* Date: 2023-10-25
* Time: 14:51
*/
@RestController
@RequestMapping("/test4")
public class TestController4 {
@RequestMapping("/getjson")
public User getJson(@RequestBody User user){
return user;
}
}
我们使用postman验证一下:这里有一些细节需要注意:上图:
json对象有格式要求:
- 使用花括号{}代表一个json对象
- 里面的属性以键值对的形式存在
- key值使用""引起来
- 键和值之间使用冒号:隔开
- 键值对之间使用逗号,隔开
假如我们去掉这个注解再次使用postman验证:
此时我们发现,在body中继续使用json对象的方式发送post请求,但是却拿不到这个参数了.
这就是对象和json对象最大的区别,这取决与你前端传递过来的参数是普通的参数(URL中?后面的内容或者是表单里的数据) 还是 json对象!!!
3.5获取URL中参数@PathVariable
有的码友又不服气了,之前那参数的时候不就是从URL中拿的吗?这会怎么又来说?
小玉再次澄清一下:之前拿参数是从URL的参数部分(?后面的内容拿),但是这里讨论的是从URL非参数部分拿:
这里需要注意了:在@RequestMapping中传入路由的时候, 你就需要吧路由的一部分当做参数,这里的参数需要使用{}花括号引用起来,方便后端代码识别
package com.example.demo;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created with IntelliJ IDEA.
* Description: 从非参数部分的URL中获得参数
* User: yyx
* Date: 2023-10-25
* Time: 15:33
*/
@RestController
@RequestMapping("/test5")
public class TestController5 {
@RequestMapping("/geturlparams/{name}/{id}")
public String getURlparams(@PathVariable("name")String name,
@PathVariable("id")int id){
return "name "+name+"id "+id;
}
}
此时我们键入二级路由的时候就可以在二级路由上传参了:
此时我们就发现这里的参数可以当做URL的"实体"的一部分了,假如我们更换位置:
这里就不能再是名称匹配了,因为根本就没有名称,这里的顺序不可调换,否则400,小玉也不知道为什么要这样设计但是有一点好处就是:?后面的参数是可变的,这里的参数相当于URL的"实体"的一部分了,查询起来速度会更快...
3.6上传文件@RequestPart
假如我们前端传来的是文件作为参数,我们如何拿到像文件这样的二进制流呢?这篇是重点,项目中可能"更换头像"的时候会用到~~~此时需要用到一个注解:@RequestPart("文件名")
此时我们要注意:文件的类型是MultipartFile file
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* Created with IntelliJ IDEA.
* Description: 上传文件,如何获取文件这样的二进制流
* User: yyx
* Date: 2023-10-25
* Time: 15:55
*/
@RestController
@RequestMapping("/test6")
public class TestContorller6 {
@RequestMapping("/getfile")
public String getFile(@RequestPart("myfile") MultipartFile file) throws IOException {
file.transferTo(new File("d:\\img\\yyx.png"));
return "success";
}
}
此时我们也必须使用postman验证了:同样细节很多,看图说话并对照着下面的1--7步骤:
- 必须使用post方式提交
- 选择body
- 选择form-data
- 在key值的表单里选择file
- 选择file
- 填入的key值必须和后端中 @RequestPart("文件名")文件名保持一致,否则无法匹配
- 在选择完file(第五步之后)后面会有一个按钮[select file]点击选择一个文件(以照片为例,因为我的后端写的文件保存在d:\img\yyx.png 是以.png结尾的)
然后我们打开d盘我选择了一张小玉的美照,看看存进去了没....
哈哈哈,是有的....
但是这样的话,我们发送多次请求,只能得到一张照片,之前的照片因为保存的路径是 d:\img\yyx.png,都被覆盖了,这样是不科学的,我们希望多次存入照片之后,哪怕是同一张照片也能单独出现....
这里我们就要对文件名下手了,我们主要有两步:
1.假如我们要保存的是视频或者GIF文件,那都用.png作为后缀是不是不太好 ,所以我们希望获得原文件的后缀名作为保存后文件的后缀名,这样能保证文件不被损坏.
2.我们希望每次生成不一样的文件名,这样就不会出现文件覆盖的问题了.
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* Created with IntelliJ IDEA.
* Description:
* User: yyx
* Date: 2023-10-25
* Time: 15:55
*/
@RestController
@RequestMapping("/test6")
public class TestContorller6 {
@RequestMapping("/getfile")
public String getFile(@RequestPart("myfile") MultipartFile file) throws IOException {
//获取文件后缀名(.png/.gif)
String lastFile = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'))
//使用UUID(由特殊的算法实现的全球唯一变量)拼接上后缀名
String newFile = UUID.randomUUID() + lastFile;
file.transferTo(new File("d:\\img\\"+newFile));
return "success";
}
}
postman验证:多发送几次post请求
3.7获取Cookie@CookieValue
下面我们研究一下如何获取cookie,以前我们学习servlet的时候是通过HttpServletRequest获取cookie的,但是在框架中我们只需要 一个注解即可:@CookieValue("cookie名称")
package com.example.demo;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created with IntelliJ IDEA.
* Description:获取cookie
* User: yyx
* Date: 2023-10-26
* Time: 15:21
*/
@RequestMapping("/test7")
@RestController
public class TestContorller7 {
@RequestMapping("/cookie")
public String getCookie(@CookieValue(value = "mycookie",required = false) String ck){
return ck;
}
}
此时我们就需要模拟一个cookie,先给这个注解设置一个required= False,然后再页面当中右键单击选择"检查" ,选择应用程序,点击cookie,在里面输入键值对:
3.8获取Session @SessionAttribute
由于session是服务器端的东西,我们只能通过代码设置session(用servlet的办法):
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* Created with IntelliJ IDEA.
* Description:获取session
* User: yyx
* Date: 2023-10-26
* Time: 15:46
*/
@RequestMapping("/test8")
@RestController
public class TestController8 {
@RequestMapping("/session")
public String setSession(HttpServletRequest request){
HttpSession session = request.getSession();
if(session != null){
session.setAttribute("session","张三");
return "ok";
}else {
return "fail";
}
}
@RequestMapping("/session2")
public String getSession(@SessionAttribute(value = "session",required = false)String se){
return se;
}
}
在URL键入验证:
4.返回数据
4.1返回.HTML页面
首先我们在resource里面的static中建一个index.html
内容如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>这是杨已萱的HTML页面</title>
</head>
<body>
<h1>
hi springbootMVC view!
</h1>
</body>
</html>
创建一个启动类TestController(默认包下面):
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Created with IntelliJ IDEA.
* Description:
* User: yyx
* Date: 2023-10-26
* Time: 17:30
*/
@Controller
@RequestMapping("/test9")
public class TestController9 {
@RequestMapping("/index")
public String index(){
return "/index.html";
}
}
注意这里的注解直接用@Controller不用@RestController了,因为返回的是页面,注意return的时候加上""双引号和/表示路由,路由名称要和你在recourse static下面创建的是一样的!
键入URL验证:
抓个包看看:
4.2返回Json对象
假如我们传给前端的不是一个html页面或者是一个普通字段的话,那就以json对象为例:
package com.example.demo;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Set;
/**
* Created with IntelliJ IDEA.
* Description:返回json对象
* User: yyx
* Date: 2023-10-26
* Time: 17:50
*/
@RequestMapping("/test10")
@ResponseBody
@Controller
public class TestController10 {
@RequestMapping("/json")
public HashMap<String,String> json(){
HashMap<String,String> map = new HashMap<>();
map.put("java","JAVA");
map.put("mysql","MYSQL");
map.put("redis","REDIS");
return map;
}
}
键入URL验证:
呼~~小玉终于吧这些内容梳理完了,这篇博客是小玉呕心沥血制作完成的,思路很清楚,有代码印证,图文呼应,保证让各位码友们能清除理解,希望码友们能get到小玉的idea,跟着小玉实操一遍,这样数极大的熟悉spring boot的常用注解,真的是忘不了,小玉希望各位不要怕学习框架知识,要相信,框架服务于程序员,不要把它神化,难化,更不可以不实操,这样的话,光看光学是远远达不到熟练使用的地步的.....相信未来大家都不会被面试官问倒,也相信大家有驾驭框架,甚至有实现框架的一天!!!