SpringBoot(二) 接收并处理请求及静态文件处理
这是Spring Boot的第二篇笔记,上一篇记录了如何安装软件并简单实现Hello World。之前说过,自己关于动态网站只学过JSP,涉猎过Django/Flask,因此不是很习惯网上Spring Boot教程,于是有了这个系列。按照习惯,一般都是在动态项目里实现静态页面展示、接着实现处理Requests及返回Response,因此本文分为两个部分。
静态文件部分
静态文件可以存放在resources文件夹下的resources、static、public文件夹下,可以自行建立以下名字的文件夹。
我是如何知道静态文件存放规则的呢?
可以从org.springframework.boot.autoconfigure.web包中的ResourceProperties.java中看到关于静态文件位置的代码。当然我觉也可以在src>resources下的application.properties文件里面改这个,但没必要。
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
/**
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
实现
在public下新建一张名为login的HTML文件,展示一张简单的登录页面,代码如下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form>
<input type="text" name="email">
<input type="password" name="pswd">
<button type="submit"> 提交</button>
</form>
</body>
</html>
启动程序,访问localhost:8080/login.html,成功看到奇丑无比的页面。
处理动态请求
之前JSP的方法是java写Servlet、前端使用Ajax,实现前后端分离。
在spring里有三种方式可以接受请求
- @PathVariable
- @RequestParam
- @RequestBody
@PathVariable
[1]https://book.douban.com/subject/30302069
[2]https://book.douban.com/subject/3616310
[3]https://www.douban.com/people/sunmker
[4]https://www.douban.com/people/ahbei
12是豆瓣书籍页面,34为豆瓣用户资料页面。
这两组URL都是要规律的,即变化的是最后部分,这个时候使用@PathVariable注解比较合适
@RequestMapping("/subject/{id}")
//获取书号
public viod getById(@PathVariable int id){
……
}
@RequestMapping("/people/{name}")
//获取书号
public viod getByName(@PathVariable String name){
……
}
@RequestParam
@RequestParam和@RequestBody都可以获取请求,但是两者对于请求的Content-Type要求不一样。
Content-Type | |
---|---|
@RequestParam | application/x-www-form-urlencoded |
@RequestBody | application/json |
提交请求有常用get/post两种方式,@RequestParam都可以获取,不管是get方法显示在URL中还是post隐藏在requests中。
因此,所以不要单纯以为@RequestParam只能获取下面这种方式的参数,POST也是可以的。
https://book.douban.com/people/sunmker/collect?start=30&sort=time&rating=all&filter=all&mode=grid
这串url是我的豆瓣「已读」的第三页,可以看到一连串的键值对,如起始值=30、排序方式为时间顺序等,使用RequestParam来读取键值对
@RequestMapping("/collect")
//获取start、sort参数
//defaultValue设置默认参数,也可以想sort处简写
public void user(@RequestParam(value="start", defaultValue="0") int id,@RequestParam("sort") String name) {
……
}
@RequestBody
@RequestBody的好处就是在于可以接受一个json的对象,可以和现有的java类很好的结合在一起,代码为例。
- Employee.java(注意,一定要写上get/set方法)
package cn.sunmker.demo;
class Employee {
private String email;
private String pswd;
Employee(){}
public Employee(String email, String pswd) {
this.email = email;
this.pswd = pswd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPswd() {
return pswd;
}
public void setPswd(String pswd) {
this.pswd = pswd;
}
}
- RR.java
package cn.sunmker.demo;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
public class RR {
List<Employee> all = new ArrayList();
{
all.add(new Employee("1@qq.com", "1"));
all.add(new Employee("2@qq.com", "2"));
all.add(new Employee("3@qq.com", "3"));
}
@GetMapping("/getNum")
public int getNum() {
return all.size();
}
@RequestMapping("/addOne")
public void addOne(@RequestBody Employee employee) {
all.add(employee);
}
@GetMapping("/getId/{id}")
public Employee getByid(@PathVariable int id){
return all.get(id);
}
@RequestMapping("/getAll")
public List<Employee> getAll() {
return all;
}
}
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<form>
<input type="email" name="email" id="inputEmail" required autofocus>
<br>
<input type="password" name="pswd" id="inputPassword" required>
<button type="submit" onclick="ssd();">Sign in</button>
</form>
<script>
function ssd() {
a = $(inputEmail).val();
b = $(inputPassword).val();
console.log(a, b);
$.ajax(
{
type: 'post',
url: 'addOne',
data: JSON.stringify({"email": a, "pswd": b}),
contentType: "application/json",
dataType: 'JSON',
}
)
}
</script>
</body>
</html>
addOne使用了@RequestBody注解,index.html中使用ajax制造application/json的post请求。
可以使用getNum查看数量是否增加。
@RequestBody可以使用Get方法吗?
用ajax不行,postman/httpei可以,网上的例子也都是用POST的,先留个疑惑,往下走。
总结
一般来说,感觉还是@RequestParam,@PathVariable比较常用,@RequestBody看起来比较高级,但是感觉适用场景比较少。