赞
踩
SpringBoot约定大于配置,默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。
spring boot的主要优点
使用 IDEA 直接创建项目
1、创建一个新项目
2、选择spring initalizer , 可以看到默认就是去官网的快速构建工具那里实现
3、填写项目信息(springboot版本不宜过高,否则运行报错)
4、选择初始化的组件(初学勾选 Web 即可)
5、填写项目路径
6、等待项目构建成功
项目结构分析:
通过上面步骤完成了基础项目的创建。就会自动生成以下文件。
1、程序的主启动类
2、一个 application.properties 配置文件
3、一个 测试类
4、一个 pom.xml
1、在主程序的同级目录下,新建一个controller包,一定要在同级目录下,否则识别不到
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M8oTF6uK-1684392412403)(D:\X\Pictures\Java\springboot\helloworld.png)]
2、在包中新建一个HelloController类
//自动装配,是@ResponsBody与@Controller的结合体
@RestController
public class HelloController {
//接口:http://localhost:8080/hello
@RequestMapping("/hello")
public String hello(){
return "hello world";
}
}
3、编写完毕后,从主程序启动项目,浏览器发起请求,看页面返回;控制台输出了 Tomcat 访问的端口号!
简单几步,就完成了一个web接口的开发,SpringBoot就是这么简单。所以我们常用它来建立我们的微服务项目!
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 父依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.7</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.jiang</groupId> <artifactId>helloworld</artifactId> <version>0.0.1-SNAPSHOT</version> <name>helloworld</name> <description>Demo project for Spring Boot</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- web场景启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springboot单元测试 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>11</source> <target>11</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
改变端口号
# springboot核心配置文件:application.properties
server.port=8081
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
@SpringBootApplication//标注这个类是一个springboot的应用
public class HelloworldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloworldApplication.class, args);
}
}
@SpringBootConfiguration //SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;
@Configuration//说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;
@Component //说明,启动类本身也是Spring中的一个组件而已,负责启动应用!
@EnableAutoConfiguration //开启自动配置功能
@AutoConfigurationPackage//自动配置包
@import //Spring底层注解@import , 给容器中导入一个组件
@Import({AutoConfigurationImportSelector.class}) //给容器导入组件 ;
@RequestParam //用于将指定的请求参数赋值给方法中的形参。
@Controller:标识一个Spring类是Spring MVC controller处理器,@RestController
@RestController是@Controller和@ResponseBody的结合体,两个标注合并起来的作用。
@Controller类中的方法可以直接通过返回String跳转到jsp、ftl、html等模版页面。
在方法上加@ResponseBody注解,也可以返回实体对象。@RestController类中的所有方法只能返回String、Object、Json等实体对象,不能跳转到模版页面。
spring.factories
yml基础语法
1、空格不能省略
2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
3、属性和值的大小写都是十分敏感的。
yml可以直接给实体类赋值
product:
id: 1001
name: cake
sell: false
date: 2023/1/23
maps: {k1: v1,k2: v2}
lists:
- soft
- white
- sweet
person:
name: jyh
age: 20
@Component//注册bean @Data /* @ConfigurationProperties作用: 将配置文件中配置的每一个属性的值,映射到这个组件中; 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定 参数 prefix = “product” : 将配置文件中的product下面的所有属性一一对应 */ @ConfigurationProperties(prefix = "product") public class Product { private Integer id; private String name; private Boolean sell; private Date date; private Map<String,Object> maps; private List<Object> lists; private Person person; } @SpringBootTest class Springboot02ConfigApplicationTests { @Autowired //将product自动注入进来 private Product product; @Test void contextLoads() { System.out.println(product); } }
//加载指定的配置文件
@PropertySource(value = "classpath:application.properties")
@Component //注册bean
@ConfigurationProperties(prefix = "person")
@Validated //数据校验
public class Person {
@Email(message="邮箱格式错误") //name必须是邮箱格式
private String name;
}
常见参数
@NotNull(message="名字不能为空") private String userName; @Max(value=120,message="年龄最大不能查过120") private int age; @Email(message="邮箱格式错误") private String email; 空检查 @Null 验证对象是否为null @NotNull 验证对象是否不为null, 无法查检长度为0的字符串 @NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格. @NotEmpty 检查约束元素是否为NULL或者是EMPTY. Booelan检查 @AssertTrue 验证 Boolean 对象是否为 true @AssertFalse 验证 Boolean 对象是否为 false 长度检查 @Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内 @Length(min=, max=) string is between min and max included. 日期检查 @Past 验证 Date 和 Calendar 对象是否在当前时间之前 @Future 验证 Date 和 Calendar 对象是否在当前时间之后 @Pattern 验证 String 对象是否符合正则表达式的规则 .......等等 除此以外,我们还可以自定义一些数据校验规则
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;
例如:
application-test.properties 代表测试环境配置
application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;
我们需要通过一个配置来选择需要激活的环境:
#比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;
#我们启动SpringBoot,就可以看到已经切换到dev下的配置了;
spring.profiles.active=dev
yml的多文档块
server: port: 8081 #选择要激活那个环境块 spring: profiles: active: prod --- server: port: 8083 spring: profiles: dev #配置环境的名称 --- server: port: 8084 spring: profiles: prod #配置环境的名称
注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!
在配置文件中能配置的东西,都存在一个固有的规律: xxxAutoConfiguration默认值 xxxProperties和配置文件绑定,我们就可以使用自定义的配置了。
shift+shift键搜索所有
自动装配原理
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
**xxxxAutoConfigurartion:自动配置类;**给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
通过yml文件修改相关属性的值
自动装配
要解决的问题:
拿到静态资源的方式:
(1)webjars
http://localhost:8080/webjars/github-com-jquery-jquery/3.4.1/jquery.js
(2)resources目录下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8LaJGUUl-1684392412405)(D:\X\Pictures\Java\springboot\resource.jpg)]
resource目录下的public、resources、static、templates文件夹中的资源可被识别,其中优先级从高到低为:resources > static (默认)>public
http://localhost:8080/**/
<!-- http://localhost:8080/1.js >
很少使用webjars
放在public或者static目录下
作用:写一个页面
需要使用thymeleaf,只需要导入对应的依赖.我们将html页面放在templates目录下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
html文件中添加
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
//在templates目录下的所有页面,只能通过controller来跳转
//需要thyeleaf模板引擎的支持
@Controller
public class TestController {
@RequestMapping("/test")
public String test(Model model){
model.addAttribute("msg","<h1>hello,springboot</h1>");
return "test";
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--所有的html元素都可以被thymeleaf替换接管: th:元素名-->
<!--不转义-->
<div th:text="${msg}"></div>
<!--转义-->
<div th:utext="${msg}"></div>
</body>
</html>
不要加注解@EnableWebMvc(此注解就是导入了一个类DelegatingWebMvcConfiguration:从容器中获取所有的WebMvcConfig),否则其他注解会失效
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/jiang").setViewName("/test");
}
}
在springboot中,有非常多的xxx Configuration,这是用来扩展的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yznmu2dr-1684392412406)(D:\X\Pictures\Java\springboot\i18n.jpg)]
login.password=password
login.remember=Remember me
login.tip=Please sign in
login.username=username
login.btn=Sign in
shift+shift快速查找
如果需要在项目中进行按钮自动切换,我们需要自定义一个组件LocaleResolver
public class MyLocalResolver implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest request) { String language = request.getParameter("lang"); Locale locale = Locale.getDefault(); if(!StringUtils.isEmpty(language)){ String[] strings=language.split("_"); return new Locale(strings[0],strings[1]); } return locale; } @Override public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { }
注册到容器
//MyMVCConfig类中
@Bean
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}
<body class="text-center"> <form class="form-signin" action="dashboard.html"> <img class="mb-4" src="/img/bootstrap-solid.svg" alt="" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1> <label class="sr-only" >Username</label> <input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""> <label class="sr-only" >Password</label> <input type="password" class="form-control" th:placeholder="#{login.password}" required=""> <div class="checkbox mb-3"> <label th:text="#{login.remember}"> <input type="checkbox" value="remember-me"> Remember me </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button> <p class="mt-5 mb-3 text-muted">© 2022-2023</p> <!添加超链接路径--> <a class="btn btn-sm" th:href="@{/index.html(lang='zh_CN')}">中文</a> <a class="btn btn-sm" th:href="@{/index.html(lang='en_US')}">English</a> </form> </body>
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar"></nav>
<div th:insert="~{commons::topbar}"></div>
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.15</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.15</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
在配置文件中选择数据源为druid
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource druid: username: root password: 123456 url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&userUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver initial-size: 5 min-idle: 5 max-active: 20 max-wait: 60000 time-between-eviction-runs-millis: 6000 min-evictable-idle-time-millis: 30000 validation-query: select 1 from dual test-while-idle: true test-on-borrow: false test-on-return: false pool-prepared-statements: true filters: stat,wall,log4j max-pool-prepared-statement-per-connection-size: 20 use-global-data-source-stat: true connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
@Configuration public class DruidConfig { @ConfigurationProperties(prefix = "spring.datasource.druid") @Bean public DataSource druidDataSource(){ return new DruidDataSource(); } //后台监控:web.xml //因为SpringBoot内置了servlet容器,所以没有web.xml @Bean public ServletRegistrationBean StatViewServlet(){ ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<StatViewServlet>(new StatViewServlet(), "/druid/*"); //后台需要有人登录,账号密码配置 HashMap initParameters = new HashMap<String, String>(); //登录的key是固定的:loginUsername,loginPassword initParameters.put("loginUsername","admin"); initParameters.put("loginPassword","123456"); //允许谁可以访问 initParameters.put("allow",""); //禁止谁访问 bean.setInitParameters(initParameters); return bean; } //filter @Bean public FilterRegistrationBean webStatFilter(){ FilterRegistrationBean bean = new FilterRegistrationBean<Filter>(); bean.setFilter(new WebStatFilter()); //可以过滤哪些请求 Map<String,String> initParameters = new HashMap(); //这些东西不进行统计(让druid不监控这些) initParameters.put("exclusions","*.js,*.css,/druid/*"); return bean; } }
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
mybatis:
type-aliases-package: com.jiang.entity
mapper-locations: classpath:mybatis/mapper/*.xml
@Mapper
@Repository
public interface UserMapper {
List<User> queryUserList();
User queryUserById(int id);
int addUser(User user);
int updateUser(User user);
int deleteUser(User user);
}
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.jiang.mapper.UserMapper"> <select id="queryUserList" resultType="User"> select * from user </select> <select id="queryUserById" parameterType="int" resultType="User"> select* from user where id=#{id} </select> <insert id="addUser" parameterType="User"> insert into user(id,name,pwd) values (#{id},#{name},#{pwd}) </insert> <update id="updateUser" parameterType="User"> update user set name=#{name},pwd=#{pwd} where id=#{id} </update> <delete id="deleteUser" parameterType="User"> delete from user where id=#{id} </delete> </mapper>
@RestController public class UserController { @Autowired private UserMapper userMapper; //url请求都是GetMapping @GetMapping("/UserList") public List<User> queryUserList(){ List<User> userList = userMapper.queryUserList(); return userList; } @GetMapping("/user/{id}") public User queryUserById(@PathVariable("id") int id){ return userMapper.queryUserById(id); } @GetMapping("/add") public String addUser(){ int result=userMapper.addUser(new User(5,"李四","1111")); return result==0?"failed":"success"; } @GetMapping("/update") public String updateUser(){ int result= userMapper.updateUser(new User(1,"Amy","111111")); return result==0?"failed":"success"; } @GetMapping("/delete") public String deleteUser(){ int result=userMapper.deleteUser(new User(5,"李四","1111")); return result==0?"failed":"success"; } }
安全要在设计之初考虑
两个框架—shiro、SpringSecurity:非常相似,除了类不一样,名字不一样
认证、授权(VIP1,VIP2,VIP3)
springsecurity简介
customizable authentication and access-control framework(身份验证和访问控制的框架)
记住几个类:
两个主要目标:
//授权 @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { //首页所有人都可以访问,功能页只有对应有权限的人才能访问 //请求授权的规则: http.authorizeHttpRequests().antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("vip2") .antMatchers("/level3/**").hasRole("vip3"); //无权限默认到登录页,我们需要 开启登录页面 //loginPage the login page to redirect to if authentication is required 身份验证跳转的页面 //loginProcessingUrl :the URL to validate username and password验证表单中的用户名和密码,即form表单提交的地址 http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login"); //注销,然后跳回首页 http.logout().logoutSuccessUrl("/"); http.csrf().disable();//关闭csrf(跨域攻击),否则post请求不生效 //开启记住我功能(cookie):默认保存14天 http.rememberMe().rememberMeParameter("remember"); } //认证 //密码编码(PasswordEncoder) @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //这些数据正常应该从数据库中获得 auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("jiang").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3").and() .withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123123")).roles("vip1").and() .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3"); } }
Apache Shiro 是一个强大灵活的开源安全框架,可以完全处理身份验证、授权、加密和会话管理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JMaUdsjM-1684392412407)(D:\X\Pictures\Java\springboot\shiro1.png)]
Subject:应用代码直接交互的对象是Subject,也就是说Shiro的对外API 核心就是Subject。Subject 代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;与Subject 的所有交互都会委托给SecurityManager;Subject 其实是一个门面,SecurityManager才是实际的执行者
SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且其管理着所有Subject;可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC中DispatcherServlet的角色
Realm:Shiro从Realm 获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm 得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm 看成DataSource
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5DSZq4c-1684392412407)(D:\X\Pictures\Java\springboot\shiro2.png)]
1.导入依赖
2.导入配置文件
3.导入quickstart.java
//一个用户对应多个角色,一个角色对应多个权限
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
currentUser.isAuthenticated()
currentUser.getPrincipal()
currentUser.hasRole("schwartz")
currentUser.isPermitted("lightsaber:wield")
currentUser.logout();
导入shiro-springboot整合依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.8.0</version>
</dependency>
自定义Realm
package com.jiang.config; import org.apache.catalina.User; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; //自定义Realm public class UserRealm extends AuthorizingRealm { //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("执行了授权:doGetAuthorizationInfo"); return null; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("执行了认证:doGetAuthenticationInfo"); //用户名,密码 数据库中获得 String username="root"; String pwd="123456"; UsernamePasswordToken userToken=(UsernamePasswordToken) token; if (!userToken.getUsername().equals(username)){ return null; } //密码认证:shiro自己做 return new SimpleAuthenticationInfo("",pwd,""); /* UsernamePasswordToken userToken=(UsernamePasswordToken) token; User user = userService.queryUserByName(userToken.getUsername()); if (user==null){ return null; } //密码认证:shiro自己做,加密了 return new SimpleAuthenticationInfo("",user.getPwd(),""); */ } }
编写shiro配置文件
@Configuration public class ShiroConfig { //ShiroFilterFactoryBean //DefaultWebSecurityManager //创建Realm对象,需要自定义 //3.ShiroFilterFactoryBean @Bean(name = "shiroFilterFactoryBean") public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); return bean; } //2.DefaultWebSecurityManager @Bean(name = "securityManager") public DefaultWebSecurityManager getdefaultSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); //关联UserRealm securityManager.setRealm(userRealm); return securityManager; } //1、创建realm对象,需要自定义类 @Bean public UserRealm userRealm(){ return new UserRealm(); } }
package com.jiang.config; import com.jiang.pojo.User; import com.jiang.service.UserService; import com.jiang.service.UserServiceImpl; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; //自定义Realm public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("执行了授权:doGetAuthorizationInfo"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermission("user:add"); return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // System.out.println("执行了认证:doGetAuthenticationInfo"); // String username="root"; // String pwd="123456"; // UsernamePasswordToken userToken=(UsernamePasswordToken) token; // // if (!userToken.getUsername().equals(username)){ // return null; // } // // //密码认证:shiro自己做,加密了 // return new SimpleAuthenticationInfo("",pwd,""); UsernamePasswordToken userToken=(UsernamePasswordToken) token; User user = userService.queryUserByName(userToken.getUsername()); if (user==null){ return null; } //密码认证:shiro自己做,加密了 return new SimpleAuthenticationInfo("",user.getPwd(),""); } }
package com.jiang.config; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; 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; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { //ShiroFilterFactoryBean //DefaultWebSecurityManager //创建Realm对象,需要自定义 //3.ShiroFilterFactoryBean @Bean(name = "shiroFilterFactoryBean") public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); //添加shiro的内置过滤器 /* * anon:无需认证就能访问 * authc:必须认证了才能访问 * user:必须拥有 记住我 功能才能用 * perms:拥有对某个资源的权限才能访问 * role:拥有某个角色权限才能访问 * */ //拦截 Map<String, String> filterMap=new LinkedHashMap<>(); //授权 filterMap.put("/user/add","perms[user:add]");//add需要权限才能访问 filterMap.put("/user/update","perms[user:update]"); filterMap.put("/user/*","authc"); //未授权 bean.setUnauthorizedUrl("/unauth"); bean.setFilterChainDefinitionMap(filterMap); //设置登录的请求 bean.setLoginUrl("/toLogin"); return bean; } //2.DefaultWebSecurityManager @Bean(name = "securityManager") public DefaultWebSecurityManager getdefaultSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); //关联UserRealm securityManager.setRealm(userRealm); return securityManager; } //1、创建realm对象,需要自定义类 @Bean public UserRealm userRealm(){ return new UserRealm(); } //整合shiroDialect: @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } }
vue+springboot
前后端如何交互:API
Swagger应运而生
在项目中使用Swagger需要springbox
1.新建springboot-web项目
2.导入相关依赖
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
配置swagger
@Configuration
@EnableSwagger2 //开启swagger2
public class SwaggerConfig {
}
可能出错,解决方法:降swagger和springboot版本(2.5.1)
配置扫描接口
@Bean public Docket docket(){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(myApiInfo()) // enable(false)浏览器不启动swagger //RequestHandlerSelectors配置要扫描接口的方式 //basePackage:要扫描的包 //withClassAnnotation()扫描类上注解 //withMethodAnnotation()扫描方法上注解 .select().apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) //paths:过滤什么路径 //.paths(PathSelectors.ant("/jiang/**")) .build(); }
配置API文档的分组
.groupName("jyh")
配置多个分组:创建多个Docket
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("A");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("B");
}
@Bean
public Docket docket3(){
return new Docket(DocumentationType.SWAGGER_2).groupName("C");
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QHzChK1b-1684392412408)(D:\文档1\markdown笔记\SSM框架\swagger.jpg)]
实体类配置
//只要我们的接口中,返回值中存在实体类,他就会被扫描到Swagger中
@PostMapping("/user")
public User getUser(){
return new User();
}
@ApiModel("用户实体类")
public class User {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
}
@Async
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("数据正在处理...");
}
//主方法上开启异步
@EnableAsync
1.获取授权码
2.编写配置文件
spring.mail.username=2798336160@qq.com
spring.mail.password=wbsbtjfdljzkdebg
spring.mail.host=smtp.qq.com
#开启加密验证
spring.mail.properties.mail.smtp.ssl.enable=true
3.编写邮件信息
@Autowired JavaMailSenderImpl mailSender; //一个简单的邮件 @Test void contextLoads() { SimpleMailMessage mailMessage = new SimpleMailMessage(); //主题 mailMessage.setSubject("20230518"); mailMessage.setText("邮件发送任务"); mailMessage.setFrom("2798336160@qq.com"); mailMessage.setTo("jiangyanhua623@163.com"); mailSender.send(mailMessage); } //复杂的邮件 @Test void contextLoads2() throws MessagingException { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setSubject("邮件测试"); // helper.setText("坚持就会有收获"); helper.setText("<p>fighting</p>",true); //附件 helper.addAttachment("detais.jpg",new File("D:\\文档1\\markdown笔记\\Linux操作系统\\img\\detais.jpg")); helper.setFrom("2798336160@qq.com"); helper.setTo("2798336160@qq.com"); mailSender.send(mimeMessage); }
1.开启定时任务
@EnableScheduling
@Service
public class ScheduledService {
//在一个特定的时间执行该方法
//秒 分 时 日 月 周几
//* 每 ?未知
@Scheduled(cron = "0 42 13 * * ?")
public void hello(){
System.out.println("hello,你被执行了");
}
}
jfdljzkdebg
spring.mail.host=smtp.qq.com
#开启加密验证
spring.mail.properties.mail.smtp.ssl.enable=true
3.编写邮件信息 ```java @Autowired JavaMailSenderImpl mailSender; //一个简单的邮件 @Test void contextLoads() { SimpleMailMessage mailMessage = new SimpleMailMessage(); //主题 mailMessage.setSubject("20230518"); mailMessage.setText("邮件发送任务"); mailMessage.setFrom("2798336160@qq.com"); mailMessage.setTo("jiangyanhua623@163.com"); mailSender.send(mailMessage); } //复杂的邮件 @Test void contextLoads2() throws MessagingException { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setSubject("邮件测试"); // helper.setText("坚持就会有收获"); helper.setText("<p>fighting</p>",true); //附件 helper.addAttachment("detais.jpg",new File("D:\\文档1\\markdown笔记\\Linux操作系统\\img\\detais.jpg")); helper.setFrom("2798336160@qq.com"); helper.setTo("2798336160@qq.com"); mailSender.send(mimeMessage); }
1.开启定时任务
@EnableScheduling
@Service
public class ScheduledService {
//在一个特定的时间执行该方法
//秒 分 时 日 月 周几
//* 每 ?未知
@Scheduled(cron = "0 42 13 * * ?")
public void hello(){
System.out.println("hello,你被执行了");
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。