SpringBoot 第1天 Springboot的配置文件和模版thymeleaf

Spring Config

1.说明

Java配置方式就是使用Java类来替代Spring原先的xml文件

2.实现方式

主要依赖于@Confuration和@Bean注解实现
@Confuration:使用在类上,说明该类是一个配置类相当于一个xml文件
@Bean:使用在方法上,作用是返回对象将对象保存在IOC容器中相当于XML文件中的bean标签

3.Config


@Configuration
@PropertySource(value="classpath:db.properties")
public class SpringConfig {

	@Bean
	public UserService userService(){
		return new UserServiceImpl();
	}
	@Value("${mysql.username}")
	private String username;
	@Value("${password}")
	private String password;
	@Bean
	public String username() {
		return username;
	}
	@Bean
	public String password() {
		return password;
	}
}

4.入口类

ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean(UserService.class);
System.out.println(userService);
String username = (String) context.getBean("mysql.username");
String password = (String) context.getBean("mysql.password");

System.out.println(username);
System.out.println(password);

Springboot介绍

首先声明,Spring Boot不是一门新技术,所以不用紧张。从本质上来说,Spring
Boot就是Spring,它做了那些没有它你也会去做的Spring
Bean配置。它使用“习惯优于配置”(项目中存在大量的配置,此外还内置了一个习惯性
的配置,让你无需手动进行配置)的理念让你的项目快速运行起来。使用Spring 
Boot很容易创建一个独立运行(运行jar,内嵌Servlet容器)、准生产级别的基于Spring
框架的项目,使用Spring Boot你可以不用或者只需要很少的Spring配置。


http://tengj.top/2017/04/24/springboot0/

SpringBoot

2.1 SpringBoot的好处

1.快速构建项目
2.对主流开发框架的无配置集成
3.项目可独立运行,无需外部依赖Servlet容器,springboot中内嵌一个tomcat
4.提高开发效率,部署效率
5.与云计算的天然集成
例如:
其实就是简单、快速、方便!平时如果我们需要搭建一个spring web项目的时候需要怎么做呢?
1)配置web.xml,加载spring和spring mvc
2)配置数据库连接、配置spring事务
3)配置加载配置文件的读取,开启注解
4)配置日志文件
...
配置完成之后部署tomcat 调试
...
现在非常流行微服务,如果我这个项目仅仅只是需要发送一个邮件,如果我的项目仅仅是生产一个积分;我都需要这样折腾一遍!
但是如果使用spring boot呢?
很简单,我仅仅只需要非常少的几个配置就可以迅速方便的搭建起来一套web项目或者是构建一个微服务!

第一个SpringBoot :HelloWorld

  1. 网页介绍
http://start.spring.io/
  1. pom.xml解析(父级依赖)
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

3.应用入口类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class Chapter1Application {

	@RequestMapping("/")
	public String index(){
		return "Hello Spring Boot";
	}
	public static void main(String[] args) {
		SpringApplication.run(Chapter1Application.class, args);
	}
}

4.解决报错问题

<dependency>
		    <groupId>org.hibernate</groupId>
		    <artifactId>hibernate-validator</artifactId>
		    <version>5.3.0.Final</version>
		</dependency>

SpringBoot原理

image

Banner

如果我们想改动,那么只需要在src/main/recesources下新建一个banner.txt文件
实际上Spring Boot在这个位置,放了一个彩蛋,我们是可以自定义这个图标的。

我们可以在resource目录下面放入一个banner.txt文件,
Spring Boot启动项目的时候就会优先启动这个文件中的内容。

http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20

SpringBoot配置文件(application.properties)

http://tengj.top/2017/02/28/springbootconfig/

mybatis

