SpringBoot快速上手
文章目录
- SpringBoot快速上手
- 案例
- SpringMVC小结
学习流程介绍:
- spring boot
- springmvc
- spring framework
- mybatis
- spring 源码
Maven
项目管理工具,idea中将他嵌入进来了
- 项目构建、打包
- 依赖管理
会出现的一个官方bug
创建完项目之后
常用的的三个功能
依赖管理
通过poe.xml
依赖已经进来了.
-
会将当前的依赖引入到当前项目里面
-
Maven Helper
插件,可以查看依赖之间的关系
Maven仓库
中央仓库
中央仓库
中央仓库查询会有一定的滞后性
本地仓库
需要自己配置噢
国内源配置
找到setting.xml
文件,在 mirrors 节点上,添加内容如下:
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>阿⾥云公共仓库</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
然后再设置好新项目的setting
.建议找一个存储空间大的盘,像我一样设置(如上图).因为随着时间推移,外卖做的项目的数量变多,本地仓库中的setting
文件的占用的内存也会越来越多.
还有就是建议命名不要用中文!
私服
企业开发中一些代码具有一定的私密性,所以企业会建立自己的私服(需要账号密码)
springboot项目创建
建议是申请教育版本的ideaa或者专业版的idea噢~
如果是社区版的idea,那么就需要你去下载spring
插件
别直接点击Install
,除非你钱多~
插件地址
什么是spring
spring是一个非常好用的框架,快 简单 安全
spring是一个家族产品,在面试中提到spring,大多是指spring家族.
而spring boot的诞生就是未来简化spring程序开发的
spring boot项目的创建
-
需要注意的是现在idea2023创建spring项目的时候,只有
jdk17 jdk21
,可以选择,这里我的解决办法是替换项目的源头,我们只知道IDEA页面创建Spring项目,其实是访问spring initializr去创建项目。故我们可以通过阿里云国服去间接创建Spring项目。将https://start.spring.io/或者http://start.springboot.io/替换为 https://start.aliyun.com/.即可解决这个问题. -
-
选择springboot版本,选择
2.X
版本,因为2.X
使用的是JDK8
,也不要选择snapshot
版本.(不稳定版本) -
-
-
此处的测试代码,和测试人员无关,是开发人员的测试代码,
开发人员先进行简单测试,测试完成之后再提交给测试人员.单元测试代码
-
项目启动
Hello World
创建HelloController
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello, SpringBoot";
}
}
然后再网页中输入localhost:8080/hello
web服务器
常⻅的Web服务器有: Apache,Nginx, IIS, Tomcat, Jboss
等
SpringBoot 内置了Tomcat服务器, ⽆需配置即可直接运⾏
Tocmat默认端⼝号是8080, 所以我们程序访问时的端⼝号也是8080
SpringMVC
本小节将会了解到的:
- 学习常见的
Spring MVC Web
注解 - 了解
SPring MVC
来完成基础功能开发 - 了解
MVC
和三层架构的设计模式 - 掌握企业开发的命名规范
什么是SpringWebMVC
Spring Web MVC
是基于Servlet API
构建的原始Web框架,从一开始就包含在Spring
框架中。它的正式名称“Spring Web MVC”
来自其源模块的名称(Spring-webmvc)
,但它通常被称为"SpringMVC
".
什么是MVC
MVC
是一种思想,而Spring MVC
是MVC
的一种实现
SpringMVC
SpringMVC
项目的创建和上面创建SpringBoot
项目一样.
不过目前推崇的前后端分离已经不需要View
层了,于是乎:
学习Spring web mvc
建立连接
@RequestMapping
类注解、方法注解
作用范围:
-
类
-
方法上
@RestController public class UserController { @RequestMapping("/hello") public String hello() { return "hello"; } }
请求方式是Get
还是Post
get
通过浏览器访问的方式为get
post
请求
指定请求方式
@RequestMapping("/user")
@RestController
public class UserController {
@RequestMapping(value = "/hello",method = RequestMethod.GET)
// 注解里,双引号的值会赋给"value"这个属性
// 只有一个属性的时候,且属性名为value,可以省略
public String hello()
{
return "hello";
}
}
请求单个参数
@RequestMapping("/r1")
public String r1(String name){
return "接受到参数 name:" + name;
}
@RequestMapping("/r2")
public String r2(int age){
return "接受到参数 age:" + age;
}
请求多个参数
@RequestMapping("/r3")
public String r3(String name,Integer age){
return "name:"+name+" "+"age:"+age;
// 参数请求 顺序先后不分
}
传递对象
// 创建userInfo
public class UserInfo {
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "UserInfo{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
@RequestMapping("/r4")
public String r4(UserInfo user){
return user.toString();
}
参数重命名
@RequestParam
@RequestMapping("/r5")
public String r4(@RequestParam("name") String username, Integer age){
return "username: " + username+ ", age: " + age;
}
@RequestParam(“name”) 从请求中获取 name 的参数,并且赋值给 username 参数 且默认这个参数是必传的
设置参数为非必传的
我们先看一下RequestParam
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
设置为false
@RequestMapping("/r5")
public String r5(@RequestParam(value = "name", required = false) String username, Integer age){
return "username: " + username+ ", age: " + age;
}
传递数组
@RequestMapping("/r7")
public String r7(String[]arr){
return Arrays.toString(arr);
}
传递集合
@RequestMapping("/r8")
public String r8(@RequestParam("list") List<String> list){
return list.toString();
}
传递JSON
数据
JSON与Javascript的关系
JSON 优点
-
简单易⽤: 语法简单,易于理解和编写,可以快速地进⾏数据交换
-
跨平台⽀持: JSON可以被多种编程语⾔解析和⽣成, 可以在不同的平台和语⾔之间进⾏数据交换和传输
-
轻量级: 相较于XML格式, JSON数据格式更加轻量级, 传输数据时占⽤带宽较⼩, 可以提⾼数据传输速度
-
易于扩展: JSON的数据结构灵活,⽀持嵌套对象和数组等复杂的数据结构,便于扩展和使⽤
-
安全性: JSON数据格式是⼀种纯⽂本格式,不包含可执⾏代码, 不会执⾏恶意代码,因此具有较⾼的安全性
public class JSONUtils {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
UserInfo userInfo = new UserInfo();
userInfo.setName("zhangsan");
userInfo.setAge(18);
userInfo.setId(12);
// 对象转 JSON
String s = objectMapper.writeValueAsString(userInfo);
System.out.println(s);
// JSON 转成 java 对象
UserInfo userInfo1 = objectMapper.readValue(s,UserInfo.class);
System.out.println(userInfo1);
}
}
@RequestMapping("/r9")
public String r9(@RequestBody UserInfo userInfo){
return userInfo.toString();
}
获取URL中的参数
@PathVariable
@RequestMapping("/r10/{articleId}")
public String r10(@PathVariable Integer articleId){
return "articleId:"+articleId;
}
上传文件
@RequestPart
@RequestMapping("/r11")
public String r11(@RequestPart MultipartFile file){
return "获取上传文件:" + file.getOriginalFilename();
}
@RequestMapping("/r11")
public String r11(@RequestPart MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
file.transferTo(new File("D:/temp/"+fileName));
return "获取上传文件:" + file.getOriginalFilename();
}
这段代码虽然也可以不加注解,但是建议还是将注解加上去
获取Cookie/Session
Cookie
HTTP 协议⾃⾝是属于 “⽆状态” 协议.
但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
Session
会话:对话的意思
在计算机领域, 会话是⼀个客⼾与服务器之间的不中断的请求响应. 对客⼾的每个请求,服务器能够识
别出请求来⾃于同⼀个客⼾. 当⼀个未知的客⼾向Web应⽤程序发送第⼀个请求时就开始了⼀个会话.
当客⼾明确结束会话或服务器在⼀个时限内没有接受到客⼾的任何请求时,会话就结束了.
服务器同⼀时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是从属于哪个⽤⼾, 也就是属于哪个会话, 就需要在服务器这边记录每个会话以及与⽤⼾的信息的对应关系.
Session
是服务器为了保存⽤⼾信息⽽创建的⼀个特殊的对象.
Session的本质就是⼀个 “哈希表”, 存储了⼀些键值对结构. Key 就是SessionID, Value 就是⽤⼾信息(⽤⼾信息可以根据需求灵活设计).
-
当⽤⼾登陆的时候, 服务器在 Session 中新增⼀个新记录, 并把 sessionId返回给客⼾端. (通过HTTP 响应中的 Set-Cookie 字段返回).
-
客⼾端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId. (通过 HTTP 请求中的Cookie 字段带上).
-
服务器收到请求之后, 根据请求中的 sessionId在 Session 信息中获取到对应的⽤⼾信息, 再进⾏后续操作.找不到则重新创建Session, 并把SessionID返回
Cookie和Session的区别
在此之前我们可以举一个例子
-
用户提供账号和密码,服务器进行验证。
-
服务器验证通过,会把信息存储在
Session
中,把SessionId
返回给客户端(通过Set-Cookie
的方式) -
客户端收到响应,把
sessionID
存储在Cookie
中 -
后续的请求中,客户端带着
SessionID
去请求(带着Cookie
信息去请求)request.getSession
就是从Cookie
中获取SessionID
,并且根据SessionID
获取Session
信息
区别如下:
Cookie
是客户端保存用户信息的一种机制.Session
是服务器端保存用户信息的一种机制:Cookie
和Session
之间主要是通过Sessionld
关联起来的,Sessionld
是Cookie
和Session
之间的桥梁Cookie
和Session
经常会在一起配合使用.但是不是必须配合.- 完全可以用
Cookie
来保存一些数据在客户端.这些数据不一定是用户身份信息,也不一定是Sessionld
Session
中的sessionld
也不需要非得通过Cookie
/Set
-Cookie
传递,比如通过URL
传递
- 完全可以用
共同点:都是会话机制
Cookie
是客户端机制
Session
是服务器机制
传统方式获取Cookie
@RestController
@RequestMapping("/request")
public class RequestController {
@RequestMapping("/getCookie")
public String getCookie(HttpServletRequest request) // 内置对象,有需要就加上,没需要就不加 需要几个就加几个
{
Cookie[] cookies = request.getCookies();
// Arrays.stream(cookies).forEach(x->{
// System.out.println(x.getName()+":"+x.getValue());
// });
// 等价于
if (cookies != null){
for(Cookie c:cookies){
System.out.println(c.getName()+":"+c.getValue());
}
return "获取Cookies成功";
}
else
return "获取Cookies不成功";
}
}
SpringBoot获取Cookie
@RequestMapping("/getCookie2")
public String getCookie2(@CookieValue ("riyewuxiushi")String riyewuxiushi){
return "riyewuxiushi"+riyewuxiushi;
}
传统方式获取Session
@RequestMapping("/setSession")
public String setSession(HttpServletRequest request){
HttpSession session = request.getSession(); // 默认值为 true
session.setAttribute("userName","zhangsan");
return "设置session成功";
}
@RequestMapping("/getSession")
public String getSession(HttpServletRequest request){
HttpSession session = request.getSession();
String userName = (String) session.getAttribute("userName");
return "登录用户:"+ userName;
}
SpringBoot获取Session
@RequestMapping("/getSession2")
public String getSession2(HttpSession session){ // 内置对象
String userName = (String) session.getAttribute("userName");
return "登录用户:"+ userName;
}
@RequestMapping("/getSession3")
public String getSession3(@SessionAttribute(value = "userName",required = false) String userName){
return "登录用户:"+ userName;
}
获取Header
传统获取Header
@RequestMapping("/getheader")
public String getheader(HttpServletRequest request){
String userAgent = request.getHeader("User-Agent");
return "userAgent"+userAgent;
}
springboot方式获取Header
@RequestMapping("/getheader2")
public String getheader2(@RequestHeader("User-Agent")String userAgent){
return "userAgent"+userAgent;
}
响应
返回静态页面
@RequestMapping("/return")
//@RestController
@Controller
// 多个注解的时候 注解不分先后顺序
public class ReturnController {
@RequestMapping("/r1")
public String r1(){
return "/index.html";
}
}
@RestContraller
和 @Controller
的区别
@RestController
和 @Controller
是 Spring Framework 中用于标记类的注解,用于定义处理 HTTP 请求的控制器。它们之间有一些区别和联系。
区别:
- 返回值处理:
@Controller
通常用于创建传统的基于视图的 Web 应用程序,它的方法可以返回模型数据和视图名称,最终由视图解析器解析为具体的视图。而@RestController
则是用于创建 RESTful Web 服务的控制器,它的方法返回的是数据对象,会自动通过消息转换器将数据转为 JSON/XML 等格式,不会经过视图解析器。 - 默认行为:
@RestController
组合了@Controller
和@ResponseBody
注解的功能。@ResponseBody
注解表示方法的返回值将直接写入 HTTP 响应体中,而不是通过视图解析器解析为视图。因此,@RestController
类的每个方法都默认返回数据对象,而不是视图。 - 使用场景:
@Controller
适用于传统的基于视图的 Web 应用程序,例如使用 Thymeleaf、JSP 或者其他模板引擎渲染视图。@RestController
适用于构建 RESTful Web 服务,响应 JSON 或 XML 格式的数据。
联系:
- 标记作用:
@RestController
和@Controller
都是用于标记类的注解,将类声明为 Spring Framework 的组件,用于处理 HTTP 请求。 - 注解继承:
@RestController
是@Controller
注解的特殊化,可以认为是@Controller
的增强版本。@RestController
继承了@Controller
的所有功能,同时还提供了自动将方法返回值转换为数据格式的能力。
// @RestController 源码
@Target({ElementType.TYPE}) // 表示注解的范围
@Retention(RetentionPolicy.RUNTIME) // 注解的生命周期
@Documented //
// 上面三个是元注解:是可以注解到 其他注解 的注解
@Controller // ----> 这说明 RestContraller 是基于 Controller 实现的
@ResponseBody
public @interface RestController {
@AliasFor(
annotation = Controller.class
)
String value() default "";
}
@RestController = @Controller + @ResponseBody
路径问题
servlet
路径有项目名,是因为一个tomcat
下面可以部署多个项目,我们需要通过路径来进行区分spring
路径不需要有项目名,是因为springboot
内置了tomcat
,一个tomcat
下面就部署当前这一个项目- 如果部署多个项目,就启动多个
tomcat
一个项目部署多个服务
IDEA 2023.2新版如何将同一个项目开启多个
返回数据@ResponseBody
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
即可以修饰类,又可以修饰方法
@RequestMapping("/r1")
public String r1(){
return "/index.html";
}
@ResponseBody
@RequestMapping("/r2")
public String r2(){
return "hello spring";
}
返回HTML片段
@ResponseBody
@RequestMapping("/r3")
public String r3(){
return "<h1>我是返回的片段</h1>";
}
get
可以被缓存 幂等post
不可以被缓存
返回JSON
@ResponseBody
@RequestMapping("/r4")
public UserInfo r4(){
UserInfo userInfo = new UserInfo();
userInfo.setId(1);
userInfo.setName("zhangsan");
userInfo.setAge(19);
return userInfo;
}
@ResponseBody
@RequestMapping("/r5")
public Map<String ,String> r5(){
HashMap map = new HashMap();
map.put("k1","v1");
map.put("k2","v2");
return map;
}
//@ResponseBody
@RequestMapping("/r6")
public String r6(){
return "/a.js";
}
@RequestMapping("/r7")
public String r7(){
return "/b.css";
}
设置状态码
@ResponseBody
@RequestMapping("/r8")
public String r8(HttpServletResponse response){
response.setStatus(401);
return "设置状态码成功";
}
状态码的设置不影响页面的显示
设置Header
设置Content-Type
我们通过设置 produces属性的值, 设置响应的报头Content-Type
// @RequestMapping源码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
@ResponseBody
@RequestMapping("/r9")
public String r9(){
return "123333";
}
@ResponseBody
@RequestMapping(value = "/r9",produces = "application/json")
public String r9(){
return "123333";
}
设置其他Header
设置其他Header的话, 需要使⽤Spring MVC的内置对象HttpServletResponse 提供的⽅法来进⾏设置
@ResponseBody
@RequestMapping(value = "/r10",produces = "application/json")
public String r10(HttpServletResponse response){
response.setHeader("myHeader","myHeaderValue");
return "设置Header成功";
}
案例
学习建议:
加法计算器
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="calc/sum" method="post">
<h1>计算器</h1>
数字1:<input name="num1" type="text"><br>
数字2:<input name="num2" type="text"><br>
<input type="submit" value=" 点击相加 ">
</form>
</body>
</html>
后端代码
接口定义
@RestController
@RequestMapping("/calc")
public class CalcController {
@RequestMapping("/sum")
public String sum(Integer num1, Integer num2){
Integer sum = num1 + num2;
return "<h1>计算机计算结果: "+sum+"</h1>";
}
}
用户登录
前端代码
// login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h1>用户登录</h1>
用户名:<input name="userName" type="text" id="userName"><br>
密码:<input name="password" type="password" id="password"><br>
<input type="button" value="登录" onclick="login()">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
function login() {
$.ajax({
type:"post",
url:"/login/check",
data:{
userName:$("#userName").val(),
password:$("#password").val()
},
success:function(result){
if (result == true){
// 用户名和密码正确
location.href = "/index.html";
// location.assign("index.html");
// location.replace("index.html");
}else{
alert("用户名或密码错误");
}
}
});
}
</script>
</body>
</html>
// 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>用户登录首页</title>
</head>
<body>
登录人: <span id="loginUser"></span>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
$.ajax({
url:"/login/index",
type:"get",
success:function (result) {
$("#loginUser").text(result);
}
});
</script>
</body>
</html>
后端代码
@RequestMapping("/login")
@RestController
public class LoginController {
@RequestMapping("/check")
public boolean check(String userName, String password, HttpSession session){
// 校验账号和密码是否为空
// if (userName == null || "".equals(userName) || password == null || "".equals(password)){
// return false;
// }
if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
return false;
}
// 校验账号和密码是否正确
// 模拟数据
if("zhangsan".equals(userName) && "123456".equals(password)){ // 防止空指针,养成习惯 常量写在前面
session.setAttribute("userName",userName);
return true;
}
return false;
}
@RequestMapping("/index")
public String index(HttpSession session){
String userName = (String) session.getAttribute("userName");
return userName;
}
}
留言板
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>留言板</title>
<style>
.container {
width: 350px;
height: 300px;
margin: 0 auto;
/* border: 1px black solid; */
text-align: center;
}
.grey {
color: grey;
}
.container .row {
width: 350px;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
}
.container .row input {
width: 260px;
height: 30px;
}
#submit {
width: 350px;
height: 40px;
background-color: orange;
color: white;
border: none;
margin: 10px;
border-radius: 5px;
font-size: 20px;
}
</style>
</head>
<body>
<div class="container">
<h1>留言板</h1>
<p class="grey">输入后点击提交, 会将信息显示下方空白处</p>
<div class="row">
<span>谁:</span> <input type="text" name="" id="from">
</div>
<div class="row">
<span>对谁:</span> <input type="text" name="" id="to">
</div>
<div class="row">
<span>说什么:</span> <input type="text" name="" id="say">
</div>
<input type="button" value="提交" id="submit" onclick="submit()">
<!-- <div>A 对 B 说: hello</div> -->
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
// 页面加载时,显示留言信息
// 从后端获取留言信息,显示在页面上
$.ajax({
type:"get",
url:"/message/getList",
success:function (messages) {
for (var message of messages){
var html = "<div>"+message.from+"对"+message.to+"说:"+message.message+"</div>";
$(".container").append(html);
}
}
});
function submit(){
//1. 获取留言的内容
var from = $('#from').val();
var to = $('#to').val();
var say = $('#say').val();
if (from== '' || to == '' || say == '') {
return;
}
$.ajax({
type:"post",
url:"/message/publish",
data:{
from:from,
to:to,
message:say
},
success:function (result) {
if (result == true){
// 添加成功
//2. 构造节点
var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
//3. 把节点添加到页面上
$(".container").append(divE);
//4. 清空输入框的值
$('#from').val("");
$('#to').val("");
$('#say').val("");
}else{
alert("发表失败");
}
}
});
}
</script>
</body>
</html>
后端代码
lombok工具包介绍
-
新项目
创建项目的时候直接加入依赖
-
老项目
在poe.xml中引入依赖,去maven中央仓库找
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency>
-
更快地引入依赖
下载这个就好啦~然后重启IDEA
使用方法:
package org.example.springmvc_demo;
import lombok.Data;
/**
* @author 日夜无休时
* @date 2024/1/29
*/
@Data
public class MessageInfo {
private String from;
private String to;
private String message;
// 换一个新工具 lombook @Data
// public String getFrom() {
// return from;
// }
//
// public void setFrom(String from) {
// this.from = from;
// }
//
// public String getTo() {
// return to;
// }
//
// public void setTo(String to) {
// this.to = to;
// }
//
// public String getMessage() {
// return message;
// }
//
// public void setMessage(String message) {
// this.message = message;
// }
}
package org.example.springmvc_demo;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @author 日夜无休时
* @date 2024/1/29
*/
@RestController
@RequestMapping("/message")
public class MessageController {
private List<MessageInfo>messageInfos = new ArrayList<>();
@RequestMapping("/publish")
public boolean publishMessage(MessageInfo messageInfo){
if (!StringUtils.hasLength(messageInfo.getFrom())
|| !StringUtils.hasLength(messageInfo.getTo())
|| !StringUtils.hasLength((messageInfo.getMessage()))){
return false;
}
// 暂时存放在内存中
messageInfos.add(messageInfo);
return true;
}
@RequestMapping("/getList")
public List<MessageInfo> getList(){
for (MessageInfo messageInfo : messageInfos){
}
return messageInfos;
}
}
图书管理系统
定义接口
-
登录
-
图书列表
MOCK
虚拟的、假的。开发的时候通常是几个团队并行开发,开发后需要进行测试(自测),如果测试时,依赖方还没完成开发,调用方就采用mock的方式,先进行测试。
应用分层
一种开发规范
三层架构(软件设计架构方式)
命名规范
- 类名 大驼峰
- 变量名 小驼峰
MVC和三层架构之间的关系
共同点:
-
解耦(高内聚,低耦合)
SpringMVC小结
什么是springmvc
spring web mvc
@RequestMapping
既是类注解,也是方法注解
访问的URL路径 = 类路径 + 方法路径
默认支持 get/post
,可以使用method
属性来限制请求方式
请求
- 请求当个参数
- 请求多个参数
- 请求参数为对象
- 对参数重命名
@RequestParam 默认是必传参数,设置 required = false 就是非必传
- 设置参数为非必传
- 请求参数为
JSON
@RequestBody
Cookie & Session
- 传递数组
- 传递集合
@RequestParam
- 获取Header
响应
- 返回静态页面
- 返回数据
@ResponseBody
- 返回
HTML
片段 - 返回
JSON
- 设置响应头(状态码、编码、其他
header
)
注解总结
- @RequestMapping: 路由映射
- @RequestParam: 后端参数重命名
- @RequestBody: 接收JSON类型的参数
- @PathVariable: 接收路径参数
- @RequestPart: 上传⽂件
- @ResponseBody: 返回数据
- @CookieValue: 从Cookie中获取值
- @SessionAttribute: 从Session中获取值
- @RequestHeader: 从Header中获取值
- @Controller: 定义⼀个控制器, Spring 框架启动时加载, 把这个对象交给Spring管理. 默认返回视图.
- @RestController: @ResponseBody + @Controller 返回数据
Cookie和Session
Cookie 和Session都是会话机制, Cookie是客⼾端机制, Session是服务端机制. ⼆者通过SessionId来关联. Spring MVC内置HttpServletRequest, HttpServletResponse两个对象. 需要使⽤时, 直接在⽅法中添加对应参数即可, Cookie和Session可以从HttpServletRequest中来获取, 也可以直接使⽤HttpServletResponse设置Http响应状态码.