spring boot 整合shiro和thymeleaf模板,SSM架构,整体业务框架搭建

一:项目Demo生成及全家桶(系列jar包)选择

一:demo生成:

1.在https://start.spring.io/官网进行项目生成(推荐)

2.在编译器中创建相关类型工程,在pom.xml中添加如下依赖,版本建议选择稳定版,最好不要选择最新版.

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

二:相关系列jar包选择

1.web相关系列jar包,包括了web开发的系列jar包,如springMVC,spring等

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

2.内置tomcat系列jar包(直接运行引导类则会运行tomcat)

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-tomcat</artifactId>
		<scope>provided</scope>
	</dependency>

PS:父类版本在2.0的时候,tomcat版本为8.5,如下图

3.热部署系列jar包(修改保存后及时自动发布,方便开发及补救紧急bug)

<dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-devtools</artifactId>
	        <optional>true</optional>
		</dependency>

4.测试类系列jar包

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

5.mybatis系列jar包

<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.0</version>
	</dependency>

PS:父类依赖中没有版本号的需要添加版本号,有版本号的可以删除版本号,看版本是否有黄色底线警告即可判断。

6.数据库连接系列jar包,也可使用spring-boot-starter-data-jpa,个人感觉jpa是hibernate的超级加强版,基于持久层方法名生成sql,骚的不行不行的。

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

7.前端模板系列jar包,spring boot 默认使用thymeleaf,对比jsp,thymeleaf有非常多的优势,支持html模板,可在网页直接调试样式等,无需像JSP放在应用服务器中加载,相关标签的使用对比JSP略有调整,但区别不是很大。

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

PS:如果需要使用JSP,则导入JSP相关jar包即可使用。

<!--配置servlet-->
		<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency> -->
 
		<!--配置jsp jstl的支持-->
        <!-- <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency> -->
        
        <!--对jsp的支持-->
        <!-- <dependency>
		    <groupId>org.apache.tomcat.embed</groupId>
		    <artifactId>tomcat-embed-jasper</artifactId>
		</dependency>

8.aop相关jar包,性能监控及相关权限控制等

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

9.缓存相关jar包

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

10.redis数据库相关jar包

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
            <version>RELEASE</version>
        </dependency>

如需要其他系列的jar包可自行搜索,百度或者spring boot官网都行

二:项目个性化设置及相关配置

一:个性化配置

1.项目运行时的banner图,如下

推荐一个将短语变成各种各样字体的网址:http://www.network-science.de/ascii/

2.配置banner图

在resources下新建一个txt文件即可,也可放置一个banner.gif文件,则项目在加载的时候会将gif每一帧画面变成点状图加载,加载完后开始加载项目,该操作主要是加强团队项目意识。

二:相关配置

1.application文件的配置,不做过多的解释,一看就明白的

#mysql配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/xxxx?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5

#redis配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=test@dbuser2018
spring.redis.ssl=false

# tomcat应用服务器配置
server.port:80


#thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

#mybatis的自定义属性配置 -暂时注释
mybatis.config= classpath:mybatis/sqlmap/mybatis-config.xml

#mybatis的mapper映射集合配置
mybatis.mapperLocations=classpath:mybatis/**/*-sqlmap.xml

#日志打印配置
#打印执行的SQL
logging.level.mapper路径=debug

ps:spring boot会自动加载resources目录下的porperties文件,所以系统配置文件和自定配置文件最好分开。

2.自定义配置文件的相关操作,自定义文件依然放置在resources目录下,需要使用相对应的配置文件类进行读取

3.编写配置文件读取类

/**  
* @Title: DBConfig.java
* @Description: 用以获取初始化主键
* @author shadow
* @date 2018年10月9日 下午5:01:58
* @version V1.0  
*/

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
* @ClassName: DBConfig
* @Description: 表名主键配置类,用以获取初始化主键
* @author shadow
* @date 2018年10月9日 下午5:01:58
*/
@Component
@ConfigurationProperties(prefix="dbid")
@PropertySource("classpath:dbidconfig.properties")
public class DBIdConfig {
	
