SpringBoot老项目改造
Contents
源码:数据库里面有2个用户 huang/123456 admin用户 、 test/123456 vip用户
https://github.com/huangzhenshi/psm_SpringBoot
#
以前的一个传统的maven管理的web项目,改造成SpringBoot并且集成一些新框架
- 文件夹路径的改变
- maven项目把静态资源文件堆在webapp下面就可以了
改用SpringBoot之后,默认的静态文件,要放在 resources\static下面
- 老项目默认就可以直接用jsp啊
- 引入maven依赖
- 配置spring.mvc.view.prefix 和 suffix,这个很方便哎
- 设置module(web resource directory 为 webapp即可),设置web的路径为 webapp,和引入maven dependence
|
- 配置日志
- 简单暴力,在resources文件夹下添加logback-spring.xml
- 设置mysql 打印sql<?xml version="1.0" encoding="UTF-8"?><configuration scan="true" scanPeriod="60 seconds" debug="false"><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="debug"><appender-ref ref="console" /></root><logger name="account_huang.dao" level="debug"/></configuration>
设置热加载
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency>
- 引入jpa依赖
- 配置jpa选项
- 修改实体类,引入注解
- 修改接口<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>spring.jpa.database-platform= org.hibernate.dialect.MySQL5Dialectjpa.hibernate.show-sql= true@lombok.Data@Entity@Table(name="fuser")public class User{@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private String id;public interface UserMapper extends JpaRepository<User, Long>{
- 事务控制的支持
直接在service实现类的方法上添加 @Transactional 即可,该方法是依赖了 jpa的jar包,或者是jdbc的jar包里面的配置。
注意事项:
- service必须是在接口层才有用啊,也是奇怪了。
- mybatis的事务也受到JPA的控制,同一个父接口
集成Shiro
- 引入jar包依赖
- 配置ShiroConfig
- 重写Realm
- 引入表
- 添加对应的实体类
ShiroConfig配置
- 过滤路径的变更,因为资源都在 /res路径下面的,设置了/res的不校验、和 WEB-INFO下的tld、tag文件的免验证
- 设置LoginUrl,进入程序自动跳转到登陆界面
- 对登陆校验路径进行免验证
- 设置没有权限的自动跳转页面@Configurationpublic class ShiroConfig {@Beanpublic ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {System.out.println("ShiroConfiguration.shirFilter()");ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);//拦截器.Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();// 配置不会被拦截的链接 顺序判断filterChainDefinitionMap.put("/static/**", "anon");filterChainDefinitionMap.put("/**/*.tag", "anon");filterChainDefinitionMap.put("/**/*.tld", "anon");filterChainDefinitionMap.put("/res/**", "anon");filterChainDefinitionMap.put("/loginCheck", "anon");shiroFilterFactoryBean.setLoginUrl("/login.do");//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了filterChainDefinitionMap.put("/logout", "logout");filterChainDefinitionMap.put("/**", "authc");//未授权界面;shiroFilterFactoryBean.setUnauthorizedUrl("/403");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}}
集成ehcache缓存
https://blog.csdn.net/snakemoving/article/details/77104217
- 引入两个jar包
- 在启动类中添加ehcache
- 添加对应的ehcache配置文件<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>1.2.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency>@Beanpublic EhCacheManager ehCacheManager(){System.out.println("ShiroConfiguration.getEhCacheManager()");EhCacheManager cacheManager = new EhCacheManager();cacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");return cacheManager;}@Beanpublic SecurityManager securityManager(){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setCacheManager(ehCacheManager());//这个如果执行多次,也是同样的一个对象;securityManager.setRealm(myShiroRealm());return securityManager;}<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd"><diskStore path="java.io.tmpdir"/><defaultCachemaxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"maxElementsOnDisk="10000000"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache></ehcache>
引入shiro标签和路径的访问权限
对系统配置的Code配置需要有admin管理权限
对CodeController整个模块进行权限控制
@Controller@RequestMapping("/code")@RequiresRoles(value = "admin")public class CodeController{对code配置的标签进行权限控制
left-config.jsp里面进行配置<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%><div class="F-left" style="width:100%;"><div class="PanelLeft F-left"><div class="BoxLeft"><img src="${ctx}/res/resource/style/images/icon01Hit.png" width="40" height="38" alt="" /><h4><b>系统配置</b></h4></div><div class="clear"></div><div class="menuLeftFirst"><ul><shiro:hasRole name="admin"><li id="configCodeNav" class="hit" onclick="refreshCenter('${ctx}/code/toMainRecordPage.do?username=${username}');" ><span>Code Config</span></li></shiro:hasRole>
引入redis做集群的session共享
- nginx的负载均衡配置:http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;upstream tomcatserver2 {server 127.0.0.1:8098;server 127.0.0.1:8099;}server {listen 80;server_name localhost;location / {proxy_pass http://tomcatserver2;proxy_redirect default;}}}
系统配置: maven依赖、引入相关bean(RedisSessionConfig 、RedisCacheConfig)、配置属性
<!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- redis session --><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId><version>1.3.1.RELEASE</version></dependency>@Configuration@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 600)public class RedisSessionConfig {}spring.redis.host= 127.0.0.1spring.redis.port= 6379spring.redis.password= huangzsspring.redis.timeout= 0spring.redis.pool.max-idle=10spring.redis.pool.max-wait=3000注意事项
要redis缓存的 对象都要实现Serializable接口,否则会报错
使用redis集成shiro做session管理和权限缓存
参考博客,含有说明和源码
https://blog.csdn.net/liaoguolingxian/article/details/77017225
- 添加相关的工具类
- ShiroRedisCache implements Cache
{} 重写了 put get value size等方法 - ShiroRedisCacheManager extends AbstractCacheManager{} 注入了ShiroRedisCache
- RedisSessionDao 被sessionmanager引用,执行一些对session的管理,比如创建、更新等操作 RedisSessionDao redisSessionDao = new RedisSessionDao(redisTemplate);
- MySessionIdGenerator 也是为了sessionmanager提供一个项目特色的id而已
- 修改Shiro-config@Bean(name = "myShiroRealm")@DependsOn(value = {"lifecycleBeanPostProcessor", "ShiroRedisCacheManager"})public MyShiroRealm myShiroRealm(RedisTemplate redisTemplate) {MyShiroRealm shiroRealm = new MyShiroRealm();shiroRealm.setCacheManager(redisCacheManager(redisTemplate));shiroRealm.setCachingEnabled(true);//认证shiroRealm.setAuthenticationCachingEnabled(false);//授权shiroRealm.setAuthorizationCachingEnabled(false);return shiroRealm;}@Beanpublic SecurityManager securityManager(RedisTemplate redisTemplate){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setCacheManager(redisCacheManager(redisTemplate));securityManager.setRealm(myShiroRealm(redisTemplate));securityManager.setSessionManager(sessionManager(redisTemplate));return securityManager;}@Bean(name = "ShiroRedisCacheManager")public ShiroRedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {ShiroRedisCacheManager redisCacheManager = new ShiroRedisCacheManager(redisTemplate);//name是key的前缀,可以设置任何值,无影响,可以设置带项目特色的值redisCacheManager.createCache("shiro_redis");return redisCacheManager;}@Bean(name = "lifecycleBeanPostProcessor")public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}@Bean(name = "sessionManager")@DependsOn(value = "lifecycleBeanPostProcessor")public DefaultWebSessionManager sessionManager(RedisTemplate redisTemplate) {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();RedisSessionDao redisSessionDao = new RedisSessionDao(redisTemplate);//这个name的作用也不大,只是有特色的cookie的名称。redisSessionDao.setSessionIdGenerator(sessionIdGenerator("starrkCookie"));sessionManager.setSessionDAO(redisSessionDao);sessionManager.setDeleteInvalidSessions(true);SimpleCookie cookie = new SimpleCookie();cookie.setName("starrkCookie");sessionManager.setSessionIdCookie(cookie);sessionManager.setSessionIdCookieEnabled(true);return sessionManager;}public MySessionIdGenerator sessionIdGenerator(String name) {return new MySessionIdGenerator(name);}