#指定bean所在包
mybatis.type-aliases-package=com.dudu.domain
#指定映射文件
mybatis.mapperLocations=classpath:mapper/*.xml


spring.datasource.url=jdbc:mysql://localhost:3306/work1?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver



mybatis注解

# crud
# 名称不一致
	@Select("select * from book where id = #{id}")
	@Results({
		@Result(property="id",column="id",id=true),
		@Result(property="name",column="b_name"),
		@Result(property="createTime",column="b_create_time"),
		@Result(property="price",column="price")
	})
	public Book findById(int id);

# 一对一
@Select("select * from chapter")
	@Results({ 
		@Result(property = "id", column = "id",id=true),
		@Result(property = "name", column = "name"),
		@Result(property = "bookId", column = "book_id"),
		@Result(property = "book",column="book_id",one = @One(fetchType=FetchType.EAGER,select="com.zhiyou100.mapper.BookMapper.findById"))
	})
	public List<Chapter> findAll();

# 一对多
	@Select("select * from book")
	//解决数据库和java属性不一致
	//property:java属性
	//column:数据库属性
	//id:判断是否是主键
	@Results({
		@Result(property="id",column="id",id=true),
		@Result(property="name",column="b_name"),
		@Result(property="createTime",column="b_create_time"),
		@Result(property="price",column="price"),
		@Result(property="chapters",column="id",many=@Many(fetchType=FetchType.EAGER,select="com.zhiyou100.mapper.ChapterMapper.findByBookId"))
		
	})
	public List<Book> findAll();
# 多对多
	@Select("select * from user")
	@Results({
		@Result(property="id",column="id",id=true),
		@Result(property="roles",column="id",many=@Many(fetchType=FetchType.EAGER,select="com.zhiyou100.mapper.RoleMapper.findByUserId"))	
	})
	public List<User> findUserAndRole();
		@Select("SELECT * from role r INNER JOIN  user_role ur ON r.id = ur.role_id where ur.user_id = #{userId}")
	public List<Role> findByUserId(int userId);

SpringBoot模版(templates:thymeleaf)

  1. Jar包
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  1. 配置文件
spring.thymeleaf.cache=true
spring.thymeleaf.check-template=true 
spring.thymeleaf.check-template-location=true
spring.thymeleaf.content-type=text/html
spring.thymeleaf.enabled=true
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.excluded-view-names=
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
  1. 头文件导入
<html xmlns:th="http://www.thymeleaf.org">

4.文本显示

<td th:text="${learn.author}"></td>

5.链接显示

<a th:text="${page}" th:href="@{/order/details(orderId=${page})}">
</a>

6.for循环表达(3种)

遍历数组
<tr th:each="learn : ${learnList}">
 	<td th:text="${learn.author}"></td>
	<td th:text="${learn.title}"></td>
	<td th:text="${learn.url}"></td>
</tr>
遍历数组:详细版本
<tr th:each="learn,item : ${learnList}">
    <td th:text="${item}"></td>
	<td th:text="${learn.author}"></td>
	<td th:text="${learn.title}"></td>
	<td th:text="${learn.url}"></td>
</tr>
循环指定次数
<span  th:each="page :${#numbers.sequence(1,count)}">
</span>

6.条件表达式

<tr th:class="${row.even}? 'even' : 'odd'">
</tr>

7 switch

	<p th:switch="${page}">
		<font th:case="1"> 匹配1 </font> 
		<font th:case="2"> 匹配2</font>
		<font th:case="*">默认匹配</font>
	</p>

8.其他作用域访问

${param.x} 返回名为x 的 request参数。(可能有多个值)
${session.x} 返回名为x的Session参数。
${application.x} 返回名为 servlet application context 的参数。

9.if

th:if="${xx} lt 'x'" 
 
 
 
gt:great than(大于)>
ge:great equal(大于等于)>=
eq:equal(等于)==
lt:less than(小于)<
le:less equal(小于等于)<=
ne:not equal(不等于)!=

SpringBoot静态文件(static:js、css)

log日志

依赖

         <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-logging</artifactId>
		</dependency>

代码输出

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private  static final Logger logger =  LoggerFactory.getLogger(UserController.class);

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 此xml在spring-boot-1.5.3.RELEASE.jar里 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <!-- 开启后可以通过jmx动态控制日志级别(springboot Admin的功能) -->
    <!--<jmxConfigurator/>-->

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--<File>/home/hfw-client/hfw_log/stdout.log</File>-->
        <File>D:/log/hfw-client/hfw_log/stdout.log</File>
        <encoder>
            <pattern>%date [%level] [%thread] %logger{60} [%file : %line] %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 添加.gz 历史日志会启用压缩 大大缩小日志文件所占空间 -->
            <!--<fileNamePattern>/home/hfw-client/hfw_log/stdout.log.%d{yyyy-MM-dd}.log</fileNamePattern>-->
            <fileNamePattern>D:/log/hfw-client/hfw_log/stdout.log.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory><!--  保留30天日志 -->
        </rollingPolicy>
    </appender>

    <logger name="com.zhiyou100" level="DEBUG" />

    <root level="info">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

Maven下载失败


 
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;
 
/**
 * 删除maven下载失败的目录
 * <pre>
 * 先搜索 存在 lastUpdated的文件(即jar文件等),
 * 然后再删除此文件的目录
 * </pre>
 */
public class DeleteMavenDownloadfailedFile {
 
	/**声明统计文件个数的变量*/ 
	static int countFiles = 0;
	
	/**声明统计文件夹的变量*/ 
	static int countFolders = 0;
 
