个人博客
http://www.milovetingting.cn
第一个SpringBoot程序
1、创建项目
选择Spring Initializr
,点击Next

2、设置项目

3、选择依赖

4、填写项目信息

5、创建controller
FooController
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package com.wangyz.springboot.controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
@RestController @RequestMapping("/foo") public class FooController { @RequestMapping("/hello") public String hello(){ return "hello"; } }
|
6、运行项目

7、在浏览器查看

修改默认启动banner
在Resources
目录下新建banner.txt
文件,内容随意,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| //////////////////////////////////////////////////////////////////// // _ooOoo_ // // o8888888o // // 88" . "88 // // (| ^_^ |) // // O\ = /O // // ____/`---'\____ // // .' \\| |// `. // // / \\||| : |||// \ // // / _||||| -:- |||||- \ // // | | \\\ - /// | | // // | \_| ''\---/'' | | // // \ .-\__ `-` ___/-. / // // ___`. .' /--.--\ `. . ___ // // ."" '< `.___\_<|>_/___.' >'"". // // | | : `- \`.;`\ _ /`;.`/ - ` : | | // // \ \ `-. \_ __\ /__ _/ .-` / / // // ========`-.____`-.___\_____/___.-`____.-'======== // // `=---=' // // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // // 佛祖保佑 永不宕机 永无BUG // ////////////////////////////////////////////////////////////////////
|
启动后,可以看到已经修改

