SpringBoot基础二
扩展SpringBoot
扩展SpringBoot中的SpringMVC的默认配置
SpringBoot默认已经给我们做了很多SpringMVC的配置,哪些配置?
1、视图解析器ViewResolver
2、静态资料的目录
3、默认首页index.html
4、图标名字和图标所在目录,favicon.ico
5、类型转换器Converter,格式转换器的Formatter
6、消息转换器HttpMessageConverters,我们直接向页面返回JSON格式的数据就靠它实现
7、消息代码解析器MessageCodesResolver, 作用配置了错误代码显示规则的一些东西,JSR303数据校验要用到它
-----但是我们在真正的项目开发中,只有这些默认配置,是绝对不够用的,所以,我们必须得学会在它们的基础上扩展更多我们需要的配置,SpringBoot是给我们提供了相应扩展接口WebMvcConfigurer,实现它并且加@Configuretion注解:
举例子:
在原来我们直接使用SpringMVC的时候,我们可以在springmvc.xml配置文件中直接配置:
<mvc:view-controller path="/index.html" view-name="index"/>
可以实现不用在controller类里写映射方法,访问localhost:8080/index直接打开users2.htmlk页面

注意:这种配置方式是“扩展”SpringBoot对SpringMVC的配置,扩展就是原有的默认配置仍然生效,现在加了我们自己的配置一起生效,但是我们是可以通过一个注解 @EnableWebMvc ,让SpringBoot里默认配置失效的,配置这个注解后,就会只有我们自己做的配置才会生效了,就像我们原来自己使用SpringMVC一样的,什么都需要我们自己配置!
SpringBoot整合JDBC
----讲到这里,基本上我们就可以使用SpringBoot来开发Web项目视图显示和业务逻辑代码,但是要做一个完成案例,我们还差一点点,就是怎么访问数据库,获取数据,接下来我们就看怎么用 SpringBoot整合 我们前面已经讲过的 jdbc,mybatis,springdata jpa,其实本质上SpringBoot底层就是使用SpringData来访问数据库,而前面我们有简介SpringData,知道它不仅仅可以操作关系型数据还可以访问NoSql数据库,所以SpringBoot当然也就是关系和非关系数据库都可以通吃咯,NoSql这块我们后面课程中会详细的讲,
1、导入启动器
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.6</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>cn.xiong.spbtjdbc</groupId><artifactId>spbtjdbc</artifactId><version>0.0.1-SNAPSHOT</version><name>spbtjdbc</name><description>Demo project for Spring Boot</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.11</version></dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

注意:刚开始创建项目时,选了parent 3.0.2出错,叫我降低牍本,到2.7.1和2.0.4.RELEASE都出错,后来改成2.7.6有用了不知为什么
2、配置全局配置文件,本人数据库mysql 8.0版本。
spring.datasource.username=root
spring.datasource.password=xiong
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdemo
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
有关Spring里的数据源啊。。。。如c3p0连接池在SpringBoot都有默认配置的,直接就可以测试了!
3,测试,在test中测试

@SpringBootTest
class SpbtjdbcApplicationTests {@Autowired(required = false)private DataSource dataSource;@Autowired(required = false)private JdbcTemplate jdbcTemplate;@Testvoid contextLoads() throws SQLException {System.out.println(dataSource.getClass());Connection connection=dataSource.getConnection();System.out.println(connection);connection.close();List<Map<String,Object>> maps = jdbcTemplate.queryForList("select *from et_users");System.out.println(maps);}}
------------------------------------------------------------结果-----------------------------------------------------------------------------
HikariProxyConnection@1005400853 wrapping com.mysql.cj.jdbc.ConnectionImpl@119b0892
[{id=1, username=xiongshaow, passwopd=123456}, {id=2, username=xuhuifeng, passwopd=123456}, {id=3, username=熊凌洲, passwopd=123456}]
Hikari为springboot2.0.6后版本使用的数据库连接池传说这个在数据库访问速度上是C3P0的25倍
SpringBoot整合druid数据源
-----SprintBoot默认使用的是HikariDataSource数据源,而且上次课中我们也说了这个数据源访问速度很快,但是这里还要给大家介绍一个第三方的数据源druid,它是阿里开发的一款开源的数据源,被很多人认为是Java语言中最好的数据库连接池,因为Druid能够提供强大的一整套监控和扩展功能,很爽。
1、导入maven的依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.11</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>
使用了log4j就要自己在类路径下加配置文件:log4j.properties
log4j.rootLogger = debug,stdout, D
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.Threshold = INFO
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p %m%n
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ./log4j.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=%d %p %m%n
注意:druid依赖log4j的日志jar包,但是SpringBoot默认使用的是slf4j+logback,所以这里导入log4j的jar包才行

2、在全局配置文件通过type的配置改变数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
3、在运行一下测试方法,看看能不能拿到数据源
@SpringBootTest
class SpbtjdbcApplicationTests {@Autowired(required = false)private DataSource dataSource;@Autowired(required = false)private JdbcTemplate jdbcTemplate;@Testvoid contextLoads() throws SQLException {System.out.println(dataSource.getClass());}}
-------------------------------------------------------后台显示结果有-----------------------------------------
class com.alibaba.druid.pool.DruidDataSource
4、不能用SpirngBoot默认利用反射的机制配置来获取druid数据源,因为数据源特有的配置SpringBoot默认配置是没有的,我们要自己做:
① 首先在全局配置文件中配上 druid 数据源自己的特性配置
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
# 配置监控统计拦截的 filters ,去掉后监控界面 sql 无法统计, 'wall' 用于防火墙
spring.datasource.filters=stat,wall,log4j
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.useGlobalDataSourceStat=true
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
这些配置可以参考阿里巴巴放到guithu网站上的参数。https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
② 自己创建配置类来创建数据源对象,并且手动获取这些配置,配置到数据源里去

@Configuration
public class DruidConfig {@ConfigurationProperties(prefix = "spring.datasource") //把全局配置文件中的配置注入到对象中@Bean //返回的DruidDataSource对象放到IOC容器中public DataSource dataSource(){return new DruidDataSource();}
}
5、配置druid的监控
① 配置管理后台的servlet,druid提供的这个servlet名字叫:StatViewServlet
② 配置web监控的拦截器filter,druid提供的filter名字叫 :WebStatFilter

@Configuration
public class DruidConfig {@ConfigurationProperties(prefix = "spring.datasource")@Beanpublic DataSource dataSource(){return new DruidDataSource();}//配置对web整个应用的监控,在druid中@Beanpublic ServletRegistrationBean getViewServlet(){ServletRegistrationBean bean =new ServletRegistrationBean(new StatViewServlet());String[] urlArr = new String[]{"/druid/*"};bean.setUrlMappings(Arrays.asList(urlArr));//还需要设置druid后台页面的一些基本的东西,后台的登录用户名和密码,后台有哪些ip地址可以访问,哪些不可以Map<String,String> initParams = new HashMap<>();initParams.put("loginUsername","admin");initParams.put("loginPassword","123456");initParams.put("allow",""); //假设任何ip地址可访问initParams.put("deny","12.122.12.1"); //拒绝某一个ip访问,这里当然是假设的bean.setInitParameters(initParams);return bean;}//配置过滤器来寮现对web应用的所有的访问请求进行过滤,从而实现对web应用对数据库的访问监控@Beanpublic FilterRegistrationBean getFilter(){FilterRegistrationBean bean= new FilterRegistrationBean(new WebStatFilter());bean.setUrlPatterns(Arrays.asList(new String[]{"/*"}));Map<String,String> initParams = new HashMap<>();initParams.put("exclusions","*.js,*.css,*.jpg,*.png,/druid/*"); //不在我们拦截之范围 bean.setInitParameters(initParams);return bean;}
}
IndexController.java
@Controller
public class IndexController {@Autowired(required = false)private JdbcTemplate jdbcTemplate;@GetMapping("/index.html")public String index(Model model){List<Map<String,Object>> maps=jdbcTemplate.queryForList("select*from et_users");model.addAttribute("users",maps);return "index";}
}
index.html(thymeleaf视图模板)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>durid_thymeleaf</title>
</head>
<body><div th:each="user:${users}"></div>
</body>
</html>
测试
1.打开监控页
http://localhost:8080/druid/回车
输入用户名:admin,密码 :123456,点‘sql监控’项。
2。打开视图页index.html
http://localhost:8080/index.html
3.测试监控有没有效果。
-----当打开视图页,我们进行了一次查询,从监控页的,“sql监控‘项中可以看到查询语句。

SpringBoot整合Mybatis
- 准备工作
1、建立一个新的工程(我用上一个工程spbtjdbc),把web、jdbc和mybatis的启动器选中
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version>
</dependency>
----mybatis启动器不是springboot官方定的,是mybatis作者自已做的,所以与其它启动器不相同的。
2、把druid数据源配置出来
-----上面已配置了。
3、把测试用的数据库和数据表建立起来

