文章目录楠哥教你学Java SpringBoot 总结笔记
- SpringBoot总结笔记
- SpringBoot
- SpringBoot概述
- SpringBoot的优点
- SpringBoot与微服务Spring Cloud
- 如何使用SpringBoot
- SpringBoot数据校验
- SpringBoot整合JSP
- SpringBoot整合Thymeleaf
- Spring Boot HTML
- Thymeleaf常用语法
- SpringBoot整合JDBC
- SpringBoot整合MyBatis
- SpringBoot整合Spring Data JPA
- SpringBoot整合Spring Data MongoDB
- SpringBoot整合Spring Data Redis
- Redis
- Redis五种数据类型
- SpringBoot整合Spring Security
- 如何使用Spring Security
- 权限管理
- SpringBoot整合Shiro
- Shiro
- Shiro核心组件
- 编写认证和授权规则
Spring Boot是一个快速开发框架,可以迅速搭建出一套基于Spring框架体系的应用,是Spring Cloud的基础。Spring Boot开启了各种自动装配,从而简化代码的开发,不需要编写各种配置文件,只需要引入相关依赖就可以迅速搭建一个应用。
Spring Boot的设计目的是用来简化Spring应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
SpringBoot的优点- 不需要web.xml
- 不需要springmvc.xml
- 不需要tomcat,Spring Boot内嵌了tomcat
- 不需要配置JSON解析,支持 REST架构
- 个性化配置非常简单
- Spring Boot的一系列特性有助于实现微服务架构的落地,从目前众多的技术栈对比来看它是Java领域微服务架构最优落地技术,没有之一。
- Spring Cloud依赖于Spring Boot
- Spring Boot专注于快速开发个体微服务,Spring Cloud是关注全局的微服务协调治理框架。
-
创建Maven工程,导入相关依赖。
org.springframework.boot spring-boot-starter-parent 2.6.7 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided -
创建Student实体类
@Data @AllArgsConstructor @NoArgsConstructor public class Student { private long id; private String name; private int age; } -
StudentRepository
public interface StudentRepository { public CollectionfindAll(); public Student findById(long id); public void saveOrUpdate(Student student); public void deleteById(long id); } -
StudentRepositoryImpl
@Repository public class StudentRepositoryImpl implements StudentRepository { private static MapstudentMap; static { studentMap = new HashMap<>(); studentMap.put(1L,new Student(1l,"小王",23)); studentMap.put(2L,new Student(2l,"小刘",12)); studentMap.put(3L,new Student(3l,"小东",24)); } @Override public Collection findAll() { return studentMap.values(); } @Override public Student findById(long id) { return studentMap.get(id); } @Override public void saveOrUpdate(Student student) { studentMap.put(student.getId(), student); } @Override public void deleteById(long id) { studentMap.remove(id); } } -
StudentHandler
@RestController @RequestMapping("/student") public class StudentHandler { @Autowired private StudentRepository studentRepository; @GetMapping("/findAll") public CollectionfindAll() { return studentRepository.findAll(); } @GetMapping("/findById/{id}") public Student findById(@PathVariable("id") long id) { return studentRepository.findById(id); } @PostMapping("/save") public void save(@RequestBody Student student) { studentRepository.saveOrUpdate(student); } @PutMapping("/update") public void update(@RequestBody Student student) { studentRepository.saveOrUpdate(student); } @DeleteMapping("/delete/{id}") public void delete(@PathVariable("id") long id) { studentRepository.deleteById(id); } } -
application.yml
server: port: 9090
-
启动类
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }@SpringBootApplication 表示当前类是SpringBoot的入口,Application类的存放位置必须是其他相关业务类的存放位置的父级。
@Data
public class User {
@NotNull(message = "id不能为空")
private Long id;
@NotEmpty(message = "姓名不能为空")
@Length(min = 2,message = "姓名长度不能小于2位")
private String name;
@Min(value = 16,message = "年龄必须大于16岁")
private int age;
}
@GetMapping("/validator")
public void validatorUser(@Valid User user,BindingResult bindingResult){
System.out.println(user);
if(bindingResult.hasErrors()){
List list = bindingResult.getAllErrors();
for(ObjectError objectError:list){
System.out.println(objectError.getCode()+"-"+objectError.getDefaultMessage());
}
}
}
SpringBoot整合JSP
- pom.xml
org.springframework.boot spring-boot-starter-parent 2.6.7 org.springframework.boot spring-boot-starter-web org.projectlombok lombok org.springframework.boot spring-boot-starter-tomcat org.apache.tomcat.embed tomcat-embed-jasper jstl jstl 1.2
- application.yml
server:
port: 9090
spring:
mvc:
view:
prefix: /
suffix: .jsp
- 创建Student实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private long id;
private String name;
private int age;
}
StudentRepository
public interface StudentRepository {
public Collection findAll();
public Student findById(long id);
public void saveOrUpdate(Student student);
public void deleteById(long id);
}
StudentRepositoryImpl
@Repository
public class StudentRepositoryImpl implements StudentRepository {
private static Map studentMap;
static {
studentMap = new HashMap<>();
studentMap.put(1L,new Student(1l,"小王",23));
studentMap.put(2L,new Student(2l,"小刘",12));
studentMap.put(3L,new Student(3l,"小东",24));
}
@Override
public Collection findAll() {
return studentMap.values();
}
@Override
public Student findById(long id) {
return studentMap.get(id);
}
@Override
public void saveOrUpdate(Student student) {
studentMap.put(student.getId(), student);
}
@Override
public void deleteById(long id) {
studentMap.remove(id);
}
}
- StudentHandler
@Controller
@RequestMapping("/student")
public class StudentHandler {
@Autowired
private StudentRepository studentRepository;
@GetMapping("/hello")
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("list",studentRepository.findAll());
return modelAndView;
}
@GetMapping("/findById/{id}")
public ModelAndView findById(@PathVariable("id") long id){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("update");
modelAndView.addObject("student",studentRepository.findById(id));
return modelAndView;
}
@GetMapping("/deleteById/{id}")
public String deleteById(@PathVariable("id") long id){
studentRepository.deleteById(id);
return "redirect:/student/hello";
}
@PostMapping("/save")
public String save(Student student){
studentRepository.saveOrUpdate(student);
return "redirect:/student/hello";
}
@PostMapping("/update")
public String update(Student student){
studentRepository.saveOrUpdate(student);
return "redirect:/student/hello";
}
}
- 启动类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
- index.jsp
学生信息
| 学生编号 | 学生姓名 | 学生年龄 | 操作 |
|---|---|---|---|
| ${student.id} | ${student.name} | ${student.age} | 修改 删除 |
- save.jsp
- update.jsp
SpringBoot整合Thymeleaf
Spring Boot HTML
Spring Boot 可以结合Thymeleaf模版来整合HTML,使用原生的 HTML作为视图。
Thymeleaf模版是面向Web和独立环境的Java模版引擎,能够处理HTML、XML、JavaScript、CSS等。
- pom.xml
org.springframework.boot spring-boot-starter-parent 2.6.7 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided org.springframework.boot spring-boot-starter-thymeleaf
- application.yml
server: port: 9090 spring: thymeleaf: prefix: classpath:/templates/ suffix: .html mode: HTML5 encoding: UTF-8
- Handler
@Controller
@RequestMapping("https://blog.csdn.net/index")
public class IndexHandler {
@RequestMapping("https://blog.csdn.net/index")
public String index(){
System.out.println("index123");
return "index";
}
}
- index.html
Title
Hello World
如果希望客户端可以直接访问HTML资源,将这些资源放置在static路径下即可,否则必须通过Handler的后台映射才可以访问静态资源。
Thymeleaf常用语法- 赋值、拼接
@GetMapping("https://blog.csdn.net/index2")
public String index2(Map map){
map.put("name","张三");
return "index";
}
- 条件判断:if/unless
th:if 表示条件成立时显示内容,th:unless 表示条件不成立时显示内容
@GetMapping("/if")
public String index3(Map map){
map.put("flag",true);
return "index";
}
- 循环
@GetMapping("https://blog.csdn.net/index")
public String index(Model model){
System.out.println("index...");
List list = new ArrayList<>();
list.add(new Student(1L,"张三",22));
list.add(new Student(2L,"李四",23));
list.add(new Student(3L,"王五",24));
model.addAttribute("list",list);
return "index";
}
index
count
学生ID
学生姓名
学生年龄
stat 是状态变量,
属性:
-
index 集合中元素的index(从0开始)
-
count 集合中元素的count(从1开始)
-
size 集合的大小
-
current 当前迭代变量
-
even/odd 当前迭代是否为偶数/奇数(从0开始计算)
-
first 当前迭代的元素是否是第一个
-
last 当前迭代的元素是否是最后一个
-
URL
Thymeleaf 对于 URL 的处理是通过 @{...} 进行处理,结合 th:href 、th:src
Hello World
跳转 跳转2![]()
- 三元运算
@GetMapping("/eq")
public String eq(Model model){
model.addAttribute("age",30);
return "test";
}
-
gt great than 大于
-
ge great equal 大于等于
-
eq equal 等于
-
lt less than 小于
-
le less equal 小于等于
-
ne not equal 不等于
-
switch
@GetMapping("/switch")
public String switchTest(Model model){
model.addAttribute("gender","女");
return "test";
}
女
男
未知
- 基本对象
- #ctx :上下文对象
- #vars:上下文变量
- #locale:区域对象
- #request:HttpServletRequest 对象
- #response:HttpServletResponse 对象
- #session:HttpSession 对象
- #servletContext:ServletContext 对象
@GetMapping("/object")
public String object(HttpServletRequest request){
request.setAttribute("request","request对象");
request.getSession().setAttribute("session","session对象");
return "test";
}
- 内嵌对象
可以直接通过 # 访问。
1、dates:java.util.Date 的功能方法
2、calendars:java.util.Calendar 的功能方法
3、numbers:格式化数字
4、strings:java.lang.String 的功能方法
5、objects:Object 的功能方法
6、bools:对布尔求值的方法
7、arrays:操作数组的功能方法
8、lists:操作集合的功能方法
9、sets:操作集合的功能方法
10、maps:操作集合的功能方法
@GetMapping("/util")
public String util(Model model){
model.addAttribute("name","zhangsan");
model.addAttribute("users",new ArrayList<>());
model.addAttribute("count",22);
model.addAttribute("date",new Date());
return "test";
}
SpringBoot整合JDBC
- pom.xml
org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java
- application.yml
server:
port: 9090
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
mode: HTML
encoding: UTF-8
datasource:
url: jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
- User
@Data
public class User{
private Long id;
private String username;
private String password;
private String email;
}
- UserRepository
public interface UserRepository {
public List findAll();
public User findById(long id);
public void save(User user);
public void update(User user);
public void deleteById(long id);
}
- UserRepositoryImpl
@Repository
public class UserRepositoryImpl implements UserRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List findAll() {
return jdbcTemplate.query("select * from user", new BeanPropertyRowMapper<>(User.class));
}
@Override
public User findById(long id) {
return jdbcTemplate.queryForObject("select * from user where id = ?", new Object[]{id}, new BeanPropertyRowMapper<>(User.class));
}
@Override
public void save(User user) {
jdbcTemplate.update("insert into user(username,password,email) values (?,?,?)", user.getUsername(), user.getPassword(), user.getEmail());
}
@Override
public void update(User user) {
jdbcTemplate.update("update user set username = ?,password = ?,email = ? where id = ?", user.getUsername(), user.getPassword(), user.getEmail(),user.getId());
}
@Override
public void deleteById(long id) {
jdbcTemplate.update("delete from user where id = ?",id);
}
}
- UserHandler
@RestController
@RequestMapping("/user")
public class UserHandler {
@Autowired
private UserRepository userRepository;
@GetMapping("/findAll")
public List findAll() {
return userRepository.findAll();
}
@GetMapping("/findById/{id}")
public User findById(@PathVariable("id") long id) {
return userRepository.findById(id);
}
@PostMapping("/save")
public void save(User user) {
userRepository.save(user);
}
@PutMapping("/update")
public void update(User user) {
userRepository.update(user);
}
@DeleteMapping("/deleteById/{id}")
public void deleteById(@PathVariable("id") long id) {
userRepository.deleteById(id);
}
}
- 启动类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
SpringBoot整合MyBatis
- pom.xml
org.springframework.boot spring-boot-starter-parent 2.6.7 org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.2 org.projectlombok lombok provided mysql mysql-connector-java
- 创建数据库表
create table student (
id int primary key auto_increment,
name varchar(11),
score double,
birthday date
);
- application.yml
server:
port: 9090
spring:
datasource:
url: jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:/mapping
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder())//对密码进行编码
.withUser("user").password(new MyPasswordEncoder().encode("123456")).roles("USER")
.and()
.withUser("admin").password(new MyPasswordEncoder().encode("123456")).roles("ADMIN", "USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().antMatchers("/admin").hasRole("ADMIN")
.antMatchers("https://blog.csdn.net/index").access("hasRole('ADMIN') or hasRole('USER')")
.anyRequest().authenticated()
.and()//此时上述已经完成操作 下面写的是自定义一个登录界面
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.csrf()
.disable();
}
}
- 优化HelloHandler
@Controller
public class HelloHandler {
@GetMapping("https://blog.csdn.net/index")
public String index(){
return "index";
}
@GetMapping("/admin")
public String admin(){
return "admin";
}
@GetMapping("/login")
public String login(){
return "login";
}
}
- login.html
- index.html
Hello World
- admin.html
SpringBoot整合Shiro Shiro后台管理系统
是一款主流的Java安全框架,不依赖任何容器,可以运行在Java SE和JavaE项目中,它的主要作用是对访问系统的用户进行身份认证、授权、会话管理、加密等操作。
Shiro 就是用来解决安全管理的系统化框架。
Shiro核心组件用户、角色、权限
给角色赋予权限,给用户赋予角色
-
UsernamePasswordToken,Shiro用来封装用户登录信息,使用用户的登录信息来创建令牌Token。
-
SecurityManager,Shiro的核心部分,负责安全认证和授权。
-
Suject,Shiro的一个抽象概念,包含了用户信息。
-
Realm,开发者自定义的模块,根据项目的需求,验证和授权的逻辑全部写在Realm中。
-
AuthenticationInfo,用户的角色信息集合,认证时使用。
-
AuthorzationInfo,角色的权限信息集合,授权时使用。
-
** **,安全管理器,开发者自定义的 Realm 需要注入到DefaultwebSecurityDManager进行管理才能生效。
-
ShiroFilterEactoryBean,ShiroFilterFactoryBean,过滤器工厂,Shiro的基本运行机制是开发者定制规则,Shiro去执行,具体的执行操作就是由ShiroFilterEactoryBean创建的一个个Filter对象来完成。
- pom.xml
org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.apache.shiro shiro-spring 1.9.0 mysql mysql-connector-java com.baomidou mybatis-plus-boot-starter 3.5.1 org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine
- 自定义Shiro过滤器
public class AccountRealm extends AuthorizingRealm {
@Autowired
private AccountService accountService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取当前登录信息
Subject subject = SecurityUtils.getSubject();
Account account = (Account) subject.getPrincipal();
//设置角色
Set roles = new HashSet<>();
roles.add(account.getRole());
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles);
//设置权限
info.addStringPermission(account.getPerms());
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
Account account = accountService.findByUsername(token.getUsername());
if (account != null) {
return new SimpleAuthenticationInfo(account,account.getPassword(),getName());
}
return null;
}
}
- 配置类 ShiroConfig
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
Map map = new Hashtable<>();
map.put("https://blog.csdn.net/main","authc");
map.put("https://blog.csdn.net/manage","perms[manage]");
map.put("https://blog.csdn.net/administrator","roles[administrator]");
factoryBean.setFilterChainDefinitionMap(map);
//设置登录界面
factoryBean.setLoginUrl("/login");
//设置未授权界面
factoryBean.setUnauthorizedUrl("/unauthorized");
return factoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("accountRealm") AccountRealm accountRealm){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(accountRealm);
return manager;
}
@Bean
public AccountRealm accountRealm(){
return new AccountRealm();
}
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
}
- handler
@Controller
public class AccountHandler {
@GetMapping("/{url}")
public String redirect(@PathVariable("url") String url){
return url;
}
@GetMapping("https://blog.csdn.net/logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "login";
}
@PostMapping("/login")
public String login(String username, String password, Model model){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
Account account = (Account) subject.getPrincipal();
subject.getSession().setAttribute("account",account);
return "index";
} catch (UnknownAccountException e) {
e.printStackTrace();
model.addAttribute("msg","用户名错误");
return "login";
}catch (IncorrectCredentialsException e){
e.printStackTrace();
model.addAttribute("msg","密码错误");
return "login";
}
}
@ResponseBody
@GetMapping("/unauthorized")
public String unauthorized(){
return "您无权访问该页面";
}
}
编写认证和授权规则
认证过滤器
- anon:无需认证。
- authc:必须认证。
- authcBasic:需要通过HTTPBasic 认证。
- user:不一定通过认证,只要曾经被Shiro记录即可,比如:记住我。
授权过滤器
-
perms:必须拥有某个权限才能访问。
-
role:必须拥有某个角色才能访问。
-
port:请求的端口必须是指定值才可以。
-
rest:请求必须基于RESTful,POST、PUT、GET、DELETE。
-
ssl:必须是安全的URL请求,协议HTTPS。
创建3个页面,main.html、manage.html、administrator.html
访问权限如下:
-
必须登录才能访问main.html
-
当前用户必须拥有manage授权才能访问manage.html
-
当前用户必须拥有administrator角色才能访问administrator.html
- main.html
首页
index
- manage.html
manage
index
- administrator.html
administrator
index
- login.html
Thymeleaf整合Shiro
- pom.xml
com.github.theborakompanioni thymeleaf-extras-shiro 2.1.0
- 配置类添加ShiroDialect
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
- index.html 实现权限不同展示效果不同
Title
index
| 退出
main