	//单位配置主键
	private String configCompanyId;

	public String getConfigCompanyId() {
		return configCompanyId;
	}
	public void setConfigCompanyId(String configCompanyId) {
		this.configCompanyId = configCompanyId;
	}	
}

4.获取方式,直接像获取实体类属性一样get就行了。

三:项目业务相关基础类编写

一:权限方面,spring boot 推荐的spring security ,因为不是非常熟悉security,所以使用shiro

导入jar包,以下含有thymeleaf模板对shiro标签的支持。

<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
<dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
            </dependency>
        <!--thymeleaf-shiro-extras-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

shiro重要的两个类:一个是bean配置类,一个是重写AuthorizingRealm的权限验证和授权的自定义类

1.配置类

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
	/**
	 * 缓存管理器
	 * @return
	 */
	@Bean
	public EhCacheManager ehCacheManager(){
	    EhCacheManager cacheManager = new EhCacheManager();
	    cacheManager.setCacheManagerConfigFile("classpath:encache/ehcache-shiro.xml");
	    return cacheManager;
	}
	
	/**
     * 
    * @Title: shirFilter
    * @Description: shiro核心拦截器
    * @param @param securityManager
    * @param @return    设定文件
    * @return ShiroFilterFactoryBean    返回类型
    * @throws
     */
	@Bean
	public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		//拦截器.authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
		Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
		// 配置不会被拦截的链接 顺序判断
		//静态资源
		filterChainDefinitionMap.put("/static/**", "anon");
		//注册路径
		filterChainDefinitionMap.put("/registration", "anon");
		//登录校验
		filterChainDefinitionMap.put("/loginCheck", "anon");
		//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
		filterChainDefinitionMap.put("/logout", "logout");
		//所有url都必须认证通过才可以访问
		filterChainDefinitionMap.put("/**", "authc");
		// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
		shiroFilterFactoryBean.setLoginUrl("/login");
		//未授权界面;
		shiroFilterFactoryBean.setUnauthorizedUrl("/403");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}
	
	
	/**
	 * 
	* @Title: shiroDialect
	* @Description: 用于thymeleaf模板使用shiro标签
	* @param @return    设定文件
	* @return ShiroDialect    返回类型
	* @throws
	 */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
	/**
	 * 
	* @Title: hashedCredentialsMatcher
	* @Description: 登录认证加密方式,需和数据库加密方式一致,密文=(盐+明文)MD5
	* @param @return    设定文件
	* @return HashedCredentialsMatcher    返回类型
	* @throws
	 */
	@Bean
	public HashedCredentialsMatcher hashedCredentialsMatcher(){
		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
		hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
		return hashedCredentialsMatcher;
	}

	/**
	 * 
	* @Title: securityManager
	* @Description: 权限认证信息,设置Realm
	* @param @return    设定文件
	* @return SecurityManager    返回类型
	* @throws
	 */
	@Bean
	public SecurityManager securityManager(){
		DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
		securityManager.setRealm(campShiroRealm());
		securityManager.setCacheManager(ehCacheManager());
		return securityManager;
	}
	
	/**
     * 
    * @Title: campShiroRealm
    * @Description: 配置shiro仓库
    * @param @return    设定文件
    * @return CampShiroRealm    返回类型
    * @throws
     */
    @Bean
	public CampShiroRealm campShiroRealm(){
		CampShiroRealm myShiroRealm = new CampShiroRealm();
		myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
		return myShiroRealm;
	}
	/**
	 * 
	* @Title: advisorAutoProxyCreator
	* @Description: 开启shiro aop注解支持,使用代理方式;所以需要开启代码支持
	* @param @return    设定文件
	* @return DefaultAdvisorAutoProxyCreator    返回类型
	* @throws
	 */
	@Bean
	   public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
	       DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
	       advisorAutoProxyCreator.setProxyTargetClass(true);
	       return advisorAutoProxyCreator;
	   }
	
	/**
	 * 
	* @Title: authorizationAttributeSourceAdvisor
	* @Description: 开启shiro aop注解支持,使用代理方式;所以需要开启代码支持
	* @param @param securityManager
	* @param @return    设定文件
	* @return AuthorizationAttributeSourceAdvisor    返回类型
	* @throws
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}
}

2.自定义类:

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import com.facejoy.camp.core.commons.WordDefined;
import com.facejoy.camp.entity.sys.SysAuth;
import com.facejoy.camp.entity.sys.SysRole;
import com.facejoy.camp.entity.sys.SysUser;
import com.facejoy.camp.service.sys.SysUserService;

public class CampShiroRealm extends AuthorizingRealm {
	
	@Autowired
	@Lazy
	SysUserService sysUserService;
	
	//权限管理,存入权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        ShiroUser shiroUser  = (ShiroUser)principals.getPrimaryPrincipal();
        if (shiroUser == null) {
            return null;
        } else {
            SysUser user = sysUserService.getUserRoleAndAuth(shiroUser.getLoginName());
            if (user != null) {
            	//System.out.println("用户角色:" + user.getRoles());
                for (SysRole role : user.getRoles()) {
                	authorizationInfo.addRole(role.getRoleCode());
                }
                //System.out.println("用户权限:" + user.getAuths());
                for (SysAuth auth : user.getAuths()) {
                	authorizationInfo.addStringPermission(auth.getAuthCode());
                }
            }
        }
        return authorizationInfo;
    }
    
    //登录认证,存入用户信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usertoken = (UsernamePasswordToken)token;
        SysUser sysUser = sysUserService.findUserByLoginName(usertoken.getUsername());
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
				 new ShiroUser(sysUser.getUserId(), sysUser.getLoginName(), sysUser.getUserName()), 
				 sysUser.getLoginPwd(),
				 ByteSource.Util.bytes(WordDefined.ADD_PWD_FIELD),
				 getName()
				 	);
        return authenticationInfo;
    }

}

3.shiro权限缓存配置文件ehcache-shiro.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>

    <diskStore path="java.io.tmpdir"/>

    <!--
       name:缓存名称。
       maxElementsInMemory:缓存最大数目
       maxElementsOnDisk:硬盘最大缓存个数。
       eternal:对象是否永久有效,一但设置了,timeout将不起作用。
       overflowToDisk:是否保存到磁盘,当系统当机时
       timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
       timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
       diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
       diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
       diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
       memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
        clearOnFlush:内存数量最大时是否清除。
         memoryStoreEvictionPolicy:
            Ehcache的三种清空策略;
            FIFO,first in first out,这个是大家最熟的,先进先出。
            LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
            LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
    />


    <!-- 登录记录缓存锁定10分钟 -->
    <cache name="passwordRetryCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

</ehcache>

4.tomcat错误返回自定义类

@Component
public class ErrorPageConfig implements ErrorPageRegistrar{

	@Override
	public void registerErrorPages(ErrorPageRegistry registry) {
		//1、按错误的类型显示错误的网页
        //错误类型为404,找不到网页的,默认显示404.html网页
        ErrorPage e404 = new ErrorPage(HttpStatus.NOT_FOUND, "/static/error/404.html");
        //错误类型为500,表示服务器响应错误,默认显示500.html网页
        ErrorPage e500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/static/error/500.html");
        registry.addErrorPages(e404, e500);
		
	}
	
	
}

5.缓存标签的使用,可缓存查询结果,对应有删除缓存标签,不一一举例

在引导类上加上@EnableCaching标签

至此:基本框架搭建完成,可以搭建业务结构了。

spring boot 非常适合微服务,只有几个接口或者业务比较少的项目,纯接口可生成jar包文件直接在服务器上运行,含有业务和页面的可生成war包直接发布。

6.thymeleaf模板中shiro标签的使用和jsp没有较大区别,引入thymeleaf使用标签即可,thymeleaf具体使用方法不赘述,可查看相关手册。

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值