4、把javabean建立起来
User.java
public class User {private int id;private String username;private String password;public User() {}public User(int id, String username, String password) {this.id = id;this.username = username;this.password = password;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
}
-
mybatis增删改查实现
image.png
1、在上次课的配置基础上,创建Mapper接口(UserDao.java--->UserDao.xml)
UserDao.java
import cn.xiong.spbtjdbc.model.User;public interface UserDao {//增public void addUser(User user);//删public void delete(int id);//改public void update(User user);//查public User get(int id);
}
UserDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.xiong.spbtjdbc.dao.UserDao"><insert id="addUser">insert into et_users(username,password) values (#{username},#{password})</insert><delete id="delete">delete from et_user where id=#{id}</delete><update id="update">update et_users u set u.username=#{username},u.password=#{password} where u.id=#{id}</update><select id="get" resultType="cn.xiong.spbtjdbc.model.User">select u.id,u.username,u.password from et_users u where u.id=#{id}</select>
</mapper>
2、在resources下创建一个mybatis的文件夹,在这个文件夹下新建mybatis-config.xml全局配置文件
,这里只有一个配置,驼峰命名。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd" >
<configuration><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
</configuration>
4、在SpringBoot的全局配置文件中配置Mybatis的两个配置文件的位置
spring.datasource.useGlobalDataSourceStat=true
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500#配置mybatis的配置文件的位置
mybatis.config-location=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
5、在启动类上加上注解 @MapperScan ({ "cn.ybzy.springbootmybatis.dao" })来告诉SpringBoot我们的映射接口的位置,
SpbtjdbcApplication
@SpringBootApplication
@MapperScan({"cn.xiong.spbtjdbc.dao"})
public class SpbtjdbcApplication {public static void main(String[] args) {SpringApplication.run(SpbtjdbcApplication.class, args);}}
SpbtjdbcApplicationTests
@SpringBootTest
class SpbtjdbcApplicationTests {@Autowired(required = false)private UserDao userDao;@Testvoid contextLoads() throws SQLException {//mybatis增删改查测试//insert,updateUser user = new User();user.setUsername("熊少华");user.setPassword("123456");user.setPassword("cexoit");userDao.addUser(user);//}}
结果:可以从数据库表中看记录的
SpringBoot整合JPA
-------JPA比mybatis方便,它是基于hibernate实现的,有大量的注解用于实现数据持久化,但在手动写sql语句上不灵活。
- 新建项目,导入启动器jdbc,jpa,mysql,web
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>
- 在全局配置文件中配置jpa的相关属性
spring.datasource.username=root
spring.datasource.password=xiong
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdemo
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#sprigboot 内部是使用 springdata , springdata 里的 jpa 是使用 hibernate 实现的
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
- 创建实体类
mport javax.persistence.*;
import java.util.Date;
@Entity
@Table(name="et_users")
public class User {private int id;private String username;private String password;private Date regDate;public User() {}public User(int id, String username, String password, Date regDate) {this.id = id;this.username = username;this.password = password;this.regDate = regDate;}@Id //让id为主键@GeneratedValue(strategy= GenerationType.IDENTITY) //id自增长public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Column(name="regdate")public Date getRegDate() {return regDate;}public void setRegDate(Date regDate) {this.regDate= regDate;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", regDatel=" + regDate +'}';}
}
解决@Table(name = “t_user“)出现“Cannot resolve table ‘t_user‘“问题
问题原因:数据源的表还没有被识别进模型类中。
处理:
1-工具栏 View -->Tool windows -->Database–>Data Source中填写数据库的信息(用户名root,密码xiong等等,连接到数据库)
或点最右边的--Database选项卡。
2-工具栏View-->Tool windows-->Persistence后双击“entityManagerFactory”右键选择Assign Data Sources加载刚才建的Database,
4、创建jpa的接口UserDao
public interface UserDao extends JpaRepository<User,Integer> {//这里相当于mybatis中的UserDao.java---->UserDao.xml我们可以什么都不用写,//它实现了对表的增册改查
什么都用写,基本的操作,人家都给我们写好了,用就是了!
5、测试就行了
@Controller
public class UserController {@Autowiredprivate UserDao userDao;@ResponseBody //这里没有视图页面,该注解让save success显示在usersave.html中@GetMapping("/usersave.html")public String save(){User user=new User();user.setUsername("马尾农");user.setPassword("123456");user.setRegDate(new Date());userDao.save(user);return "save success";}@ResponseBody@GetMapping("/get_user/{id}")public User getUserById(@PathVariable("id") Integer id){User user = userDao.findById(id).get();return user;}
}

http://localhost:8080/usersave.html
若记录增加成功,会返加如下图的内容

http://localhost:8080/get_user/1
可以获取表的1条记录找印的信息。
用SpringBoot做一个web小案例
- 搭建开发环境,导入相应的启动器和jar包依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.6</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>cn.xiong</groupId><artifactId>spbtapp</artifactId><version>0.0.1-SNAPSHOT</version><name>spbtapp</name><description>Demo project for Spring Boot</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
- 配置数据库基本信息,建立起项目的包结构,并创建model类(数据源等)
spring.datasource.username=root
spring.datasource.password=xiong
spring.datasource.url=jdbc:mysql://124.222.48.147:3306/springbootdemo
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#sprigboot 内部是使用 springdata , springdata 里的 jpa 是使用 hibernate 实现的
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring boot jpa使用注解方式实例化javabean,放进IOC中,十分方便(比以前的spring 5方便很多很多了),会自动创建对应 javabean的表
User.java
@Entity
@Table(name="t_users")
public class User {private int id;private String username;private String password;private Date regDate;private Address address;public User() {}public User(int id, String username, String password, Date regDate, Address address) {this.id = id;this.username = username;this.password = password;this.regDate = regDate;this.address = address;}@Id@GeneratedValue(strategy= GenerationType.IDENTITY)public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Date getRegDate() {return regDate;}@Column(name="reg_date")public void setRegDate(Date regDate) {this.regDate = regDate;}@ManyToOnepublic Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}}
Address.java
@Entity
@Table(name="t_address")
public class Address {private int id;private String addressInfo;@Id@GeneratedValue(strategy= GenerationType.IDENTITY)public int getId() {return id;}public void setId(int id) {this.id = id;}public String getAddressInfo() {return addressInfo;}@Column(name="address_info")public void setAddressInfo(String addressInfo) {this.addressInfo = addressInfo;}}
- 把首页做成登录页面login.html的视图做出来
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>login页面</title>
</head>
<body>
<form th:action="@{/login.html}" method="post">用户名: <input type="text" name="username" placeholder=" 请输入用户名 "/><br/><br/>密 码: <input type="password" name="pasword" placeholder=" 请输入密码 "/><br/><br/><input style="margin-left:60px;" type="submit" value=" 登录 "/>
</form>
</body>
</html>
启动启动类后,没错的话,会生成两张表t_users,t_address.

- 我们在login.html页面输入用户名和密码点击登录,请求访问到/login,然后在login方法里获取User对象,在到UserService的login方法中判断登录,来依照这个逻辑,来完成剩下的功能:
image.png
UserDao.java
public interface UserDao extends JpaRepository<User,Integer> {//不要写任何方法,增删改查都在JpaRepository中实现了。/*** 默认接口实现中没有提供根据用户名查询用记录的方法,所以自已做,但命名规则一定要遵守其getBy,find,delet,save开头的名规则*/public User getByUsername(String username);
}
UserService.java
public interface UserService {//最基本的增删改查public void add(User user);public void delete(int id);public void update(User user);public User get(int id);public List<User> getAllUser();//判断登录的查询,根据用户名来查询有没有用户记录public User login(User user);}
UserServiceImpl.java
import java.util.List;
@Service("userService") //把UserServcieImpl实例放进IOC中
public class UserServiceImpl implements UserService{@Autowired //UserDao接口实现JpaRepository注入到了IOC中。private UserDao userDao;@Overridepublic void add(User user) {userDao.save(user);}@Overridepublic void delete(int id) {userDao.deleteById(id);}@Overridepublic void update(User user) {userDao.saveAndFlush(user);}@Overridepublic User get(int id) {return userDao.findById(id).get();//findById(id)返回一个Optional对象,该对象是一个容器,里面可以只有null,所以再加一个.get()}@Overridepublic List<User> getAllUser() {return userDao.findAll();}@Overridepublic User login(User user) {//判断登录用户,基本思路,登录成功返回一个登录成功的User对象,登录失败返回一个null//1.根据用户名查询有没有的对应的用户记录User u=userDao.getByUsername(user.getUsername());if(u==null) return null;//2.进一步判断密码是否对应一致if(!u.getPassword().equals(user.getPassword()))return null;return u;}
}
UserController.java
i注:两个/login.html视图,是不一样的,一个是POst请求,一个是Get请求(网页默认的进入请求)
@Controller
public class UserController {@Autowiredprivate UserService userService;//进入登录页面@GetMapping("/login.html")public String loginPage(){return "login";}//主页面进入方法@GetMapping("/main.html")public String main(){return "main";}//登录逻辑判断@PostMapping("/login.html")public String login(User user, HttpSession session, Model model){//接收我们的页面的用户名和密码的控制层//调用服务层的login方法,判断是否登录成功//成功,就将返回的user对象保存到session的域空间里//不成功,要给登录页面返回一个错误提示User u= userService.login(user);if(u!=null){session.setAttribute("loginUser",u);//跳转。。。return "redirect:/main.html";}else{model.addAttribute("loginErr","用户名或密码有误!");}return "login";}
}
login.html,main.html
-------------------------------------------------------------------------------login.html---------------------------------------------------
<body>
<br><br>
<div style="color:red;" th:text="${loginErr}" th:if="${not #strings.isEmpty(loginErr)}"></div>
<form th:action="@{/login.html}" method="post">用户名: <input type="text" name="username" placeholder=" 请输入用户名 "/><br/><br/>密 码: <input type="password" name="password" placeholder=" 请输入密码 "/><br/><br/><input style="margin-left:60px;" type="submit" value=" 登录 "/>
</form>
</body>------------------------------------------------------------------------------------main.html----------------------------------------------
<body>你进入了主面页!说明登录成功了。
</body>
- 测试
《1》。先进入登录页,http://localhost:8080/login.html
《2》。输入用户名,密码,若成功进入 - 用SpringBoot做一个web小案例配置拦截器判断登录状态
功能:如进入了主页,不能再返回到登录页面了。也不能没有登录就进入主页了。
首先:新建一个springmvc的拦截器:web/LoginInterptor.java,
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session=request.getSession();User user = (User) session.getAttribute("loginUser"); //UserController.java中登录成功后存入session的if(user!=null){return true; //已登入成功,放行}else{//访问者没有登录,就不能访问主页request.setAttribute("loginErr","你还没有登录,请登录后再访问!"); //页面中类EL表达式@{loginErr}读取。request.getRequestDispatcher("/login.html").forward(request,response);return false;}}
}
其次:把拦截器注册进SpringBoot里:config/WebConfig.java思路:首先拦截所有内容,再排除 login.html,index.html
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/login.html","/","/index.html");}
}
改一下UserController.java中进入登入页方法。思路:有user进入主页,进入主页后,再输登录页时,自动回到主页上,不显示登录页
//进入登录页面@GetMapping("/login.html")public String loginPage(HttpSession session){boolean flag = session.getAttribute("loginUser")==null?true:false;if(flag) {return "login";}else{return "redirect:/main.html";}}
- 登出功能实现
main.html中,点击‘登出’,马上响应到控制层的类中的logout.html映射方法。下面是一个通用的主页模板
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title> 案例主页面 </title><style>.top{width: 100%;height: 100px;border: 1px #cccccc solid;line-height: 100px;text-align: center;}.middle{width: 100%;height: 450px;}.middle .sidlebar{width: 120px;height: 450px;float: left;border: 1px #cccccc solid;}.middle .main{width: 100%;height: 450px;border: 1px #cccccc solid;}.footer{width: 100%;height: 80px;border: 1px #cccccc solid;line-height: 80px;text-align: center;}</style>
</head>
<body>
<div class="top">spring boot 开发 web 小案例的头部
</div>
<div class="middle"><div class="sidlebar"><br/><a href="#" th:href="@{/main.html}">main 主页面 </a><br/><br/><a href="#" th:href="@{/userlist.html}"> 用户列表 </a><br/><br/><a th:href="@{/logout.html}">登出</a></div><div class="main">main 主页面</div>
</div>
<div class="footer">spring boot 开发 web 小案例的脚部
</div>
</body>
</html>
//登出@GetMapping("/logout.html")public String logout(HttpSession session){session.invalidate();return "redirect:/login.html";}
公共代码抽离和复用与切换项显示用户信息
注意:后台的其他页面几乎和main页面一样 ,只是< < div class= "main"> >这个主体区域显示内容不一样,这种情况下,thymeleaf模板是给我们提供了公共代码抽离出来,大家共用的功能!,如头部,底部
-
thymeleaf提供的抽离和共用模板代码
①抽离代码的写法:commons.html
image.png
②调用公共代码的写法有三种
image.png
<div th:replace="~{commons::top}"></div>
这个写法,用公共代码片段替换掉本div的标签
<div th:include="~{commons::top}"></div>
这个写法,就是把公共代码片段标签里的内容,复制过来放到本div标签里
举例
commons.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>公共代码</title>
</head>
<body>
<div class="top" th:fragment="top">spring boot 开发 web 小案例的头部
</div>
<div class="sidlebar" th:fragment="sidlebar"><br/><a href="#" th:href="@{/main.html}">main 主页面 </a><br/><br/><a href="#" th:href="@{/userlist.html}"> 用户列表 </a><br/><br/><a th:href="@{/logout.html}">登出</a>
</div>
<div class="footer" th:fragment="footer">spring boot 开发 web 小案例的脚部
</div>
</body>
</html>
main.html,userlist.html等页面调用
<div th:replace="./commons::top"></div>
<div class="middle"><div th:replace="commons::sidlebar"></div><div class="main">main 主页面/用户列表等页面</div>
<div th:replace="./commons::footer"></div>
- 切换用户列表并显示用户信息
1、userlist.html页面用UserController.java的映射方法显示所有用户信息(Model对象注入--映射对象到视图中):
@GetMapping("/userlist.html")public String userList(Model model){List<User> users = userService.getAllUser();model.addAttribute("users",users);return "userlist";}
<div class="main">搜索:<input type="text" name="searchByUsername"/><button>搜索</button><br><table style="width: 600px;" border="1" cellspacing="0" cellpadding="0"><tr><td> 用户 id</td><td> 用户名 </td><td> 用户密码 </td><td> 用户注册时间 </td><td> 用户住址 </td><td> 操作 </td></tr><tr th:each="user:${users}"><td>[[${user.id}]]</td><td>[[${user.username}]]</td><td>[[${user.password}]]</td><td>[[${#dates.format(user.regDate,'yyyy-MM-dd HH:mm:ss')}]]</td><td>[[${user.address.addressInfo}]]</td><td><a th:href="@{/deleteuser.html(id=${user.id})}"> 删除 </a><a th:href="@{/updateuser.html(id=${user.id})}"> 修改 </a></td></tr></table></div>
----与主页一样的元素框架。
2、在侧边栏导航切换页面同时切换高亮
----当点击左侧某个项时,红色高亮显示。

***首先:在各个要切换的页面中写上一个样式,commons.html不用写样式:
<sytle>
.active{color:red;text-decoration: none;}</style>
其次:在要被切换的页面里写上如代码(isActive='main.html'/'userlist.html'.....")
<div th:replace="commons::top" ></div>
<div class="middle"><div th:replace="commons::sidlebar(isActive='main.html')"></div><div class="main">main 主页面</div>
</div>
<div th:replace="commons::footer"></div>
再后:在公共页中写上th:class="${isActive=='main.html'?'active':''}"
<div class="sidlebar" th:fragment="sidlebar"><br/><a href="#" th:class="${isActive=='main.html'?'active':''}" th:href="@{/main.html}">main 主页面 </a><br/><br/><a href="#" th:class="${isActive=='userlist.html'?'active':''}" th:href="@{/userlist.html}"> 用户列表 </a><br/><br/><a th:href="@{/logout.html}">登出</a>
</div>
3,模糊查询
首先:dao,service层各加两个接口,service实现类中实现查询方法
----------------------------------------------------------UserDao.java接口-------------------------------------------------------------
public interface UserDao extends JpaRepository<User,Integer> {//不要写任何方法,增删改查都在JpaRepository中实现了。/*** 默认接口实现中没有提供根据用户名查询用记录的方法,所以自已做,但命名规则一定要遵守其getBy,find,delet,save开头的名规则*/public User getByUsername(String username);/*** dao层里建立模糊查询的接口**/public List<User> getByUsernameLike(String str);
}
---------------------------------------------------------UserService.java接口----------------------------------------------------------
/模糊查询public List<User> getByUsernameLike(String str);
------------------------------------------------------UserServiceImpl.java实现类----------------------------------------------------
@Overridepublic List<User> getByUsernameLike(String str) {return userDao.getByUsernameLike(str);}
其次:控制类中,映射查询结果到视图层中。
//模糊查询@PostMapping("/userSearch.html")public String userSearch(String searchByUsername,Model model){List<User> users = userService.getByUsernameLike("%"+searchByUsername+"%");model.addAttribute("users",users);return "userlist";}
最后:视图层中
<div class="main"><form th:action="@{/userSearch.html}" method="post">搜索:<input type="text" name="searchByUsername"/><input type="submit" value="模糊查询"></input></form><br><table style="width: 600px;" border="1" cellspacing="0" cellpadding="0"><tr><td> 用户 id</td>
-----
思路:把对象UserServiceImpl对象注入到控制层中,再控制层映射对象到视中。控制层接收视图表单传送的字符串searchByUsername,再查询,注入进视图显示
添加删除用户事务配置
----用户信息有一个关联对象Address,所以我们要建立相应的dao,service层的类。
1.AddressDao.java
它执行JpaRepository接口,不用像以前那样,做AddressDaoImpl实现类,springboot jpa执久化框架自动实例化,实现了基本的增删改查方法,并结合模型类的@Entity,@Table(name="t_addresss")注解去自动创建相应数据源(mysql)的表,并放Spring IOC(控制反转容器中),用时直接@Autowired private AddressDao addressDao即可
import org.springframework.data.jpa.repository.JpaRepository;public interface AddressDao extends JpaRepository<Address,Integer> {
}
2.AddressService.java,AddressServiceImpl.java
该实现类中没有相应的jpa接口实现,所以用到@Service("addressService")注解,去实例代理对象addressService,放到IOC中。
public interface AddressService {//增删改查public void add(Address address);public void delete(int id);public void update(Address address);public Address get(int id);public List<Address> getAllAddress();}
-----------------------------------------------------------------------------AddressServiceImpl.java---------------------------------
@Service("addressService")
public class AddressServiceImpl implements AddressService{//springboot jpa自动把dao类注入到IOC中,不用写什么注解在头上@Autowiredprivate AddressDao addressDao;@Overridepublic void add(Address address) {addressDao.save(address);}@Overridepublic void delete(int id) {addressDao.deleteById(id);}@Overridepublic void update(Address address) {addressDao.saveAndFlush(address);}@Overridepublic Address get(int id) {return addressDao.findById(id).get();}@Overridepublic List<Address> getAllAddress() {return addressDao.findAll();}
}
3.userlist.html,adduser.html
在userlist.html做了一个‘添加’超链接,链到控制层的映射方法上,该方法映射为@GetMapping("/adduser.html"),显示用
<a th:href="@{/adduser.html}">添加用户</a><br>
adduser.html
表单提交,转到@PostMapping("/adduser.html")方法中,
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>添加用户</title>
</head>
<body>
<div class="main"><br><br><form th:action="@{/adduser.html}" method="post">用户名: <input type="text" name="username" /><br><br>用户密码: <input type="text" name="password" /><br><br>选中用户地址: <select name="address.id"><option th:value="${address.id}"th:each="address:${addresses}">[[${address.addressInfo}]]</option></select><br><br><input type="submit" th:value=" 添加 " /></form>
</div></body>
</html>
4.UserController.java
添加用户(两个方法,一个显示用到get,真正添加用到post)
//添加用户(两个方法,一个显示用到get,真正添加用到post),有一关联对象地址Address,所以也要建立相应的dao,service类@GetMapping("/adduser.html")public String adduser(Model model){//这里需要获取现在的地址信息List<Address> allAddress = addressService.getAllAddress();model.addAttribute("addresses",allAddress);return "adduser";}@PostMapping("/adduser.html")public String adduser(User user){user.setRegDate(new Date());userService.add(user);return "redirect:/userlist.html";}
localhost:8080/login.html---登录成功-----用户列表选项---添加用户

- 删除用户
UserController.java
//删除记录@GetMapping("/deleteuser.html")public String deleteuser(Integer id){userService.delete(id);return "redirect:/userlist.html";}
如果想点删除时有弹出框提示,则可以用script方法来做
首先:userlist.html写上一个del()的script方法。
</style><script>function del(){var msg="您真的确定要删除吗?";if(confirm(msg)==true){return true;}else{return false;}}</script>
然后:userlist.html中的删除链接标签内写上如下代码
<td><a onclick="javascript:return del();" th:href="@{/deleteuser.html(id=${user.id})}"> 删除 </a>
- 修改用户
UserController.java
//修改记录//打开修改页面@GetMapping("/updateuser.html")public String updateUser(Integer id,Model model){User user = userService.get(id);model.addAttribute("user",user);List<Address> allAddress = addressService.getAllAddress();model.addAttribute("addresses",allAddress);return "updateuser";}//真正修改@PostMapping("/updateuser.html")public String updateUser(User user){System.out.println("user:"+user);userService.update(user);return "redirect:/userlist.html";}
updateuser.html
注:有一个隐藏表单,用于传递id号,id号不显示在页面上。
<body>
<div class="main"><br><br><form th:action="@{/updateuser.html}" method="post"><input type="hidden" name="id" th:value="${user.id}">用户名: <input type="text" name="username" th:value="${user.username}"/><br><br>用户密码: <input type="text" name="password" th:value="${user.password}"/><br><br>注册时间: <input type="text" name="regDate" th:value="${user.regDate}"/><br><br>选中用户地址: <select name="address.id"><option th:value="${address.id}" th:selected="${user.address.id == address.id}"th:each="address:${addresses}">[[${address.addressInfo}]]</option></select><br><br><input type="submit" th:value=" 修改 " /></form>
</div>
</body>
User.java
发现错误: Field error in object 'user' on field 'regDate'
前端传来的日期时间是 String 类型的,封装为 user 对象的时候,出问题,解决方案,我们前讲 ssh 项目课程里说过,简单一个注解:
---日期型格式化后是字符串类型, 控制层是要用到日期型,所以要转换之,在日期属性上加如下代码
@Entity
@Table(name="t_users")
public class User {private int id;private String username;private String password;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date regDate;
- 事务配置
在service层的事务处理:
在Spring Boot中,当我们使用了spring-boot-starter-jdbc或spring-boot-starter-data-
jpa依赖的时候,框 架会自动默认分别注入DataSourceTransactionManager或
JpaTransactionManager。所以我们不需要任何额外 配置就可以用@Transactional注解进行事务的使用。
Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问 数据库 的Service方法上添加注解 @Transactional 便可。关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 如果你添加的
是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager实例。我们可以在启动类中添加如下方法,Debug测试,就能知道自动注入的是PlatformTransactionManager 接口的哪个实现类。
@EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的
@SpringBootApplication
public class SpbtappApplication {@Beanpublic Object testBean(PlatformTransactionManagerplatformTransactionManager){System.out.println(">>>>>>>>>>" +platformTransactionManager.getClass().getName());return new Object();}public static void main(String[] args) {SpringApplication.run(SpbtappApplication.class, args);}}
----------------------------------------------------------------------------事务启动成功,控制台可见-------------------------------
>>>>>>>>>>org.springframework.orm.jpa.JpaTransactionManager
这些SpringBoot为我们自动做了,这些对我们并不透明,如果你项目做的比较大,添加的持久化依赖比较多,我们还是会选择人为的指定使用哪个事务管理器。
在Spring容器中,我们手工注解@Bean 将被优先加载,框架不会重新实例化其他的PlatformTransactionManager 实现类。然后在Service中,被 @Transactional 注解的方法,将支持事务。如果注解在类上,则整个类的所有方法都默认支持事务。
@EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的
@SpringBootApplication
public class SpbtappApplication {// 其中 dataSource 框架会自动为我们注入@Beanpublic PlatformTransactionManager txManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Beanpublic Object testBean(PlatformTransactionManagerplatformTransactionManager){System.out.println(">>>>>>>>>>" +platformTransactionManager.getClass().getName());return new Object();}public static void main(String[] args) {SpringApplication.run(SpbtappApplication.class, args);}}
SpringBoot异常处理
- 自定义统一的错误处理页面
总体来讲,springboot里处理异常有五种方式,先看第一种:
1、利用springboot的默认配置,我们自定义统一的错误处理页面:前面说了SpringBoot只是帮助我们做了整合的工作,做配一堆的默认配置工作,异常处理的配置当然会有!
-----SpringBoot里边儿有个BasicErrorController...等一系列对象来处理异常,很人性化,是浏览器访问,出异常它会返回一张html页面显示异常信息,是其他设备访问出现异常,它会直接返回json格式的异常数据。
返回的异常信息可以在DefaultErrorAttributes类里查询:
timestamp:发生异常的时间戳
status:异常状态码
error:错误提示信息
exception:错误对象
message:异常消息
errors:JSR303数据校验的异常信息
----当系统发生异常时,不希望访问SpringBoot默认的页面,要访问自己的错误页面怎么办?
SpringBoot内部有关异常方法的设定:
发生异常后
①有模板引擎目录下有错误页面没的? 有,它就会默认去访问,这里的规则是 /模板引擎目录/error/错误代码命名的页面,比如(/templates/error/404.html), 另外SpingBoot把错误分成了两类,客服端异常4xx,服务器端异常5xx,所以我们可也有( ( /templates/error/4xx.html和/templates/error/5xx.html )两个页面!
②/模板引擎目录/没有错误页面模板 ,SpringBoot回去静态资源目录static/error/下面找 错误代码命名的 页面
③/模板引擎目录/没有错误页面,静态资料目录下页面没有的, 显示SpringBoot自己默认的页面知道内部设计后,那就好办了根据规则自己做错误页面就是了! 看例子:
image.png
举例测试:localhost:8080/testerr回车会出现 5xx.html提示信息
首先:在resources/templates/err目录下创建5xx.html页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" xmlns:th="http://www.thymeleaf.org"><title>Title</title>
</head>
<body>
自定义的5xx错误页面:错误代码:[[${status}]] ---- [[${exception}]] [[${message}]]
</body>
</html>
其次:控制层中建一个打开页面,当然了设置一个处理不了的问题如:除0.
//测试5xx错误@GetMapping("/testerr")public String testError(){int i=10;int j=0;double d= i/j; //0不能被整除,会报异常信息return "/userlist.html";}
最后:localhost:8080/login.html------localhost:8080/testerr回车
- 异常处理之注解@ExceptionHander和@ControllerAdvice
----springboot里处理异常有五种方式,看第2、3种:
<1>.注解@ExceptionHander
该处理注解,只处理它所在的控制类中的异常,例:UserController.java,myerror.html可以定义在项目的任何地方,无须指定什么诸如templeats目录中。
//测试5xx错误@GetMapping("/testerr")public String testError(){int i=10;int j=0;double d= i/j; //0不能被整除,会报异常信息return "/userlist.html";}
//异常处理注解方法,下面方法专响应除0的异常@ExceptionHandler(value = {java.lang.ArithmeticException.class,})public ModelAndView doError(Exception ex){ModelAndView md = new ModelAndView(); //md该视图可以存在任何地方,不像html那样要指定地方md.addObject("err",ex);md.setViewName("myerror");return md;}
myerror.html显示异常信息, localhost:8080/login.html登录后,再进入 localhost:8080/testerr回车
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
[[${err}]]
</body>
</html>
------------------------------------------------------------除0异常-------------------------------------------------------------------------
java.lang.ArithmeticException: / by zero
<2>.注解@ControllerAdvice
----该注解可以处理所有控制类中所发生的异常错误,我们可以把该注解的方法放在一个控制类中。这样就比<1>灵活多了。
DoAllErrorController.java
@ControllerAdvice
public class DoAllErrorController {@ExceptionHandler(value = {java.lang.ArithmeticException.class})public ModelAndView testExceptionHander(Exception e){ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("err",e);modelAndView.setViewName("myerror");return modelAndView;}
}
- 异常处理之SimpleMappingExceptionResolver
在springmvc的xml配置文件中的配置:
image.png
但是springboot没的xml配置文件的,但有对应的配置类,我们可以建一个置类(config层中建)
MyEerrorConfig.java
@Configuration
public class MyEerrorConfig {@Beanpublic SimpleMappingExceptionResolver simpleMappingExceptionResolver(){SimpleMappingExceptionResolver ser = new SimpleMappingExceptionResolver();Properties mapper = new Properties();mapper.put("java.lang.ArithmeticException","myerror"); //把异常注入到myerror视图中ser.setExceptionMappings(mapper);ser.setExceptionAttribute("err");return ser;}
}
myerror.html
<body>
[[${exception}]] 或者 [[${err}]]
</body>
- 异常处理之接口HandlerExceptionResolver
也是建一个配置类
MyExceptionConfig.java
@Configuration
public class MyExceptionConfig implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {ModelAndView mv = new ModelAndView();if(ex instanceof ArithmeticException){ //数学算术异常mv.setViewName("myerror");}if(ex instanceof NullPointerException){mv.setViewName("myerror");}mv.addObject("exception",ex);return mv;}
}
myerror.html
<body>
[[${exception}]]
</body>
SpringBoot中使用表单数据有效性检验
-----在SpringBoot里使用服务器端的数据校验和单独使用SpringMVC中的数据校验采用的是一样的技术JSR303这个规范的实现产品Hibernate-Validate,回顾一下在springMVC里讲过的数据校验内容的基础上来看SpringBoot的具体操作:
一、JSR-303简介
---JSR-303只是一个规范,而Spring也没有对这一规范进行实现,那么当我们在SpringMVC中使用JSR-303的时候就需要我们提供一个对JSR-303规范的实现,Hibernate Validator就是实现了这一规范的具体框架。
JSR-303的校验是基于注解的,它内部已经定义好了一系列的限制注解,我们只需要把这些
注解标记在需要验证的 实体类的属性上或是其对应的get方法上。
二、JSR 303 基本的校验规则
空检查@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=) Validates that the annotated string is between min and max included.
日期检查@Past 验证 Date 和 Calendar 对象是否在当前时间之前,验证成立的话被注释的元素一定是一个过去的日期@Future 验证 Date 和 Calendar 对象是否在当前时间之后 ,验证成立的话被注释的元素一定是一个将来的日期@Pattern 验证 String 对象是否符合正则表达式的规则,被注释的元素符合制定的正则表达式,regexp:正则表达式 flags: 指定 Pattern.Flag 的数组,表示正则表达式的相关选项。
数值检查建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为”“,Integer为null@Min 验证 Number 和 String 对象是否大等于指定的值@Max 验证 Number 和 String 对象是否小等于指定的值@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度@Digits 验证 Number 和 String 的构成是否合法@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。@Range(min=, max=) 被指定的元素必须在合适的范围内@Range(min=10000,max=50000,message=”range.bean.wage”)@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)@CreditCardNumber信用卡验证@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。@ScriptAssert(lang= ,script=, alias=)@URL(protocol=,host=, port=,regexp=, flags=)
二、具体操作步骤
(1)SpringBoot已经将相关的jar包整合进来了,不用我们自己导入jar包了,不知什么原因,我的springboot 2.7.6没有导入进来,所以我要手工导入
<dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.11.Final</version></dependency>
(2)在JavaBean的属性上加验证注解。
@Entity
@Table(name = "t_users")
public class User {private int id;@NotEmptyprivate String username;@NotEmptyprivate String pasword;
(3)在Controller的处理方法上的参数前,加@Valid注解,增加出错后,错误信息放置的对象参数Errors/BindingResult errorrs。

(5)前面把错误信息带回了添加页面,显示出来,前面讲异常处理的时候,已经说了回显
的异常信息会放到errors变量里注入视图
<form th:action="@{/adduser.html}" method="post">
用户名: <input type="text" name="username" /><span style="color: red;" th:errors="${user.username}">ss</span><br><br>
用户密码: <input type="text" name="pasword" /><span style="color: red;" th:errors="${user.password}"></span><br><br>
选中用户地址: <select name="address.id">
<option th:value="${address.id}" th:each="address:${addresses}">[[${address.addressInfo}]]</option></select><br><br>
<input type="submit" th:value=" 添加 " />
</form>

5)有些系统默认的错误信息不好用,我们一般都自己写错误提示信息
①用注解,在注解中带message参数

有关Servlet容器的配置
SpringBoot(2.1.0时)默认使用嵌入式Servlet容器,最新版本的SpringBoot默认是选的是Tomcat9.0.12,(SpringBoot默认支持三种Servlet容器:tomcat,jetty,undertow)
1、既然是嵌入的,就没的server.xml配置文件给我们做定制化,所以嵌入的Servlet容器,SpringBoot提供了对应方式来配置:
在SpringBoot的全局配置文件中配置(所有能配置的项目都可以在ServerProperties类里查询-----打一个类文件按ctrl+shift+n---输入ServerProperties)
①用server.xxxx的属性来配置有关Servlet容器的通用配置
②用server.tomcat.xxxx来专门配置tomcat有关的配置
③其他两个Servlet容器以此类推
2、怎么切换SpringBoot里边儿的三个Servlet容器:
一,tomcat:开源,也是比较好用的一个Servlet容器,很多人用,不管是用来做测试还是生产环境,SpringBoot默认
二,jetty:小Serlvet容器,适合做长链接,也就是链接上就不断,长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,很多人开发测试的时候很喜欢用,因为它启动比tomcat要快很多
三,undertow:是一个非阻塞的Servlet容器,但是它不支持JSP
①排除掉默认的tomcat依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><artifactId>spring-boot-starter-tomcat</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions>
</dependency>
②引入jetty或undertow的启动模块
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty/undertow</artifactId>
</dependency>
3、在SpringBoot的基础上使用外部的tomcat
①创意一个war工程,就不能用jar了; 注意:一定要选war,否则不会成功!再
‘文件’---Project Settings

注:上图有一个错误处,webapp\WEB-INF中是有''隔开的。
②生成webapp目录和web.xml配置文件
③添加外部tomcat服务器
注:添加外部tomcat之前,先配好tomcat服务器位置。





配置Deployment里artifacts选项:
④配置全局变量
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
最后可以测试一下了
testController.java
@Controller
public class testController {@GetMapping({"/","/index.html"})public String index(){return "index";}
}
WEB-INF/jsp/index.jsp
<%@ page import="java.util.Date" %><%--Created by IntelliJ IDEA.User: AdministratorDate: 2023/2/22/022Time: 10:43To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
jsp页面。 <%=new Date()%>
</body>
</html>
localhost:8080/ 回车 或 localhost:8080/index.html 回车
jsp页面。 Wed Feb 22 11:28:34 CST 2023
SpringBoot的国际化
国际化(internationalization)是设计容易适应不同区域要求的产品的一种方式。
它要求从产品中抽离所有地域语言元素。换言之,应用程序的功能和代码设计考虑了在不同地区运行的需要。开发这样的程序的过程,就称为国际化。
那么当我们使用Spring Boot如何进行国际化呢?我们用一个例子来演示操作的步骤
1、我们写一个thymeleaf模板:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>hello spring boot</title>
</head>
<body>
<p> 欢迎你登录到 ybzy.ke.qq.com 我的课程分享网站 </p>
</body>
</html>
2、写出对应的controller类:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "/hello";
}
}
我们观察hello.html里面的信息直接就是中文显示,但是我们现在的需求是当访问语言是zh的时候显示为中文,当语言为en的时候显示为英文,那么怎么操作呢?
******首先我们先定义国际化资源文件,spring boot默认就支持国际化的,而且不需要你过多的做什么配置,只需要在resources/这个根路径下定义国际化配置文件,文件 名称必须以messages开头 ,注意:配置文件的名字和存放的位置SpringBoot的内部代码里默认的就是messages和classpath,当然我们可以在配置文件中配置spring.messages.basename的值来改变这两个东西。
我们先用默认的配置定义如下几个文件:
1.messages.properties (默认,当找不到语言的配置的时候,使用该文件进行展示)。
2.messages_zh_CN.properties(中文)
3.messages_en_US.properties(英文)
分别写上内容:
1.welcome = 欢迎你登录到 ybzy.ke.qq.com 我的课程分析网站(default)
2.welcome = \u6b22\u8fce\u4f60\u767b\u5f55\u5230 \u963f\u91cc\u5df4\u5df4\u7f51\u7ad9\uff08\u4e2d\u6587\uff09
3.welcome = welcome to login to ybzy.ke.qq.com website(English)
配置信息完毕后,那么在前端展示怎么修改呢,修改hello.html文件,使用#{key}的方式进行使用
messages中的字段信息:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>hello spring boot</title>
</head>
<body>
<p><label th:text= "#{welcome}"></label></p>
</body>
</html>
修改火狐浏览器的国际化信息,看测试效果:
about:config
在搜索框输入accept,然后找到intl.accept_languages修改对应的值,我这里原本是:
zh-CN, zh, zh-TW, zh-HK, en-US, en
为了看到效果,修改为:
en-us, en
通过三个问题,简单说下原理:
第一个问题,为什么命名必须是messages开头,需要看一个源码文件:MessageSourceAutoConfiguration
如果我们没有在application.properties中配置spring.messages.basename属性,那么使用默认的messages,好了这个问题就这么简单解决了。
第二个问题:为什么我看到的是中文(或者英文)呢?
为了让web应用程序支持国际化,必须识别每个用户的首选区域,并根据这个区域显示内容。在Spring MVC应用程序中,用户的区域是通过区域解析器来识别的,它必须是实现LocaleResolver接口。Spring MVC提供了几个LocaleResolver实现,让你可以按照不同的条件来解析区域。除此之外,你还可以实现这个接口创建自己的区域解析器。如果没有做特殊的处理的话,Spring 采用的默认区域解析器是AcceptHeaderLocaleResolver。它通过检验HTTP请求的头部信息accept-language来解析区域。这个头部是由用户的web浏览器底层根据底层操作系统的区域设置进行设定的。请注意,这个区域解析器无法改变用户的区域,因为它无法修改用户操作系统的区域设置。
第三个问题:怎么根据我们的需要切换语言环境呢?
我们可以自定义我们的区域解析器LocaleResolver,然后将它注册到spring的ioc容器中。
自定义启动器
---------在springboot的学习过程中,我们发现它的最核心的东西,就是帮助我们做了很多配置,这点就是通过starter这个启动器来实现的,这个starter不仅能帮助我们把某一个应用场景需要的jar包一起导入进来,关键还是针对这些jar的主要配置,都做好了,我们只需要简单地配置或修改一点点少量的属性,就可以完成配置工作了!
--------spring boot虽然给我们提供了很多这样的启动器starter,但是在实际的开发中,这些官方的启动器显然是不够用的,所以,需要我们能够自定义出我们自己的starter,这里我们用一个简单的案例来演示一下怎么创建自己的starter,我们要实现一个这样的启动器,这个启动器能帮我们配置一个Service,这个Service里有一个方法是hello,调用这个方法,它可以从全局配置文件中读取一个前缀信息和传入的信息组合起来然后返回,再用注解注入到IOC 中,写相应的关联类,再把两个模块install打包到本地库中,再建一个springboot项目,导包之,启动启动类后,就能把HelloService注入到IOC中,后@Autowired自动生成对象应用之接下来我们看具体的操作步骤:
1、第一步骤:我们来做要给空的启动器的Module
通过空项目来做:

建好空项目后,再添加模块,第一个模块选maven功程



第二步骤:创建自动配置的Module,第一个模块选spring initializer功程



第三步骤:清理到两个module中的多余的东西,加上依赖,启动器依赖自动配置
自动启动器模块的中的如下图三个文件都可删除,pom.xml中的插件和test启动依整都可删除。

第一个模块中pom.xml中加上自动配置启动模块中的依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>xiong.spring.boot.starter</groupId><artifactId>xiong-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>xiong.spring.starterdemo</groupId><artifactId>xiong-spring-boot-starter-autoconfigurer</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies></project>
第四步骤:编写自动配置模块
首选 :写一个HelloService.java

public class HelloService {private HelloProperties helloProperties;public String hello(String str){//return "返回一个前缀,使用starter的时候,项目的全局配置文件中配置的"+"--"+str;return helloProperties.getPrefix()+"--"+str;}public HelloProperties getHelloProperties() {return helloProperties;}public void setHelloProperties(HelloProperties helloProperties) {this.helloProperties = helloProperties;}
}
其次:编写一个HelloProperties.java
@ConfigurationProperties(prefix="hello")
@Component
public class HelloProperties {private String prefix;public String getPrefix() {return prefix;}public void setPrefix(String prefix) {this.prefix = prefix;}
}
然后:编写一个HelloServiceAutoconfiguration.java
该类,为HelloService与HelloProperties建立串联关系
/*** 该类,为HelloService与HelloProperties建立串联关系*/@Configuration@ConditionalOnWebApplication //只有在web应用中引入自定义的启动器的时候,这个启动配置类才会生效(引用者是另一个项目)@EnableConfigurationProperties(HelloProperties.class) //这个注解可以把此类与HelloProperties类建立关联,并把Properties类注入IOC中
public class HelloServiceAutoconfiguration {@Autowiredprivate HelloProperties helloProperties;@Bean //此处是,把HelloService对象注入到spring IOC容器中public HelloService helloService(){HelloService helloService = new HelloService();helloService.setHelloProperties(helloProperties); //非常关键,把HelloService与HelloProperties串联了return helloService;}
}
再然后:建如下图所示的文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.ybzy.starterdemo.HelloServiceAutoconfiguration
文件内容是从以下两图示范的地方复制过来的。


最后:打包到本地仓库或私服中,一般最先会到本地中,如果配了私服,也会同时打包到私服中。
打包顺序:先自动启动配置module,再启动配置module,从最右边---maven项---Lifecyle---install
第五步骤:测试
首先:建一个springboot项目,一定要有web启动器。
其次:pom.xml中,导入启动配置module包
<dependencies><dependency><groupId>ybzy.spring.boot.starter</groupId><artifactId>ybzy-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
再次:全局配置文件中application.properties
hello.prefix=helloxiongshaowen
最后:建一个控制类IndexController.java,再localhost:8080/回车
HelloService.java对象已被导入的自定义的启动器配注入到了IOC中
@Controller
public class IndexController {@Autowiredprivate HelloService helloService;@ResponseBody //因为没有建视图橨板页,所以它可以把返回的内容以json格式显示到index中@GetMapping({"/","/index"})public String index(){return helloService.hello("自已定义的启动器starter测试");}
}
本示例的两候个项目,如下图所示,在网盘中可以看到,其中两个是模块
本示例的本个项目,如下图所示,在网盘中可以看到

springboot中遇到的问题
- java: 程序包javax.validation不存在
之前,有位同学反馈说,在运行newbee-mall-api项目时遇到了下面这个问题,无法正常编译项目,错误截图如下:
看了一下应该是@NotEmpty、@Valid这几个验证注解引起的,因为这几个注解都是定义在javax.validation包中的。再了解下去发现这位同学升级了Spring Boot的版本号。
Spring Boot 2.2.* 版本里是有这些代码的,在这位同学升级的Spring Boot 2.3版本中是没有对应代码的,需要自己再把validation相关的包引入进来,代码如下:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
- STS pom.xml Unknown error
这个问题的原因是2.2.0.RELEASE中==maven插件升级到了3.1.1,有些IDE插件不兼容。解决这个问题只需要在pom.xml 文件的properties中加入maven jar插件的版本号。
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><maven-jar-plugin.version>3.1.1</maven-jar-plugin.version></properties>
- STS中出现如下图错误:
image.png
由于最近在弄elastic-job ,在下载源码后会报一些错误,变量log 找不到,没有getter/setter 方法之类的。
之前没有接触过lombok ,这次看了些帖子,也只是暂时解决了这样的问题。
1.前往官网下载:https://projectlombok.org/download lombok.jar
-----本人已经下载放在网盘STS_svn目录中。
2.将lombok.jar放在eclipse的安装目录下。
3.在eclipse的安装目录下。shift+右键 ->在此处打开shell窗口,执行命令
5.点击Specify location.. 选择eclipse 的安装目录。然后点击install/update
6.安装成功,退出,在eclipse.ini(sts.ini)中会看到新增lombok.jar一行
7.有时后可能这样自动安装的路径导致eclipse无法启动,可以将eclipse.ini文件自动追加的一行修改为下所示
-Xbootclasspath/a:lombok.jar
-javaagent:lombok.jar
8.启动eclipse ,clean。错误消失。
- springboot路径问题
一。获取web(servlet)获取文件的真实(服务器)路径 方法:,获取target类路径的目录
public String upload(MultipartFile uploadFile, HttpServletRequest req){String realPath=req.getSession().getServletContext().getRealPath("/uploadFile/");//getRealPath: C:\Users\Administrator\AppData\Local\Temp\tomcat-docbase.8080.596262946748719422/uploadFile///String realPath = ClassUtils.getDefaultClassLoader().getResource("").getPath();//getRealPath: /C:/Users/Administrator/Desktop/idea/fileupload/target/classes/System.out.println("getRealPath: "+realPath);
二。SpringBoot 读取classPath 路径下文件几种方式及
spring boot默认加载文件的路径:
/META-INF/resources/
/resources/
/static/
/public/
Classpath含义
存放各种资源配置文件 eg.init.properties log4j.properties struts.xml
存放模板文件 eg.actionerror.ftl
存放class文件对应的是项目开发时的src目录编译文件
一般java项目中 classpath存在与 WEB-INFO/目录。
当我们需要某个class时,系统会自动在CLASSPATH里面搜索,如果是jar,就自动从jar里面查找,如果是普通的目录,则在目录下面按照package进行查找。
但与PATH不同的是,默认的CLASSPATH是不包含当前目录的,这也是CLASSPATH里面要包含一个点的道理了。
Tomcat下的Web应用有两个预置的classpath : WEB-INF/classes 和WEB-INF/lib启动项目,项目就会加载这两个目录里的数据。这是war包的规范.要改变预置的classpath比较麻烦,在Tomcat的配置文件里没有发现类似的配置,要实现自己的classloader才能达到目的。
一个在tomcat中运行的web应用.它的classpath都包括如下目录:
我知道的有:
%tomcat%/lib
web-inf/lib
web-inf/classes//方式1: 流的方式ClassPathResource classPathResource = new ClassPathResource(pathfileName);InputStream inputStream = classPathResource.getInputStream();//方式2: 流的方式String s = this.getClass().getResource("/") + pathfileName;InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(pathfileName);//方式3: 流的方式InputStream resourceAsStream1 = Thread.currentThread().getContextClassLoader().getResourceAsStream(pathfileName);//方式4: 文件的方式File file = org.springframework.util.ResourceUtils.getFile("classpath:"+pathfileName);

喜欢的朋友记得点赞、收藏、关注哦!!!
相关文章:
SpringBoot基础二
扩展SpringBoot 扩展SpringBoot中的SpringMVC的默认配置 SpringBoot默认已经给我们做了很多SpringMVC的配置,哪些配置? 1、视图解析器ViewResolver 2、静态资料的目录 3、默认首页index.html 4、图标名字和图标所在目录,favicon.ico 5、类型转…...
力扣第129题:求根到叶子节点数字之和 - C语言解法
力扣第129题:求根到叶子节点数字之和 - C语言解法 题目描述 给定一个二叉树,求根到叶子节点的数字之和。 每条从根到叶子的路径都代表一个数字。例如,根到叶子路径 1->2->3 代表数字 123。返回所有路径数字之和。 示例 1࿱…...
图像处理-Ch7-小波函数
个人博客!无广告观看,因为这节内容太多了,有点放不下,分了三节 文章目录 多分辨率展开(Multi-resolution Expansions)序列展开(Series Expansions)尺度函数(Scaling Function)例:哈尔尺度函数(Haar scaling func)多分…...
Unity中实现转盘抽奖效果(一)
实现思路: 旋转转盘的z轴,开始以角加速度加速到角速度最大值,结束的时候,以角加速度减速使角速度减少到0,然后转盘z轴旋转的角度就是加上每秒以角速度数值大小,为了使角度不能一直增大,对360度…...
小程序基础 —— 07 创建小程序项目
创建小程序项目 打开微信开发者工具,左侧选择小程序,点击 号即可新建项目: 在弹出的新页面,填写项目信息(后端服务选择不使用云服务,开发模式为小程序,模板选择为不使用模板)&…...
Apache Commons Pool :介绍与使用
Apache Commons Pool :介绍与使用 什么是 commons-pool2? commons-pool2 是 Apache Commons 提供的一个开源对象池实现框架。它旨在为应用程序提供通用的对象池支持,方便开发者管理资源(如数据库连接、网络连接等)复…...
(二)编译原生SDK以及配置交叉编译链
文章目录 编译原生SDKLinuxSDK的安装第一步解压LinuxSDK第二步安装依赖软件第三步解压Buildroot的dl文件 Linux系统镜像编译、生成第一步 配置编译环境第二步 编译 LinuxSDK编译上面配置好的 环境配置编译 LinuxSDK配置内核选项配置 Buildroot编译 Qt 库 编译生成 Linux 系统镜…...
YK人工智能(三)——万字长文学会torch深度学习
2.1 张量 本节主要内容: 张量的简介PyTorch如何创建张量PyTorch中张量的操作PyTorch中张量的广播机制 2.1.1 简介 几何代数中定义的张量是基于向量和矩阵的推广,比如我们可以将标量视为零阶张量,矢量可以视为一阶张量,矩阵就是…...
【游戏设计原理】41 - 游戏的核心
1. 如何理解? 这条原理主要在讲述“游戏核心”这一概念的重要性及其在游戏开发中的作用。游戏的核心是指决定游戏整体玩法和体验的核心元素,它通常是游戏的主要机制、目标或动作方式。理解这一原理时,我们可以从以下几个层面来考虑ÿ…...
GraalVM:云原生时代的Java虚拟机
1. 概述 GraalVM是由Oracle公司开发的一款高性能、多语言的虚拟机平台。它不仅兼容传统的JVM字节码执行,还引入了即时编译(JIT)技术的革新,以及对多种编程语言的支持。GraalVM旨在通过提供更高效的执行环境来满足云计算环境中日益…...
goView二开低代码平台1.0
官网文档地址:GoView 说明文档 | 低代码数据可视化开发平台 简介:GoView 是一个拖拽式低代码数据可视化开发平台,通过拖拽创建数据大屏,使用Vue3框架,Ts语言和NaiveUI组件库创建的开源项目。安装步骤和地址文档里都有…...
【golang】go errors 处理错误追踪打印堆栈信息
目录 背景使用参考 背景 使用原生go语言编程时,常常需要处理错误,然而golang中没有像java/python等其他语言的try-catch方式一样的方式来处理异常事件,只能通过函数返回值接收并处理错误。 在实践中,由于牛马的不熟练或随意处理错…...
【brew安装失败】DNS 查询 raw.githubusercontent.com 返回的是 0.0.0.0
从你提供的 nslookup 输出看,DNS 查询 raw.githubusercontent.com 返回的是 0.0.0.0,这通常意味着无法解析该域名或该域名被某些 DNS 屏蔽了。这种情况通常有几个可能的原因: 可能的原因和解决方法 本地 DNS 问题: 有可能是你的本…...
【Python系列】Python 连接 PostgreSQL 数据库并查询数据
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
深度学习利用Kaggle和Colab免费GPU资源训练
这两个平台,我先用的Colab,在修改完无数bug,成功训练完一个epoch后,超时了,查阅了官网资料,之后应该还可以用,但这个限制是动态的,你可能第二天就可以用,也没准下个月。遂…...
WebAssembly 学习笔记
WASM 概述 wasm最初是为了在浏览器获得接近原生的性能体验。 支持将其他语言实现的程序编译到wasm字节码,引入到浏览器由JS交互调用。 后又有了脱离JS的wasm运行时,可以直接运行wasm。 从而促成了wasm跨平台分发的能力。 但由于运行时的安全沙箱限制&a…...
二、github基础
Github基础 备用github.com网站一、用户界面-Overview(概览)1用户信息2 导航栏3 热门仓库4 贡献设置5贡献活动6搜索和筛选7自定义收藏8贡献统计9最近活动10其他链接 二、用户界面-Repositories(仓库)1 libusb_stm322 savedata3 Fi…...
「下载」智慧文旅运营综合平台解决方案:整体架构,核心功能设计
智慧文旅运营综合平台,旨在通过集成大数据、云计算、物联网、人工智能等先进技术,为景区、旅游企业及相关管理机构提供一站式的智慧化运营服务。 智慧文旅运营综合平台不仅能够提升游客的游览体验,还能帮助景区管理者实现资源的优化配置和业务…...
《探寻真正开源的大模型:开启AI创新新纪元》
《探寻真正开源的大模型:开启AI创新新纪元》 一、开源大模型崛起:AI 发展的新曙光二、开源大模型的 “庐山真面目”三、明星开源大模型闪耀登场(一)LLaMA 3:实力强劲的开源先锋(二)Phi-3&#x…...
麒麟信安云在长沙某银行的应用入选“云建设与应用领航计划(2024)”,打造湖湘金融云化升级优质范本
12月26日,2024云计算产业和标准应用大会在北京成功召开。大会汇集政产学研用各方专家学者,共同探讨云计算产业发展方向和未来机遇,展示云计算标准化工作重要成果。 会上,云建设与应用领航计划(2024)建云用…...
C#如何操作数据库
C#如何操作数据库 前言1、查询操作2、增删改操作3、需要返回id主键的sql语句执行 前言 本文主要交代如何通过引用 using MySql.Data.MySqlClient;来操作数据库 需要导入.dll文件 例如:在本地Mysql下载目录下->Connecter NET 8.0->Assemblies->net5.0->…...
c++领域展开第八幕——类和对象(下篇 初始化列表、类型转换、static成员)超详细!!!!
文章目录 前言一、初始化列表二、类型转换三、static成员总结 前言 上篇博客我们实现了一个简单的日期类,基本的类和对象是清楚了 今天我们再来学习后面的一些类和对象的语法,慢慢的完善所学的东西 fellow me 一、初始化列表 • 之前我们实现构造函数时…...
termux-boot安卓开机自动启动应用
termux安装 github 蓝奏云 v119.1 termux-boot安装 github 蓝奏云 v0.8.1 安装 给权限运行加锁后台 am启动应用命令 am start -n 包名/启动项获取包名和启动入口(图中app为爱玩机工具箱) 例 简黑时钟蓝奏云 包名com.hm.jhclock 桌面启动项com.hm.jh…...
Echart实现3D饼图示例
在可视化项目中,很多地方会遇见图表;echart是最常见的;这个示例就是用Echart, echart-gl实现3D饼图效果,复制即可用 //需要安装,再引用依赖import * as echarts from "echarts"; import echar…...
【JAVA】神经网络的基本结构和前向传播算法
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默, 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……) 2、学会Oracle数据库入门到入土用法(创作中……) 3、手把…...
设计模式-抽象工厂模式
在设计模式中,抽象工厂模式(Abstract Factory Pattern)是一个非常常见且重要的模式,它属于创建型模式,用于提供创建一组相关或相互依赖对象的接口,而无需指定具体类。它的核心思想是将“创建对象”这一功能…...
webpack
前言 在现代前端开发的浪潮中,Webpack 已经成为一个不可或缺的构建工具。它不仅能够帮助我们打包 JavaScript 代码,还能够处理各种资源(如 CSS、图片、字体等),并提供一系列优化手段,极大地提升开发效率和…...
BLIP论文笔记
论文地址 BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation 论文思想 其实Clip就相当于只用了ITC...
Java List 集合详解:基础用法、常见实现类与高频面试题解析
正文 在 Java 集合框架中,List 是一个非常重要的接口,广泛用于存储有序的元素集合。本文将带你深入了解 List 接口的基本用法、常见实现类及其扩展,同时通过实际代码示例帮助你快速掌握这些知识。 👉点击获取2024Java学习资料 1…...
HTML5 SSE
HTML5 SSE(Server-Sent Events,服务器发送事件)是一种允许服务器实时向浏览器推送数据的技术。它是HTML5规范的一部分,主要通过HTTP协议实现。SSE的主要特点包括: 单向通信:与WebSocket不同,SSE…...
SpringBoot篇(监控)
目录 学习前言 一、什么是监控? 二、监控的意义 1. 简介 2. 总结 3. 思考 三、可视化监控平台 1. 简介 2. 实操 2.1. 服务端开发 2.2. 客户端开发 配置多个客户端 2.3. 总结 2.4. 思考 四、监控原理 1. 简介 2. 总结 五、自定义监控指标 1. 简介…...
python23-常用的第三方库01:request模块-爬虫
requests 模块是 Python 中的一个第三方库,用于发送 HTTP 请求。 它提供了一个简单且直观的 API,使得发送网络请求和解析响应变得非常容易。requests 模块支持各种 HTTP 方法,如 GET、POST、PUT、DELETE 等,并且具有处理 cookies…...
【pytorch】现代卷积神经网络
文章目录 1 AlexNet2 VGG3 NiN4 GoogLeNet5 批量规范化batch normalization6 ResNet6.1 残差块6.2 resnet 7 DenseNet7.1 稠密块体7.2 过渡层7.3 DenseNet模型 1 AlexNet AlexNet由八层组成:五个卷积层、两个全连接隐藏层和一个全连接输出层。 AlexNet使用ReLU而不…...
Excel 身份证号计算年龄
1. 设置身份证号列格式 复制身份证列值到记事本或其他地方重新设置身份证号列单元格格式为“文本”将复制出去的身份证号重新复制粘贴回来 2. 年龄列单元格中添加公式 DATEDIF(DATE(LEFT(MID(A2, 7, 8), 4), MID(MID(A2, 7, 8), 5, 2), RIGHT(MID(A2, 7, 8), 2)), TODAY(), …...
【ArcGIS Pro】完整的nc文件整理表格模型构建流程及工具练习数据分享
学术科研啥的要用到很多数据,nc文件融合了时间空间数据是科研重要文件。之前分享过怎样将nc文件处理成栅格后整理成表格。小编的读者还是有跑不通整个流程的,再来做一篇总结篇,也分享下练习数据跟工具,如果还是弄不了的࿰…...
WebRTC的线程模型
WebRTC中的线程类: Thread类: (1)Thread类中的数据: class Thread {// 消息队列:MessageList messages_; // 消息队列,所有需要线程处理的消息,都要先入队PriorityQueue delayed_m…...
活动预告 | Microsoft Power Platform 在线技术公开课:实现业务流程自动化
课程介绍 参加“Microsoft Power Platform 在线技术公开课:实现业务流程自动化”活动,了解如何更高效地开展业务。参加我们举办的本次免费培训活动,了解如何借助 Microsoft AI Builder 和 Power Automate 优化工作流。结合使用这些工具可以帮…...
Docker安装(Docker Engine安装)
一、Docker Engine和Desktop区别 Docker Engine 核心组件:Docker Engine是Docker的核心运行时引擎,负责构建、运行和管理容器。它包括守护进程(dockerd)、API和命令行工具客户端(docker)。适用环境&#…...
Spring自动化创建脚本-解放繁琐的初始化配置!!!(自动化SSM整合)
一、实现功能(原创,转载请告知) 1.自动配置pom配置文件 2.自动识别数据库及数据表,创建Entity、Dao、Service、Controller等 3.自动创建database.properties、mybatis-config.xml等数据库文件 4.自动创建spring-dao.xml spring-mvc.xml …...
Llama系列关键知识总结
系列文章目录 第一章:LoRA微调系列笔记 第二章:Llama系列关键知识总结 第三章:LLaVA模型讲解与总结 文章目录 系列文章目录Llama: Open and Efficient Foundation Language Models关键要点LLaMa模型架构:Llama2分组查询注意力 (G…...
分布式系统架构6:链路追踪
这是小卷对分布式系统架构学习的第6篇文章,关于链路追踪,之前写过traceId的相关内容:https://juejin.cn/post/7135611432808218661,不过之前写的太浅了,且不成系统,只是简单的理解,今天来捋一下…...
flink cdc使用flink sql方式运行一直报Make sure a planner module is on the classpath
flink cdc使用flink sql方式运行一直报Make sure a planner module is on the classpath 引入jar包信息: flink-connector-oracle-cdc:3.2.1 flink:1.20.0 flink-table-runtime:1.20.0 flink-streaming-java:1.20.0 flink-clients:1.20.0 Exception in thread &q…...
Vue.js组件开发-怎样将style私有化
Vue.js组件开发中,将style私有可以通过使用<style scoped>来实现的。scoped属性会告诉Vue为这个组件的CSS样式添加一个数据属性,从而确保这些样式只应用于该组件的元素,而不会影响到其他组件或全局样式。 示例: 展示如何使…...
第十届“挑战杯”大学生课外学术科技作品竞赛解析及资料
“挑战杯”被誉为大学生科技创新创业的“奥林匹克”盛会,它汇聚了来自各个学科、各个年级的精英人才。在这里,同学们带着对未知的好奇和对知识的渴望,组成一个个团队,向难题发起挑战。现在,第十届“挑战杯”大学生课外…...
从0入门自主空中机器人-2-1【无人机硬件框架】
关于本课程: 本次课程是一套面向对自主空中机器人感兴趣的学生、爱好者、相关从业人员的免费课程,包含了从硬件组装、机载电脑环境设置、代码部署、实机实验等全套详细流程,带你从0开始,组装属于自己的自主无人机,并让…...
跟着逻辑先生学习FPGA-实战篇第一课 6-1 LED灯闪烁实验
硬件平台:征战Pro开发板 软件平台:Vivado2018.3 仿真软件:Modelsim10.6d 文本编译器:Notepad 征战Pro开发板资料 链接:https://pan.baidu.com/s/1AIcnaGBpNLgFT8GG1yC-cA?pwdx3u8 提取码:x3u8 1 知识背景 LED,又名…...
【文献精读笔记】Explainability for Large Language Models: A Survey (大语言模型的可解释性综述)(四)
****非斜体正文为原文献内容(也包含笔者的补充),灰色块中是对文章细节的进一步详细解释! 四、提示范式(Explanation for Prompting Paradigm) 随着语言模型规模的扩大,基于提示(prom…...
分布式算法(五):初识ZAB协议
文章目录 一、什么是Zookeeper二、ZAB与Zookeeper的关系为什么Zookeeper不直接使用Paxos 三、ZAB简介1.名词解释提案(Proposal)事务(Transaction)原子广播(Atomic Broadcast) 2.集群角色领导者(…...
用Python操作字节流中的Excel工作簿
Python能够轻松地从字节流中加载文件,在不依赖于外部存储的情况下直接对其进行读取、修改等复杂操作,并最终将更改后的文档保存回字节串中。这种能力不仅极大地提高了数据处理的灵活性,还确保了数据的安全性和完整性,尤其是在网络…...
PHP-Casbin v4.0.0 发布,支持 ACL、RBAC、ABAC 等模型的访问控制框架
PHP-Casbin 是一个用 PHP 语言打造的轻量级开源访问控制框架,支持 ACL、RBAC、ABAC 多种模型。它采用了元模型的设计思想,支持多种经典的访问控制方案,如基于角色的访问控制 RBAC、基于属性的访问控制 ABAC 等。 更新内容: http…...