Spring Boot整合
Spring和Spring Boot都是用来构建项目的脚手架
Spring和Spring Boot的区别?
Spring 需要手动进行组件的配置
Spring Boot是自动进行组件的配置
一、Spring Boot如何自动进行组件的配置
1.1 自动装配
引入了MyBatis的依赖,项目启动时会自动加载MyBatis相关的组件
DataSource 、sqlSessionFactory...
当启动了Spring Boot时,pom.xml中配置的所有框架的组件都会自动进行加载。
比如:pom.xml中引入了mybatis依赖,不配置datasource,启动就会报错。
1.2 如何进行自动装配?
- pom.xml文件中添加mybatis的依赖
- Spring Boot就会自动加载MyBatis需要的bean
只需要在该类配置中将需要创建的对象进行配置即可,Spring 框架就会读取配置类,进而创建对象(反射)
Spring Boot如何自动实现bean的创建,通过配置类的方式
引入MyBatis依赖之后,依赖中会包含一个配置类的信息,配置类中会标注要创建的bean
Spring Boot启动之后会读取配置类信息,从而获得MyBatis需要创建的bean,然后进行创建
Maven:org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:3.0.5
/META-INF/spring.factories
启动Spring Boot时,会读取spring.factories文件,通过key获取到两个配置类。
二、MyBatis Plus
MyBatis Plus基于MyBatis,MyBatis需要开发者手动编写SQL语句,MyBatis Plus不需要开发者手动编写。使用MyBatis Plus会减少代码量。
XML
<dependency>
<groupId>com.baomidou<groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.1</version>
</dependency>
MyBatis Plus除了可以自动生成SQL外,还可以自动生成代码(Controller、Service、Mapper和Enity)
2.1 MyBatis Plus逆向工程的依赖
XML
<!--mybatis plus逆向工程的依赖 要跟starter的版本一致-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.7</version>
</dependency>
<!--模板引擎-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
3.5.x 完全重构了生成器,旧的 AutoGenerator 类虽然还在,但构造器已私有化,必须使用新的 流式 API。建议使用3.3.2
XML
<!--mybatis plus的依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--mybatis plus逆向工程的依赖 跟starter的版本一致-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<!--模板引擎-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
2.2 通过表逆向生成项目
java
package com.dyz;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
public class Main {
public static void main(String[] args) {
AutoGenerator autoGenerator = new AutoGenerator();
//配置数据源
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL);
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/car_rental_separate?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("123456");
autoGenerator.setDataSource(dataSourceConfig);
//全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOpen(false);
globalConfig.setOutputDir(System.getProperty("user.dir") + ("/src/main/java"));
globalConfig.setServiceName("%sService"); //%s替换符,避免出现IService不规范的情况
autoGenerator.setGlobalConfig(globalConfig);
//配置包
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("com.dyz");
packageConfig.setEntity("entity");
packageConfig.setController("controller");
packageConfig.setMapper("mapper");
packageConfig.setService("service");
packageConfig.setServiceImpl("service.impl");
autoGenerator.setPackageInfo(packageConfig);
//生成策略
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setEntityLombokModel(true);
strategyConfig.setInclude("sys_news");
strategyConfig.setNaming(NamingStrategy.underline_to_camel);//下划线转驼峰 SysNew,不是Sys_news这样不规范
autoGenerator.setStrategy(strategyConfig);
//启动
autoGenerator.execute();
}
}
生成器帮你写 Java 代码,但 Spring Boot 的启动配置还得你自己配。
就是说想要项目跑起来,还得自己写appliation.yml配置
java
package com.dyz.controller;
import com.dyz.entity.SysNews;
import com.dyz.service.SysNewsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
//@Controller
@RestController //返回json
@RequestMapping("/news")
public class SysNewsController {
@Autowired
private SysNewsService sysNewsService;
@GetMapping("/list")
public List<SysNews> list(){
return this.sysNewsService.list();
}
@GetMapping("/get/{id}")
public SysNews getById(@PathVariable("id") Integer id){
return this.sysNewsService.getById(id);
}
}
java
package com.dyz;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.dyz.mapper")
public class SpringbootMybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisPlusApplication.class, args);
}
}
三、Spring Boot整合jdbcTemplate
jdbcTemplate是一个轻量级的JDBC封装组件。
jdbcTemplate是Spring自带的JDBC模板组件,底层实现了对JDBC的封装,需要开发者自定义SQL语句,jdbcTemplate帮助完成数据库的连接,SQL的执行,结果集的封装。
jdbcTemplate提供了通用的SQL操作方法,execute、update、batchUpdate、query
jdbcTemplate和MyBatis的区别?
MyBatis的SQL定义在XML文件中,jdbcTemplate的SQL定义在Java类中。
3.1 pom.xml中添加依赖
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
3.2 表创建&实体类

