必学框架新版SpringBoot教程(下集)
个人简介
作者是一个来自河源的大三在校生,以下笔记都是作者自学之路的一些浅薄经验,如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门。
@[toc]
SpringBoot+JDBC
1.导入JDBC和mysql的依赖
在Pom.xml导入以下依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
2.在application的配置文件配置数据源(DataSource)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ssmrl?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=18420163207
3.测试数据源是否生效
在SpringBoot单元测试进行
@SpringBootTest
class DemoApplicationTests {
@Autowired //自动注入数据源,因为我们已经配置过了(application.properties),它会在IOC容器去找到数据源
private DataSource dataSource;
@Test
void contextLoads() {
System.out.println(dataSource);
}
}
运行结果如下:
结论:我们从输出结果可以看到,SpringBoot默认的数据源是HikariDataSource,这个数据源是目前最快的数据源,比阿里巴巴的Druid还要快,但是DruidDatasource有监控功能,后面再说
SpringBoot原生JDBC
1.在SpringBoot单元测试类中:
@SpringBootTest
class DemoApplicationTests {
@Autowired
private DataSource dataSource;
@Test
void contextLoads() throws SQLException {
Connection connection = dataSource.getConnection();
String sql="select empid,empName from emp";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getInt(1)+" "+resultSet.getString(2));
}
}
}
输出结果如下:
SpringBoot+JdbcTemplate
JdbcTemplate是Spring对JDBC的封装,目的是让Jdbc更加容易使用
说明我们的JdbcTemplate可以正常使用了
**里面的sql语句可以写预处理,也就是用“ ? ”占位 **
查询单个数据:
查询多个数据:
SpringBoot+Druid
因为我们在DataSourceAutoConfiguration类中看到如下代码:
@Import({Hikari.class, Tomcat.class, Dbcp2.class, OracleUcp.class, Generic.class, DataSourceJmxConfiguration.class})
protected static class PooledDataSourceConfiguration {
protected PooledDataSourceConfiguration() {
}
}
Hikari.class 导入了Hikari的数据源,SpringBoot默认自带了HikariDataSource,如何切换数据源呢?
我们只需要在配置文件加上一句代码:
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
添加Druid数据源的监控功能
public abstract class ResourceServlet extends HttpServlet {
//Druid监控的帐号密码
private static final Log LOG = LogFactory.getLog(ResourceServlet.class);
public static final String SESSION_USER_KEY = "druid-user";
public static final String PARAM_NAME_USERNAME = "loginUsername"; //配置帐号
public static final String PARAM_NAME_PASSWORD = "loginPassword"; //配置密码
因为我们在配置文件指定了spring.datasource.type=com.alibaba.druid.pool.DruidDataSource,会自动使用SpringBoot的默认配置,我们不想这样可以自己写一个Druid配置类,然后在附加上去
@Configuration
public class myDruid {
//指定前缀为:spring.datasource
@ConfigurationProperties(prefix = "spring.datasource")
@Bean //添加到IOC容器中去
public DataSource druidDatasource(){
DruidDataSource druidDataSource=new DruidDataSource();
return druidDataSource;
}
//添加Druid监控,这个ServletRegisterBean相当于web.xml的<servlet></servlet>
@Bean
public ServletRegistrationBean servletRegistrationBean(){
//指定servlet的类
ServletRegistrationBean servletRegistrationBean=new ServletRegistrationBean(new StatViewServlet());
//配置映射路径
servletRegistrationBean.addUrlMappings("/druid/*");
//配置帐号密码
servletRegistrationBean.addInitParameter("loginUsername","admin");
servletRegistrationBean.addInitParameter("loginPassword","123456");
return servletRegistrationBean;
}
}
这样就完成啦
输入刚刚配置的帐号密码就可以进入
SpringBoot+Mybatis
springBoot+Mybatis整合比较简单
@Mapper:作用在dao接口上,作用就是把这个接口转换成可以注入的实现类。(注意,此时只是转换成了实现类,并没有在IOC容器中,所以我们还要加上组件注解,如@Repository,不然会不起作用)
也可以在springBoot启动类加上:@MapperScan:扫描一个包上的Mapper接口,并将自动转换成实现类,这时候我们在加上一个组件注解,然后@AutoWired就可以了。
具体的SpringBoot+Mybatis原理还未掌握。。。
SpringBoot+Mybtis绑定异常解决
绑定异常有很多种,当我们Mapper和Mapper.xml都绑定起来了,但是还报错。
解决方法:在POM.xml加上Mybatis的文件过滤:
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
SpringBoot异步任务
使用场景:比如我们发送验证码,从前端发送请求到后端是要等待的(网络通信是有延迟的),比如我们发送成功一个验证码需要3s,如果不是异步操作,我们就处于“单线程“的状态,会在3s内都无法在页面进行任何操作,这样用户体验感会很差,如果我们是异步任务,就相当于“多线程”,会单独的开启一个线程去发送验证码,另外一个线程以供用户操作页面,这样用户的体验感会更好。
@Async:标注这个类或者方法是异步的,标注之后就相当于另外开启了一个线程去处理这个@Async方法
@EnableAsync:开启异步任务功能。(必须要有)
@SpringBootApplication
@EnableAsync //开启异步任务功能。
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Async的方法要放在另外的类上,不然会导致异步功能失效
错误示范:
发现上面的写法,@Async不起作用。
正确写法:
这样就生效了,所以结论是,@Async异步任务需要单独放在其他类上。。。。。(很重要)
SpringBoot定时任务
主要是运用cron表达式,进行定时的操作
public class MySend {
//每两秒执行一次。
@Scheduled(cron = "0/2 * * * * ? ")
public void send(){
System.out.println("hello");
}
}
@SpringBootApplication
@EnableScheduling //开启定时任务,定时任务是cron表达式
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
SpringBoot邮件任务
SpringBoot把原生java发送邮件的代码进行进一步的封装,使得原来十分繁琐的过程变得极其好用。
1.在Pom.xml导入对应的邮件启动器
<!-- springBoot邮件启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
2.开启qq邮箱的SMTP服务
3.获取SMTP授权码
4.配置application-dev.properties
#发送邮箱配置
spring.mail.host=smtp.qq.com
spring.mail.username=1550324080@qq.com #邮箱号
spring.mail.password=zgwjpsscpsidicce #授权码(不是密码)
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
发送简单邮件
5.用测试类去测试一下
@SpringBootTest
class DemoApplicationTests {
@Autowired
JavaMailSenderImpl javaMailSender; //邮件发送必须要的类
@Test
void contextLoads(){
//发送简单邮件用SimpleMailMessage类
SimpleMailMessage simpleMailMessage=new SimpleMailMessage();
simpleMailMessage.setFrom("1550324080@qq.com"); //从哪个邮箱发送
simpleMailMessage.setTo("1550324080@qq.com"); //发送到哪个邮箱
simpleMailMessage.setSentDate(new Date()); //日期
simpleMailMessage.setText("hello"); //内容文本
simpleMailMessage.setSubject("主题"); //题目
javaMailSender.send(simpleMailMessage); //开启发送邮件。。需要时间去发送,这里我们可以用异步方法,提升体验感
}
}
发现报错了。。。
成功了!!!!
这里有个要注意的点,就是刚刚为什么会报错。
当我们自动装配 JavaMailSenderImpl javaMailSender;会显示无法找到他对应的bean。。。导致刚刚报错
因为我们邮箱的配置必须要在application.properties里面配置,而不能在application-dev.properties配置
发送复杂邮件
@SpringBootTest
class DemoApplicationTests {
@Autowired
JavaMailSenderImpl javaMailSender;
@Test
void contextLoads() throws MessagingException, FileNotFoundException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage(); //创建复杂邮件
//*****需要上传附件,就要在MimeMessageHelper的构造器加上true,不然会报错****
MimeMessageHelper mimeMessageHelper=new MimeMessageHelper(mimeMessage,true); //创建MimeMessageHelper去封装MimeMessage
mimeMessageHelper.setFrom("1550324080@qq.com");
mimeMessageHelper.setTo("1550324080@qq.com");
mimeMessageHelper.setSubject("主题");
mimeMessageHelper.setText("<h3>h3字体</h3><br/><h5>h5字体</h5>");
// FileSystemResource fileSystemResource = new FileSystemResource(new File("C:\\Users\\youzhengjie666\\Pictures\\1.PNG"));
//上传附件
mimeMessageHelper.addAttachment("tupian1",new File("C:\\Users\\youzhengjie666\\Pictures\\1.PNG"));
javaMailSender.send(mimeMessage);
}
}
SpringBoot+Shiro安全框架
1.先导入Shiro-spring的依赖
<!-- shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>
2.创建一个类,去配置shiro
package com.boot.shiro;
import com.boot.realm.myRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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 org.springframework.web.filter.DelegatingFilterProxy;
import javax.servlet.Servlet;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@Configuration
public class myShiro {
//配置加密
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("MD5");
return hashedCredentialsMatcher;
}
@Bean
public Realm realm(@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher hashedCredentialsMatcher){
myRealm myRealm=new myRealm();
myRealm.setCredentialsMatcher(hashedCredentialsMatcher);
return myRealm;
}
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("realm") Realm realm){
DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(realm);
return defaultWebSecurityManager;
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
LifecycleBeanPostProcessor lifecycleBeanPostProcessor = new LifecycleBeanPostProcessor();
return lifecycleBeanPostProcessor;
}
@Bean("shiroFilter")
public ShiroFilterFactoryBean setshiroFilter(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
shiroFilterFactoryBean.setLoginUrl("/tologin");
shiroFilterFactoryBean.setSuccessUrl("/tolist");
shiroFilterFactoryBean.setUnauthorizedUrl("/tounauth");
LinkedHashMap<String, String> filters = new LinkedHashMap<>();
filters.put("/tologin","anon");
filters.put("/login","anon");
filters.put("/toadmin","roles[admin]");
filters.put("/touser","roles[user]");
filters.put("/**","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filters);
return shiroFilterFactoryBean;
}
// @Bean
// public FilterRegistrationBean shiroFilter(){
// FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
// filterRegistrationBean.setFilter(new DelegatingFilterProxy());
// ArrayList<Object> list = new ArrayList<>();
// list.add("/**");
// filterRegistrationBean.setUrlPatterns(list);
//
// return filterRegistrationBean;
// }
}
3.创建一个类,配置realm
package com.boot.realm;
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 java.util.HashSet;
import java.util.Set;
public class myRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//模仿从后台查询数据库
String us="123";
String pd="202cb962ac59075b964b07152d234b70"; //原密码是:123 ,这是MD5加密而成的
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(us,pd,this.getName());
return info;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取principal===>也就是我们传入的帐号
String principal = (String) principalCollection.getPrimaryPrincipal();
Set<String> roles=new HashSet<>();
roles.add("admin");
SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo(roles);
return simpleAuthorizationInfo;
}
}
4.配置controller层
@Controller
public class testController {
@RequestMapping(path = "/tologin")
public String tologin(){
return "login";
}
@RequestMapping(path = "/login")
public String login(String username,String password){
Subject subject = SecurityUtils.getSubject();
if(!subject.isAuthenticated()){
UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);
try {
subject.login(usernamePasswordToken);
}catch (Exception e){
return "redirect:tologin";
}
}
return "forward:tolist";
}
@RequestMapping(path = "/tolist")
public String tolist(){
return "list";
}
@RequestMapping(path = "/tounauth")
public String tounauth(){
return "unauth";
}
@RequestMapping(path = "/toadmin")
public String toadmin(){
return "role_admin";
}
@RequestMapping(path = "/touser")
public String touser(){
return "role_user";
}
}
5.需要的html文件
扩展MVC
扩展SpringMVC只需要去实现WebMvcConfigurer类就可以了,并且这个类是配置类
如果加了@EnableWebMVC注解,就相当于全面接管SpringMVC,也就是会把SpringBoot默认配置全部失效
@Configuration
public class myMvcConfig implements WebMvcConfigurer {
//添加视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//这个代码相当于==>
//@RequestMapping("/test")
//public String xxx{
// return "role_admin";
//}
registry.addViewController("/test").setViewName("role_admin");
}
}
页面国际化
创建xxx.properties作为默认国际化配置文件,xxx_zh_CN.properties作为中文配置,xxx_en_US.properties作为英文配置,这个Resource Bundle 'login’是会自动生成的
进入login.properties
左上角有个“+”号,就是用来添加国家化消息的
在application-dev.properties指定国家化消息的basename,因为我们自定义了xxx.properties的xxx是login,所以login就是我们的总的国家化配置文件,只需要绑定这个login就行了
spring.messages.basename=i18n.login //i18n就是我们用来存放国家化配置文件的包名
login.html
<form th:action="@{/login}" th:method="post">
<span th:text="#{username}"></span>:<input type="text" name="username">
<br/>
<span th:text="#{password}"></span>:<input type="password" name="password">
<br/>
<input type="submit" th:value="#{submit}">
</form>
<a th:href="@{/tologin(locale='zh_CN')}">中文</a>
<a th:href="@{/tologin(locale='en_US')}">English</a>
注意:thymeleaf的#{}就是用来取国家化消息的
此时我们想进行中英文切换。我们需要做如下配置:
1.在login.html中传locale
<a th:href="@{/tologin(locale='zh_CN')}">中文</a>
<a th:href="@{/tologin(locale='en_US')}">English</a>
2.配置自定义的localeResolver
public class myLocale implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
Locale aDefault = Locale.getDefault();//获取默认的Locale
String locale = request.getParameter("locale"); //获取login.html传来的语言
if(!StringUtils.isEmpty(locale)){
//zh_CN 要变成====>Locale("zh","CN"),只有把"_"分割成zh和CN
String language=locale.charAt(0)+""+locale.charAt(1);
String country=locale.charAt(3)+""+locale.charAt(4);
return new Locale(language, country);
}
return aDefault;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
3.将这个自定义LocaleResolver交给Spring管理
注意:这个自定义地区解析器的Bean的id必须是“ localeResolver ”,不然会找不到这个Bean
@Configuration
public class myLocaleConfig {
@Bean("localeResolver")
public myLocale localeResolver(){
return new myLocale();
}
}
然后就大功告成了
- 点赞
- 收藏
- 关注作者
评论(0)