Spring Boot2 学习笔记之获取 get,post 请求 (一)
2021 年的目标,掌握 java 与 spring boot2 用来开发 web 应用,作为开始,首先从获取请求入手!
创建 spring boot 项目
在这里使用 idea 里的 Spring Initializr 创建,选项里选择 Spring Boot DevTools , Lombok , Spring Web 这 3 个
pom.xml 文件如下
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.request</groupId> <artifactId>request</artifactId> <version>1.0.0</version> <name>request</name> <description>Request Demo project for Spring Boot</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
点击创建即可,然后安装 java 依赖包,在 Application 文件目录下创建一个 controller 目录
在 controller 目录下创建我们的 controller,进行测试获取请求参数。
解析请求路径
首先我们要解析请求路径,即浏览器访问路径为“/v1/first”时,该 java 程序需要知道使用哪个控制器进行处理
在这里类上使用了 Slf4j 和 RestController 2 个注解,方法有 GetMapping(“/v1/first”) 注解
@Slf4j @RestController public class TestGet { @GetMapping("/v1/first") public String first(){ return "hello first!"; } }
获取 get 请求
下一步获取 path 参数,类似于”/v1/user/{id}
“这样的路由,需要获取 id 的值
在这里类上使用 @RequestMapping("/v1")
,可以将路径前缀统一设置为 v1
方法上使用@GetMapping("/secend/{id}")
,这里需要接受参数,path 变量使用@PathVariable("id")
注解进行获取
代码如下:
@Slf4j @RestController @RequestMapping("/v1") public class TestGet { @GetMapping("/first") public String first(){ return "hello first!"; } @GetMapping("/second/{id}") public String secend(@PathVariable("id") long id){ return "Your Id is "+id; } }
在方法中使用 @RequestParam("t")
来获取 t 参数
@GetMapping("/three") public String three(@RequestParam("t") String t){ return "t 参数为 "+t; }
如果需要获取 t 参数是多个的话,可以使用 Array 来接收参数
@GetMapping("/three") public String three(@RequestParam("t") String[] t){ return "t 参数为 "+ Arrays.toString(t); }
如果参数很多的话,怎么放到 Map 中呢?
@GetMapping("/three") public String three(@RequestParam Map<String,String> t){ String res = "t 的参数为:"; for(String k : t.keySet()){ res += k+" : "+t.get(k)+";"; } return res; }
如果参数里面既有同名参数,又有异名参数,参数很多且类型不同时,类似于“?a=123&b=abc&b=222
”
我们可以构建一个类来接收参数
//Book 类 @Data @Component public class Book { private String name; private List<String> ids; } //TestGet 类中 @Autowired Book Book; @GetMapping("/four") public String four(Book book){ String res = "book 参数有:name:"+book.getName() + " ids:"+String.join(",", book.getIds()); return res; }
也可以构建多个对象,但是如果有多个对象,对象有同名参数的时候该如何处理?
接下来再构建一个 Author 对象
//定义 Author 数据对象 @Data @Component public class Author { private String name; } //TestGet 控制器内 @Autowired Book Book; Author Author; // 添加 InitBinder 指定 前缀 book @InitBinder("book") private void initBinderBook(WebDataBinder binder) { binder.setFieldDefaultPrefix("book."); } // 添加 InitBinder 指定 前缀 author @InitBinder("author") private void initBinderAuthor(WebDataBinder binder) { binder.setFieldDefaultPrefix("author."); } @GetMapping("/four") public String four(@ModelAttribute("book") Book book,@ModelAttribute("author") Author author){ String res = "book 参数有:name:"+book.getName() + " ids:"+String.join(",", book.getIds()); res += " author 参数有 name:"+author.getName(); return res; }
获取 post 请求
@Slf4j @RestController @RequestMapping("/v1") public class TestPost { @PostMapping(value="first") public String first(@RequestParam(value="name",defaultValue = "") String name,@RequestParam(value="author",defaultValue = "") String author){ return "名称:"+name+" 作者:"+author; } }
使用@RequestParam
来获取 post 参数,使用defaultValue 来设置默认值
如果参数特别多的话,我们可以放到 hashMap 中来获取参数
@PostMapping(value="second") public Map<String,Object> second(@RequestParam HashMap<String,Object> req){ Map<String,Object> res = new HashMap<>(); res.put("name",req.get("name")); res.put("author",req.get("author")); return res; }
如果哪一项不传的话,该项的值为 Null
当然我们也可以使用对象来接收数据
@Autowired Book Book; @PostMapping(value="three") public Map<String,Object> three(Book book){ Map<String,Object> res = new HashMap<>(); res.put("name",book.getName()); res.put("ids",book.getIds()); return res; }
有时候需要获取 json 格式的数据,可以在方法中加入@RequestBody
注解
该注解需要请求参数在 body 里,且请求头必须有Content-Type: application/json
@PostMapping(value="four") public Map<String,Object> four(@RequestBody Book book){ Map<String,Object> res = new HashMap<>(); res.put("name",book.getName()); res.put("ids",book.getIds()); return res; }