java
package com.dyz.entity;
import lombok.Data;
import java.util.Date;
@Data
public class News {
private int id;
private String title;
private String content;
private Date createtime;
private String opername;
}
3.3 创建Mapper接口,定义JDBC方法
浏览器一般只能测试查询方法
postman一款接口测试工具
java
package com.dyz.jdbcTemplate;
import com.dyz.entity.News;
import java.util.List;
public interface NewsMapper {
public List<News> list();
public News getById(Integer id);
public void add(News news);
public void update(News news);
public void deleteById(Integer id);
public void batchUpdate();
public void batchAdd();
public void batchDelete();
}
java
package com.dyz.jdbcTemplate;
import com.dyz.entity.News;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Repository
public class NewsMapperImpl implements NewsMapper{
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<News> list() {
return this.jdbcTemplate.query("select * from sys_news",new BeanPropertyRowMapper<>(News.class));
}
@Override
public News getById(Integer id) {
return this.jdbcTemplate.queryForObject("select * from sys_news where id = ?",new Object[]{id},new BeanPropertyRowMapper<>(News.class));
}
@Override
public void add(News news) {
this.jdbcTemplate.update("insert into sys_news(title,content,createtime,opername) values(?,?,?,?)",news.getTitle(),news.getContent(),news.getCreatetime(),news.getOpername());
}
@Override
public void update(News news) {
this.jdbcTemplate.update("update sys_news set title = ?,content = ?,createtime = ?,opername = ? where id = ?",news.getTitle(),news.getContent(),news.getCreatetime(),news.getOpername(),news.getId());
}
@Override
public void deleteById(Integer id) {
this.jdbcTemplate.update("delete from sys_news where id = ?",id);
}
@Override
public void batchAdd() {
List<Object[]> args = new ArrayList<>();
args.add(new Object[]{"测试1","这是测试数据1",new Date(),"admin"});
args.add(new Object[]{"测试2","这是测试数据2",new Date(),"admin"});
args.add(new Object[]{"测试3","这是测试数据3",new Date(),"admin"});
args.add(new Object[]{"测试4","这是测试数据4",new Date(),"admin"});
this.jdbcTemplate.batchUpdate("insert into sys_news(title,content,createtime,opername) values (?,?,?,?)",args);
}
@Override
public void batchUpdate() {
List<Object[]> args = new ArrayList<>();
args.add(new Object[]{"测试12","这是测试数据1",new Date(),"admin"});
this.jdbcTemplate.batchUpdate("update sys_news set title = ?,content = ?,createtime=?,opername=?",args);
}
@Override
public void batchDelete() {
List<Object[]> args = new ArrayList<>();
args.add(new Object[]{1});
args.add(new Object[]{5});
this.jdbcTemplate.batchUpdate("delete from sys_news where id = ?",args);
}
}
3.4 controller实现方法
java
package com.dyz.controller;
import com.dyz.entity.News;
import com.dyz.jdbcTemplate.NewsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
//@Controller
@RestController
public class NewsController {
@Autowired
private NewsMapper newsMapper;
@GetMapping("/list")
public List<News> list(){
return this.newsMapper.list();
}
@GetMapping("/getById/{id}")
public News getById(@PathVariable("id") Integer id){
News news = null;
try {
news = this.newsMapper.getById(id);
} catch (Exception e) {
return null;
}
return news;
}
@PostMapping("/add")
public void add(@RequestBody News news){
this.newsMapper.add(news);
}
@PutMapping("/update")
public void update(@RequestBody News news){
this.newsMapper.update(news);
}
@DeleteMapping("/delete/{id}")
public void deleteById(@PathVariable("id") Integer id){
this.newsMapper.deleteById(id);
}
@GetMapping("/batchAdd")
public void batchAdd(){
this.newsMapper.batchAdd();
}
@GetMapping("/batchUpdate")
public void batchUpdate(){
this.newsMapper.batchUpdate();
}
@GetMapping("/batchDelete")
public void batchDelete(){
this.newsMapper.batchDelete();
}
}
四、Spring Boot整合Spring Data JPA
Spring Data JPA是Spring框架提供的持久层解决方案。
4.1 pom.xml中引入依赖
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
4.2 创建数据表&实体类
java
package com.dyz.jpaentity;
import jakarta.persistence.*;
import lombok.Data;
import java.util.Date;
@Data
@Entity(name = "sys_news") //表示关联到数据库
public class News {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //自增
private Integer id;
@Column //普通字段
private String title;
@Column
private String content;
@Column
private Date createtime;
@Column
private String opername;
}
4.3 创建接口
java
package com.dyz.repository;
import com.dyz.jpaentity.News;
import org.springframework.data.jpa.repository.JpaRepository;
public interface NewsRepository extends JpaRepository<News,Integer> {
}
4.4 创建Controller
java
package com.dyz.controller;
import com.dyz.jpaentity.News;
import com.dyz.repository.NewsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/jpa")
public class JPANewsController {
@Autowired
private NewsRepository newsRepository;
@GetMapping("/list")
public List<News> list(){
return this.newsRepository.findAll();
}
@GetMapping("/getById/{id}")
public News getById(@PathVariable("id") Integer id){
Optional<News> optional = this.newsRepository.findById(id);
return optional.get();
}
@PostMapping("/add")
public void add(@RequestBody News news){
this.newsRepository.save(news);
}
@PutMapping("/update")
public void update(@RequestBody News news){
this.newsRepository.save(news);
}
@DeleteMapping("/deleteById/{id}")
public void DeleteById(@PathVariable("id") Integer id){
this.newsRepository.deleteById(id);
}
}
五、Spring Boot整合Spring Security
5.1 登录认证
5.1.1 pom.xml中添加依赖
相当于添加安全校验的框架,会自动跳转到login页面进行校验
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
5.1.2 创建html页面
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Welcome</h1>
</body>
</html>
5.1.3 创建controller
java
package com.dyz.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class IndexController {
@GetMapping("/welcome")
public String index(){
return "welcome";
}
}
5.1.4 控制台输出&测试
username:user



