1.Spring Boot
Spring: POJO容器。AOP各个层次之间的结藕
Spring MVC: 分离模型与视图
Spring Data: 数据存储
Spring Security: 集成了第三方技术
2.Spring MVC
类似的技术:struts,JSF,MVC
解决的问题:分离模型层(M)与视图层(V)
怎么分离:提供控制层(C)
3.注解
@Controller: 控制器
@RestController: RESTful控制器
@ResponseBody: 响应体,返回数据(json),不是视图名
@RequestBody: 请求体,获得Http请求头的负载(json/xml)并填充层对象
@RequestMapping
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PathVariable: 路径变量,/user/{name}/address/{id}
路径代表资源,方法代表资源的操作。
4.方案
1.RESTful API+Vue ClI(前后端分离) ------推荐-----
2.RESTful API+static(HTML,CSS,JS) ------今天写的---
3.Controller+模板引擎(JSP,JSTL,Thymeleaf)
5.工程目录
Course.java
package com.newer.work;
/**
* POJO
* @author Admin
*
*/
public class Course {
int id;
String title;
String info;
public Course() {
}
public Course(int id, String title, String info) {
super();
this.id = id;
this.title = title;
this.info = info;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Course [id=" + id + ", title=" + title + ", info=" + info + "]";
}
}
CourseController.java
package com.newer.work;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* RESTful风格API(开发接口)
*
* 建议: URL中加入/api/版本号的前缀
* @author Admin
*
*/
@RestController
@RequestMapping("/api/v1/course")
public class CourseController {
// Get "/course"
@GetMapping
public List<Course> findAll() {
return Db.selectAll();
}
@GetMapping("/{id}")
public Course load(@PathVariable int id) {
// Course c=new Course();
// c.setId(id);
return Db.selectById(id);
}
// 接收HTTP请求Body中的JSON数据,必须使用@RequestBody注解
@PostMapping
public Course create(@RequestBody Course c) {
// 存储
// c.setId(999);
Course course=Db.insert(c);
// 数据库中保存的对象
return course;
}
// @RequestBody从HTTP请求头中读取数据(JSON)填充一个Course类型对象
@PutMapping("/{id}")
public ResponseEntity<String> update(@PathVariable int id,@RequestBody Course c) {
// 更新
Db.update(id, c);
// Http响应头中的状态码
// 1xx 信息中
// 2xx 成功
// 3xx 重定向
// 4xx 客户端错误
// 5xx 服务端错误
return new ResponseEntity<String>("Http响应主体",HttpStatus.OK);
}
@DeleteMapping("/{id}")
public boolean remove(@PathVariable int id) {
// 删除
return Db.delete(id);
}
}
Db.java
package com.newer.work;
import java.util.ArrayList;
import java.util.List;
/**
* 模拟数据库
* @author Admin
*
*/
public class Db {
// 计数器,类变量
static int count=1000;
// 集合,表
static List<Course>courseTable=new ArrayList<>();
static {
courseTable.add(new Course(1,"vue","前端框架"));
courseTable.add(new Course(3,"JS","前端框架"));
courseTable.add(new Course(7,"redis","数据存储"));
}
/**
* 返回所有数据
* @return
*/
public static List<Course>selectAll(){
return courseTable;
}
/**
* 返回课程编号等于id的课程
*
* @param id 课程编号
* @return 匹配的课程或null
*/
public static Course selectById(int id) {
Course c=null;
for(Course course:courseTable) {
if(course.getId()==id) {
c=course;
break;
}
}
return c;
}
/**
* 插入一条数据
*
* @param c 新课程
* @return
*/
public static Course insert(Course c) {
// 数据库存储后才生成id
// 第一个值是1001
c.setId(++count);
courseTable.add(c);
return c;
}
/**
* 根据id删除记录
*
* @param id 编号
* @return boolean 成功删除返回true,否则返回false
*/
public static boolean delete(int id) {
Course d=null;
// 删除不要用foreach
for (int i = 0; i < courseTable.size(); i++) {
Course course=courseTable.get(i);
if(course.getId()==id) {
courseTable.remove(i);
break;
}
}
// 是否成功删除
return d!=null;
}
/**
* 更新编号为id的数据
* @param id 编号
* @param c 新数据
*/
public static void update(int id,Course c) {
// 更新不要用foreach
for (int i = 0; i < courseTable.size(); i++) {
Course course=courseTable.get(i);
if(course.getId()==id) {
// 更新
course.setTitle(c.getTitle());
course.setInfo(c.getInfo());
break;
}
}
}
}
HomeController.java
package com.newer.work;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
// Get "/"--->"index.html"
@GetMapping("/")
public String home() {
return "index.html";
}
@GetMapping("/course")
public String course() {
// 请求转发到"/"--->index.html
// return "/";
// 响应重定向"/"---地址栏改变
// 状态码302.
return "redirect:/";
}
}
WorkApplication.java
package com.newer.work;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WorkApplication {
public static void main(String[] args) {
SpringApplication.run(WorkApplication.class, args);
}
}
index.html
<!doctype html>
<html lang="en">
<head>
<title>Spring Boot+Vue</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="jumbotron jumbotron-fluid">
<div class="container">
<h1 class="display-3">服务端&前端在一起</h1>
<p class="lead">Spring Boot+ Vue+axios</p>
</div>
</div>
<div id="app" class="container">
<!-- -->
<table class="table">
<thead>
<tr>
<th><input type="checkbox" name="" id=""></th>
<th>编号</th>
<th>课程</th>
<th>描述</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(c, index) in courseList" :key="index">
<td><input type="checkbox" name="" id=""></td>
<td>{{c.id}}</td>
<td>{{c.title}}</td>
<td>{{c.info}}</td>
</tr>
</tbody>
</table>
</div>
<script>
new Vue({
el: '#app',
data: {
courseList: []
},
methods: {
},
created() {
// 实例创建
// 前端和服务端在一起,不需要IP和端口
let url = '/api/v1/course'
axios.get(url)
.then(res => {
console.log(res)
this.courseList = res.data
})
.catch(err => {
console.error(err);
})
},
mounted() {
// 挂载
},
})
</script>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
</body>
</html>
application.properties
#显示Spring MVC 日志信息
logging.level.web=debug
#显示请求头详细信息
spring.http.log-request-details=true
测试: