【SpringBoot1.x】RestfulCRUD
SpringBoot1.x RestfulCRUD
添加资源
将所有的静态资源都添加到 src/main/resources/static
文件夹下,所有的模版资源都添加到 src/main/resources/templates
文件夹下。
创建数据库表,并编写对应实体类。
use web_restful_crud;
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for department
-- ----------------------------
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
`id` int(11) primary key NOT NULL AUTO_INCREMENT,
`departmentName` varchar(255) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
use web_restful_crud;
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`id` int(11) primary key NOT NULL AUTO_INCREMENT,
`lastName` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`gender` int(2) DEFAULT NULL,
`birth` date DEFAULT NULL,
`d_id` int(11) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
public class Department {
private Integer id;
private String departmentName;
// setter getter toString
}
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender; // 1 male, 0 female
private Date birth;
private Department department;
// setter getter toString
}
默认访问首页
可以使用 WebMvcConfigurerAdapter 可以来扩展 SpringMVC 的功能,可以不用自己实现一个 ViewController。
src/main/java/cn/parzulpan/config/CustomMvcConfig.java
/**
* @Author : parzulpan
* @Time : 2020-12
* @Desc : 自动以配置类,扩展 SpringMVC
*/
@Configuration
public class CustomMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 浏览器发送 /parzulpan 请求来到自定义 404 页面
registry.addViewController("/parzulpan").setViewName("404");
}
// 将组件注册在容器,所有的 WebMvcConfigurerAdapter 组件都会一起起作用
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
}
};
return adapter;
}
}
国际化
国际化之前添加 Thymeleaf 支持。
<html lang="en">
<link href="asserts/css/bootstrap.min.css" rel="stylesheet">
改为:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link href="asserts/css/bootstrap.min.css" th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">
这样做的好处是,当通过 server.context-path=/crud
更改项目路径时,静态文件可以自动匹配。
之前使用国际化的步骤:
- 编写国际化资源文件
- 使用 ResourceBundleMessageSource 管理国际化资源文件
- 在页面使用
fmt:message
取出国际化内容
SpringBoot 使用国际化的步骤:
编写国际化配置文件
SpringBoot 自动配置好了管理国际化资源文件的组件
MessageSourceAutoConfiguration
,它会根据浏览器语言设置的信息切换国际化,即默认的就是根据请求头带来的区域信息获取 Locale 进行国际化如果想点击链接切换国际化,可以自定义 LocaleResolver(获取区域信息对象)
/**
* @Author : parzulpan
* @Time : 2020-12
* @Desc : 自定义区域信息解析器
*/ public class CustomLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
// 获取请求中的语言参数
String language = request.getParameter("locale");
Locale locale = Locale.getDefault(); //如果没有就使用默认的
// 如果请求的链接携带了国际化参数
if (!StringUtils.isEmpty(language)){
// zh_CN
String[] split = language.split("_");
// 国家,地区
locale = new Locale(split[0], split[1]);
}
return locale; } @Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { }
}
然后在自定义配置类将自定义区域信息解析器添加到容器中
// 自定义区域信息解析器添加到容器中
@Bean
public LocaleResolver localResolver() {
return new CustomLocaleResolver();
}
登陆
开发期间模板引擎页面修改以后需要实时生效的步骤:
- 禁用模板引擎的缓存
spring.thymeleaf.cache=false
- 页面修改完成以后
Ctrl+F9
,重新编译
使用拦截器进行登陆检查:
自定义登录拦截器
/**
* @Author : parzulpan
* @Time : 2020-12
* @Desc : 登录拦截器
*/ public class LoginHandleInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("loginUser");
if (user == null) {
// 未登录,提示信息,并返回登录页面
request.setAttribute("msg", "没有权限!请先登录!");
request.getRequestDispatcher("/index").forward(request, response);
return false;
} else {
// 已登录,放行请求
return true;
}
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
}
注册拦截器到自动配置类
// 将组件注册在容器,所有的 WebMvcConfigurerAdapter 组件都会一起起作用
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// SpringBoot 已经做好了静态资源映射
registry.addInterceptor(new LoginHandleInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/", "/index", "/index.html", "/user/login");
}
};
return adapter;
}
Thymeleaf 公共页面元素抽取
比如顶部栏和侧边栏都是公共页面,可以抽取出来。
抽取公共片段
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
引入公共片段
<!--
~{templatename::selector}:模板名::选择器
~{templatename::fragmentname}:模板名::片段名
-->
<div th:insert="~{footer :: copy}"></div>
使用三种不同的引入公共片段的
th属性
,引入公共片段后的效果th:insert
将公共片段整个插入到声明引入的元素中<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
th:replace
将声明引入的元素替换为公共片段<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
th:include
将被引入的片段的内容包含进这个标签中<div>
© 2011 The Good Thymes Virtual Grocery
</div>
RestfulCRUD 分析
URI 格式 /资源名称/资源标识
HTTP 请求方式区分对资源 CRUD 操作
普通CRUD(uri来区分操作) | RestfulCRUD | |
---|---|---|
查询 | getEmp | emp & GET |
添加 | addEmp?xxx | emp & POST |
修改 | updateEmp?id=1 | emp/{id} & PUT |
删除 | deleteEmp?id=1 | emp/{id} & DELETE |
员工列表
- 查询所有员工
- 请求URI
emps
- 请求方式
GET
- 请求URI
@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
@Autowired
DepartmentDao departmentDao;
/**
* 查询所有员工,返回列表页面
*/
@GetMapping("/emps")
public String list(Model model) {
Collection<Employee> employees = employeeDao.getAll();
model.addAttribute("emps", employees); // 结果放到请求域中
return "emp/list"; // Thymeleaf 会自动拼串,classpath:/templates/emp/list.html
}
}
员工添加
- 来到员工添加页面
- 请求URI
emp
- 请求方式
GET
- 请求URI
- 员工添加
- 请求URI
emp
- 请求方式
POST
- 请求URI
@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
@Autowired
DepartmentDao departmentDao;
/**
* 来到员工添加页面
*/
@GetMapping("/emp")
public String toAddPage(Model model) {
// 查询所有部门,在页面显示
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("depts", departments);
return "emp/add";
}
/**
* 员工添加,SpringMVC 会自动进行参数绑定
*/
@PostMapping("/emp")
public String addEmp(Employee employee) {
employeeDao.save(employee);
return "redirect:/emps";
}
}
员工修改
- 来到员工修改页面
- 请求URI
emp/{id}
- 请求方式
GET
- 请求URI
- 员工修改
- 请求URI
emp
- 请求方式
PUT
- 请求URI
@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
@Autowired
DepartmentDao departmentDao;
/**
* 来到修改页面,查出当前员工,在页面回显
*/
@GetMapping("/emp/{id}")
public String toEditPage(@PathVariable("id") Integer id, Model model) {
Employee employee = employeeDao.get(id);
model.addAttribute("emp", employee);
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("depts", departments);
return "emp/add"; // add.html 是一个修改和添加二合一的页面
}
/**
* 员工修改,SpringMVC 会自动进行参数绑定
*/
@PutMapping("/emp")
public String updateEmp(Employee employee) {
employeeDao.save(employee);
return "redirect:/emps";
}
}
员工删除
- 查询所有员工
- 请求URI
emp/{id}
- 请求方式
DELETE
- 请求URI
@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
@Autowired
DepartmentDao departmentDao;
/**
* 员工删除
*/
@DeleteMapping("/emp/{id}")
public String deleteEmp(@PathVariable("id") Integer id) {
employeeDao.delete(id);
return "redirect:/emps";
}
}
练习和总结
【SpringBoot1.x】RestfulCRUD的更多相关文章
- 【SpringBoot1.x】SpringBoot1.x 任务
SpringBoot1.x 任务 文章源码 异步任务 在 Java 应用中,绝大多数情况下都是通过同步的方式来实现交互处理的.但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使 ...
- 【SpringBoot1.x】SpringBoot1.x 开发热部署和监控管理
SpringBoot1.x 开发热部署和监控管理 热部署 在开发中我们修改一个 Java 文件后想看到效果不得不重启应用,这导致大量时间花费,我们希望不重启应用的情况下,程序可以自动部署(热部署). ...
- 【SpringBoot1.x】SpringBoot1.x 分布式
SpringBoot1.x 分布式 分布式应用 Zookeeper&Dubbo ZooKeeper 是用于分布式应用程序的高性能协调服务.它在一个简单的界面中公开了常见的服务,例如命名,配置管 ...
- 【SpringBoot1.x】SpringBoot1.x 安全
SpringBoot1.x 安全 文章源码 环境搭建 SpringSecurity 是针对 Spring 项目的安全框架,也是 SpringBoot 底层安全模块默认的技术选型.他可以实现强大的 we ...
- 【SpringBoot1.x】SpringBoot1.x 检索
SpringBoot1.x 检索 文章源码 概念 Elasticsearch 是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本.数字.地理空间.结构化和非结构化数据.Elasticse ...
- 【SpringBoot1.x】SpringBoot1.x 消息
SpringBoot1.x 消息 文章源码 概述 大多应用中,可通过消息服务中间件来提升系统异步通信.扩展解耦能力. 消息服务有两个重要概念,即消息代理(message broker)和目的地(des ...
- 【SpringBoot1.x】SpringBoot1.x 缓存
SpringBoot1.x 缓存 文章源码 JSR107 Java Caching 定义了 5 个核心接口,分别为: CachingProvider 定义了创建.配置.获取.管理和控制多个 Cache ...
- 【SpringBoot1.x】SpringBoot1.x 启动配置原理 和 自定义starter
SpringBoot1.x 启动配置原理 和 自定义starter 启动配置原理 本节源码 启动过程主要为: new SpringApplication(sources) 创建 SpringAppli ...
- 【SpringBoot1.x】SpringBoot1.x 数据访问
SpringBoot1.x 数据访问 简介 对于数据访问层,无论是 SQL 还是 NOSQL,Spring Boot 默认采用整合 Spring Data 的方式进行统一处理,添加大量自动配置,屏蔽了 ...
随机推荐
- CF1407D Discrete Centrifugal Jumps 题解
蒟蒻语 写了 \(100\) 行的 线段树上ST表维护二分维护单调栈维护dp, 结果最后发现只要俩单调栈就好了 = = 蒟蒻解 首先 \(dp_i\) 表示从 \(1\) 楼到 \(i\) 楼要跳几次 ...
- AcWing 276. I-区域
题目链接 设 \(0\) 为单调伸长, \(1\) 为单调伸短. 设 \(f[i][j][l][r][x(0 / 1)][y (0 / 1)]\) 为第 \(i\) 行,已经选出\(j\)个格子,第\ ...
- window下使用cmd查看端口占用的进程,并杀死该进程
做项目的时候经常会遇到"address already in use"的情况,此时可以选择使用dos命令将该进程杀死. 首先,查找端口对应的进程,使用命令(以进程号8080为例): ...
- 关于Switch Case的优化
switch case虽然是代替if else而出现的,并不好维护,有时候使用switch还不如使用if else. 但没有别的东西能代替switch case了吗?答案当然是否定的,现在就有两种方式 ...
- 三、LoadRunner卸载
由于安装的时候没看提前了解清楚,LoadRunner社区版只能模拟50个用户,满足不了工作需求,删了重装吧. 1-打开"控制面板"-点击"卸载程序" 2-找到H ...
- pyhon 自动化 logger
#!/Users/windows8.1/PycharmProjects/pythonapi# @Software: PyCharm Community Edition# -*- coding: utf ...
- 3. 搞定收工,PropertyEditor就到这
分享.成长,拒绝浅藏辄止.搜索公众号[BAT的乌托邦],回复关键字专栏有Spring技术栈.中间件等小而美的原创专栏供以免费学习.本文已被 https://www.yourbatman.cn 收录. ...
- Salesforce LWC学习(二十九) getRecordNotifyChange(LDS拓展增强篇)
本篇参考: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/data_ui_api https ...
- 使用BulkLoad恢复hbase数据
问题: hbase 集群启动不了,maste一直在初始化,数据面临丢失风险. 解决: 把hbfs上 /hbase 目录移走 改名为/hbase-bak 删除zk上的数据,重新建立一个新的hbase集群 ...
- MySQL(二):快速理解MySQL数据库索引
索引 基本概念:索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现. 数据结构 Tree 指的是 Balance Tree,也就是平衡树.平衡树是一颗查找树,并 ...