yml文件中可自定义账号密码
java
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/car_rental_separate
username: root
password: 123456
security:
user:
name: dyz
password: 123456
除基本的登录认证,还可以用来完成资源权限管理:当请求某个资源时,对角色进行认证,如果该角色拥有访问权限则正常访问,否则无法访问。
5.2 权限管理
admin:可以访问index和welcome页面
user:只能访问welcome页面

WebSecurityConfigurerAdapter 在 Spring Security 5.7.0+ / Spring Boot 2.7+ 中已被弃用(deprecated) ,并在 Spring Security 6.x / Spring Boot 3.x 中完全移除。
基于内存的用户认证(In-Memory Authentication) + URL 路径拦截(Filter Chain 授权)
5.2.1 新建页面
index.html
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head><title>首页</title></head>
<body>
<h2>🔴 管理员专属页面 - Index</h2>
<p>当前用户: <span sec:authentication="name"></span></p>
<p>角色: <span sec:authentication="principal.authorities"></span></p>
<a th:href="@{/welcome}">去Welcome页面</a> |
<form th:action="@{/logout}" method="post" style="display:inline;">
<button type="submit">退出</button>
</form>
</body>
</html>
welcome.html
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head><title>欢迎</title></head>
<body>
<h2>欢迎页面 - Welcome</h2>
<p>当前用户: <span sec:authentication="name"></span></p>
<!-- 只有 ADMIN 能看到这个链接 -->
<div sec:authorize="hasRole('ADMIN')">
<a th:href="@{/index}">去Index页面(仅管理员)</a>
</div>
<!-- 只有 USER 能看到这个提示 -->
<div sec:authorize="hasRole('USER')">
<p>您是普通用户,无法访问 Index 页面</p>
</div>
<form th:action="@{/logout}" method="post" style="display:inline;">
<button type="submit">退出</button>
</form>
</body>
</html>
5.2.2 创建controller
java
package com.dyz.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class IndexController {
@GetMapping("/index")
public String index() {
return "index"; // admin专属页面
}
@GetMapping("/welcome")
public String welcome() {
return "welcome"; // 所有用户都能访问
}
}
5.2.3 安全配置类
java
package com.dyz.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
// 必须放行 Security 内置端点,不写的话,login会被拦截
.requestMatchers("/login", "/logout", "/error").permitAll()
.requestMatchers("/index").hasRole("ADMIN")
.requestMatchers("/welcome").hasAnyRole("ADMIN", "USER")
.anyRequest().authenticated()
)
.formLogin(form -> form.defaultSuccessUrl("/welcome"));
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("123456"))
.roles("ADMIN")
.build();
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("123456"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(admin, user);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
六、Spring Boot整合Shiro
通过过滤器和拦截器去拦截用户的各种请求,然后进行各种验证、登录、权限验证。
6.1 Shiro核心组件
- Token:存储用户登录信息,用户在登录时创建,Shiro通过Token来判断当前用户的身份和权限。
- Subject:存储当前用户信息,当前用户:用户/第三方进程/后台账户/其他正在交互的用户。
- SecurityManager:Shiro的核心,用来管理内部的组件实例,实现安全认证和授权。
- Realm:实现数据交互,对用户执行认证和授权验证时,Shiro从Realm中查找用户信息和权限信息。
6.1.1 pom.xml添加依赖
XML
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.8.0</version>
</dependency>
6.1.2 创建表
sql
mysql> use sys;
Database changed
mysql> create table account(id int primary key auto_increment,username varchar(11),password varchar(11),permits varchar(20),role varchar(20));

6.1.3 创建实体类
java
package com.dyz.entity;
import lombok.Data;
@Data
public class Account {
private Integer id;
private String username;
private String password;
private String permits;
private String role;
}
6.1.4 创建控制器
java
package com.dyz.controller;
import com.dyz.entity.Account;
import com.dyz.mapper.AccountMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountMapper accountMapper;
@GetMapping("/list")
public List<Account> list(){
return this.accountMapper.selectList(null);
}
}
6.1.5 创建mapper
java
package com.dyz.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dyz.entity.Account;
public interface AccountMapper extends BaseMapper<Account> {
}
6.1.6 创建service及其impl
java
package com.dyz.service;
import com.dyz.entity.Account;
public interface AccountService {
public Account findByUsername(String username);
}
java
package com.dyz.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dyz.entity.Account;
import com.dyz.mapper.AccountMapper;
import com.dyz.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public Account findByUsername(String username) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
return this.accountMapper.selectOne(queryWrapper);
}
}
6.1.7 创建Shiro过滤器
java
package com.dyz.realm;
import com.dyz.entity.Account;
import com.dyz.service.AccountService;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.springframework.beans.factory.annotation.Autowired;
//AuthenticatingRealm只支持认证,不支持授权
// AuthorizingRealm 同时支持认证和授权
public class AccountRealm extends AuthorizingRealm {
@Autowired
private AccountService accountService;
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
Account account = this.accountService.findByUsername(token.getUsername());
//验证密码
if (account != null){
return new SimpleAuthenticationInfo(account, account.getPassword(), getName());
}
return null;
}
}
6.1.8 创建配置类
java
package com.dyz.config;
import com.dyz.realm.AccountRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ShiroConfiguration {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(
@Qualifier("securityManager")DefaultWebSecurityManager securityManager
){
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
return factoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(
@Qualifier("accountRealm")AccountRealm accountRealm
){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(accountRealm);
return securityManager;
}
@Bean
public AccountRealm accountRealm(){
return new AccountRealm();
}
}
6.2 Shiro 认证授权规则
认证过滤器:
- anon:无需认证就能访问
- authc:必须登录才能访问
- authBasic:需要通过httpBasic认证
- user:不一定通过认证,只要曾经被Shiro记录过登录状态的用户都可以正常发起请求
授权过滤器
- perms:必须拥有权限才能访问
- roles:必须拥有角色才能访问
- port:请求的端口必须为指定值才可访问
- res:请求必须时基于RESTful的才能访问
- ssl:必须是安全的URL请求,协议为HTTPS
6.2.1 创建页面/要求/完善配置类
login.html、main.html、manage.html、administratoy.html
- 登录状态才能访问main.html页面
- 拥有manager权限的用户才能访问 manage.html
- 拥有administrator角色才能访问administratoy.html
login.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
<table>
<tr>
<td>用户名:</td>
<td>
<input type="text" name = "username"/>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" name="password"/>
</td>
</tr>
<tr>
<td>
<input type="submit" value="登录"/>
</td>
</tr>
</table>
</form>
</body>
</html>
ShiroConfiguration.java
java
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(
@Qualifier("securityManager")DefaultWebSecurityManager securityManager
){
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
//权限设置
Map<String,String> map = new HashMap<>();
map.put("/main","authc");
map.put("/manage","perms[manager]");
map.put("/administrator","roles[administrator]");
factoryBean.setFilterChainDefinitionMap(map);
//设置登陆页面
factoryBean.setLoginUrl("/login");
//设置未授权页面
factoryBean.setUnauthorizedUrl("/unauth");
return factoryBean;
}
6.2.2 controller实现登录
java
@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);
return "main";
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名错误");
return "/login";
} catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "/login";
}
}
@RequestMapping("/unauth")
@ResponseBody
public String unauth(){
return "未授权,无法访问";
}
6.2.3 AccountRealm中实现授权方法
java
//授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection){
//获取当前登录对象
Subject subject = SecurityUtils.getSubject();
Account account = (Account) subject.getPrincipal();
//设置角色
Set<String> roles = new HashSet<>();
roles.add(account.getRole());
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles);
//设置权限
info.addStringPermission(account.getPermits());
return info;
}