	/**
	 *递归查找包含关键字的文件
	 */ 
	public static File[] searchFile(File folder, final String keyWord) {
 
		File[] subFolders = folder.listFiles(new FileFilter() {// 运用内部匿名类获得文件
					public boolean accept(File pathname) {// 实现FileFilter类的accept方法
						if (pathname.isFile()) {// 如果是文件
							countFiles++;
						} else {
							// 如果是目录
							countFolders++;
						}
						if (pathname.isDirectory()
								|| (pathname.isFile() && pathname.getName().toLowerCase().contains(keyWord.toLowerCase()))) {// 目录或文件包含关键字
							return true;
						}
						return false;
					}
				});
 
		List<File> result = new ArrayList<File>();// 声明一个集合
		for (int i = 0; i < subFolders.length; i++) {// 循环显示文件夹或文件
			if (subFolders[i].isFile()) {// 如果是文件则将文件添加到结果列表中
				result.add(subFolders[i]);
			} else {// 如果是文件夹,则递归调用本方法,然后把所有的文件加到结果列表中
				File[] foldResult = searchFile(subFolders[i], keyWord);
				for (int j = 0; j < foldResult.length; j++) {// 循环显示文件
					result.add(foldResult[j]);// 文件保存到集合中
				}
			}
		}
		File files[] = new File[result.size()];// 声明文件数组,长度为集合的长度
		result.toArray(files);// 集合数组化
		return files;
	}
 
	
	public static File[] find(String root, String keyword) {
		File folder = new File(root);// 默认目录
		if (!folder.exists()) {// 如果文件夹不存在
			System.out.println("目录不存在:" + folder.getAbsolutePath());
			return null;
		}
		File[] result = searchFile(folder, keyword);// 调用方法获得文件数组
 
		return result;
	}
 
	/**
	 * 删除文件和目录
	 * 
	 * 注意:根据业务场景,此方法没有采用递归删除
	 * 
	 * @param file
	 */
	public static void delete(File file) {
		if (file.exists()) {
			if (file.isFile()) {
				boolean bb = file.delete();
				System.out.println(file.getAbsolutePath() + " 删除状态:" + bb);
			} else if (file.isDirectory()) {
				File files[] = file.listFiles();
				for (int i = 0; i < files.length; i++) {
					File _file = files[i];
					boolean bb = _file.delete();
					System.out.println("      " + _file.getAbsolutePath() + " 删除状态:" + bb);
				}
			}
			boolean bb = file.delete();
			System.out.println(file.getAbsolutePath() + " 删除状态:" + bb);
		} else {
			System.out.println("所删除的文件不存在!" + file.getAbsolutePath());
		}
	}
 
	public static void main(String[] args) {
		String root = "E:\\lee\\maven";
		String keyword = "lastUpdated";
 
		File[] result = find(root, keyword);
		if (result == null ) {
			return;
		}
		if (result.length == 0) {
			System.out.println("查找文件为 0");
			return;
		}
		
		System.out.println("在 " + root + " 以及所有子文件时查找对象" + keyword);
		System.out.println("查找了" + countFiles + " 个文件," + countFolders + " 个文件夹,共找到 " + result.length + " 个符合条件的文件:");
		for (int i = 0; i < result.length; i++) {// 循环显示文件
			File file = result[i];
			delete(new File(file.getParentFile().getAbsolutePath()));
			// System.out.println(file.getAbsolutePath() +
			// " == "+file.getParentFile().getAbsolutePath());// 显示文件绝对路径
		}
 
	}
}

Shiro和SpringBoot结合

package com.zhiyou100.config;

import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.zhiyou100.realm.UserRealm;

import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.mgt.SecurityManager;
@Configuration
public class ShiroConfig {

	@Autowired
	UserRealm userRealm;
	
	@Bean
	public SecurityManager securityManager(){
		DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
		manager.setRealm(userRealm);
		return manager;
	}
	@Bean
	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
		ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
		bean.setSecurityManager(securityManager);
		bean.setLoginUrl("/login.html");
		bean.setUnauthorizedUrl("/error.html");
		Map<String, String> map = new HashMap<String, String>();
		map.put("/css/**", "anon");
		map.put("/img/**", "anon");
		map.put("/user/login.do", "anon");
		map.put("/login.html", "anon");
		map.put("/error.html", "anon");
		map.put("/**", "authc");
		bean.setFilterChainDefinitionMap(map);
		return bean;
	}
	@Bean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
		DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
		creator.setProxyTargetClass(true);
		return creator;
	}
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
		return new AuthorizationAttributeSourceAdvisor();
	}
}

thymeleaf和shiro结合

添加依赖

<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>

在shiro的configuration中配置

@Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

在html中加入xmlns

<html lang="zh_CN" xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

使用


# 判断是否有角色
shiro:hasRole="user"
# 判断是否有权限
shiro:hasPermission="update"
# 获取当前登录的账号,account代表调用account属性
shiro:principal property="account"

例如:
<span shiro:authenticated="true" >
      <span>欢迎您:<span th:text="${userInfo.realName}"></span></span>
</span>
<div shiro:hasPermission="update">
    <a href="/2">2222</a>
</div>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值