YAML
基本数据类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| name: zs
person: name: zs age: 18
student: {name: zs,age: 18}
aninals: - dog - cat
pets: [dog,cat]
|
相对于properties
只能保存key-value
,yaml
可以保存更多的数据类型
在properties
和yaml
中同时配置,properties
的优先级要高。
给实体赋值
1、使用默认的配置文件:application.properties
、application.yaml
1 2 3
| person: name: ls age: 18
|
1 2
| person.name=zs person.age=18
|
person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.wangyz.springboot.pojo;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;
@Component @ConfigurationProperties(prefix = "person") public class Person { private String name; private int age;
public Person() { }
public Person(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
|
SpringbootApplicationTests.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.wangyz.springboot;
import com.wangyz.springboot.pojo.Person; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest class SpringbootApplicationTests {
@Autowired private Person person;
@Test void contextLoads() { System.out.println(person); }
}
|
2、自定义配置文件
person.properties
1 2
| person.name=ww person.age=18
|
person.java
1 2 3 4 5 6 7 8
| @Component
@PropertySource(value = "classpath:person.properties") public class Person { @Value("${person.name}") private String name; private int age; }
|
JSR303校验
1、依赖引入
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>7.0.1.Final</version> </dependency>
<dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <version>3.0.0</version> </dependency>
|
2、增加注解
Person.java
1 2 3 4 5 6
| @Validated public class Person { @Email(message = "邮箱格式不正确") @Value("${person.email}") private String email; }
|
多环境配置
优先级
1、项目根目录下的config文件夹下的配置文件
2、项目根目录下的配置文件
3、Resource目录下的config文件夹下的配置文件
4、Resource目录下的配置文件
多环境
1、通过properties
设置
application-dev.properties
application-test.properties
application.properties
选择环境
1
| spring.profiles.active=test
|
2、通过yaml
设置
application.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| server: port: 8084 spring: profiles: active: test
--- server: port: 8085 spring: profiles: dev
--- server: port: 8086 spring: profiles: test
|
静态资源配置
优先级
resources
>static
>public
自定义资源路径
1 2
| spring.mvc.static-path-pattern=/foo/** spring.web.resources.static-locations=classpath:/foo
|
自定义首页
index.html
可以放在resources
目录下的public
,resources
,static
目录下
Thymeleaf
1、导入依赖
1 2 3 4 5 6 7 8 9
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
<dependency> <groupId>nz.net.ultraq.thymeleaf</groupId> <artifactId>thymeleaf-layout-dialect</artifactId> </dependency>
|
2、配置
1 2 3 4 5 6 7 8 9
| spring.thymeleaf.cache = false
spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.mode=HTML5
spring.thymeleaf.suffix=.html
spring.thymeleaf.prefix=classpath:/templates/
|
自定义视图解析器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.wangyz.springboot.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Locale;
@Configuration public class MyMvcConfig implements WebMvcConfigurer {
@Bean public ViewResolver myViewResolver() { return new MyViewResolver(); }
public static class MyViewResolver implements ViewResolver {
@Override public View resolveViewName(String viewName, Locale locale) throws Exception { return null; } } }
|
视图控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.wangyz.springboot.config;
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration public class MyMvcConfig implements WebMvcConfigurer {
@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/thymeleaf/hello").setViewName("index"); } }
|
JDBC
1、依赖
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency>
|
2、配置
application.yml
1 2 3 4 5 6
| spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver
|
3、使用
JDBCController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package com.wangyz.demo.controller;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.Map;
@RestController public class JDBCController { @Autowired(required = false) JdbcTemplate template;
@GetMapping("/addUser") public String addUser() { String sql = "insert into mybatis.user(id,name,pwd) values(5,'hello','123456')"; template.update(sql); return "add success!"; }
@GetMapping("/deleteUser/{id}") public String deleteUser(@PathVariable("id") int id) { String sql = "delete from mybatis.user where id=?"; Object[] params = new Object[1]; params[0] = id; template.update(sql, params); return "delete success!"; }
@GetMapping("/updateUser/{id}") public String updateUser(@PathVariable("id") int id) { String sql = "update mybatis.user set name=?,pwd=? where id=?"; Object[] params = new Object[3]; params[0] = "小明"; params[1] = "123456"; params[2] = id; template.update(sql, params); return "update success!"; }
@GetMapping("/userList") public List<Map<String, Object>> getUserList() { String sql = "select * from mybatis.user"; List<Map<String, Object>> list = template.queryForList(sql); return list; } }
|
Druid
1、依赖
1 2 3 4 5
| <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.15</version> </dependency>
|
2、配置YAML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true
filters: stat maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionoProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
|
3、Config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package com.wangyz.demo.config;
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource; import java.util.HashMap; import java.util.Map;
@Configuration public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druidDataSource(){ return new DruidDataSource(); }
@Bean public ServletRegistrationBean statViewServlet(){ ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*"); HashMap<String,String> initParam = new HashMap<>(); initParam.put("loginUsername","admin"); initParam.put("loginPassword","123456"); initParam.put("allow","");
bean.setInitParameters(initParam); return bean; }
@Bean public FilterRegistrationBean webStatFilter(){ FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new WebStatFilter()); Map<String,String> initParam = new HashMap<>(); initParam.put("exclusions","*.js,*.css,/druid/*"); bean.setInitParameters(initParam); return bean; } }
|
4、访问
http://localhost:8080/druid/index.html
MyBatis
1、依赖
1 2 3 4 5 6 7 8 9
| <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
|
2、pojo
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package com.wangyz.demo.pojo;
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;
@Data @AllArgsConstructor @NoArgsConstructor public class User { private int id; private String name; private String pwd; }
|
3、mapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.wangyz.demo.mapper;
import com.wangyz.demo.pojo.User; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper @Repository public interface UserMapper {
int addUser(User user);
int deleteUser(int id);
int updateUser(User user);
User getUserById(int id);
List<User> getUserList();
}
|
4、mapper.xml
resource/mybatis/mapper/UserMapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?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.wangyz.demo.mapper.UserMapper">
<insert id="addUser" parameterType="User"> insert into mybatis.user (id,name,pwd) values(#{id},#{name},#{pwd}) </insert>
<delete id="deleteUser" parameterType="int"> delete from mybatis.user where id = #{id} </delete>
<update id="updateUser" parameterType="User"> update mybatis.user set name=#{name},pwd=#{pwd} where id = #{id} </update>
<select id="getUserById" resultType="User"> select * from mybatis.user where id = #{id} </select>
<select id="getUserList" resultType="User"> select * from mybatis.user </select> </mapper>
|
5、配置
application.properties
1 2
| mybatis.type-aliases-package=com.wangyz.demo.pojo mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
|
Spring Security
1、依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
<dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> <version>3.0.5.RELEASE</version> </dependency>
|
2、controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package com.wangyz.demo.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;
@Controller public class SecurityController {
@RequestMapping("/") public String index() { return "index.html"; }
@RequestMapping("/l1") public String l1() { return "/l1/index.html"; }
@RequestMapping("/l2") public String l2() { return "/l2/index.html"; }
@RequestMapping("/l3") public String l3() { return "/l3/index.html"; }
@RequestMapping("/toLogin") public String login(){ return "login.html"; }
@RequestMapping("/toLogout") public String logout(){ return "logout.html"; } }
|
3、config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| package com.wangyz.demo.config;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/l1/**").hasRole("v1") .antMatchers("/l2/**").hasRole("v2") .antMatchers("/l3/**").hasRole("v3");
http.formLogin() .loginPage("/toLogin") .loginProcessingUrl("/login") .usernameParameter("username") .passwordParameter("password");
http.logout().logoutSuccessUrl("/");
http.rememberMe().rememberMeParameter("remember"); }
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("v1", "v2", "v3") .and() .withUser("u1").password(new BCryptPasswordEncoder().encode("123456")).roles("v1") .and() .withUser("u2").password(new BCryptPasswordEncoder().encode("123456")).roles("v2") .and() .withUser("u3").password(new BCryptPasswordEncoder().encode("123456")).roles("v3") ;
} }
|
4、index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body>
<div sec:authorize="isAuthenticated()"> <label sec:authentication="name"></label> <label sec:authentication="principal.authorities"></label> <a th:href="@{/toLogout}">退出</a> </div>
<div sec:authorize="!isAuthenticated()"> <a th:href="@{/toLogin}">登录</a> </div>
<a th:href="@{/l1}">l1</a><br/> <a th:href="@{/l2}">l2</a><br/> <a th:href="@{/l3}">l3</a><br/> </body> </html>
|
5、login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <!doctype html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Login</title> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <link th:href="@{/css/signin.css}" rel="stylesheet"> </head> <body class="text-center">
<main class="form-signin w-100 m-auto"> <form th:action="@{/login}" method="post"> <img class="mb-4" th:src="@{/img/bootstrap-logo.svg}" alt="" width="72" height="57"> <h1 class="h3 mb-3 fw-normal" text="请登录"></h1>
<div class="form-floating"> <input type="text" class="form-control" id="floatingInput" th:placeholder="用户名" name="username"> <label for="floatingInput" th:text="用户名"></label> </div> <div class="form-floating"> <input type="password" class="form-control" id="floatingPassword" th:placeholder="密码" name="password"> <label for="floatingPassword" th:text="密码"></label> </div>
<div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me" th:text="记住我" name="remember"> </label> </div> <button class="w-100 btn btn-lg btn-primary" type="submit" th:text="登录"></button> <p class="mt-5 mb-3 text-muted">© 2017–2022</p> </form> </main>
</body> </html>
|
6、logout.html
1 2 3 4 5 6 7 8 9 10 11 12
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Logout</title> </head> <body> <form th:action="@{/logout}" method="post"> <input type="submit" value="退出"> </form> </body> </html>
|