记录一下最近整理的spring boot项目
项目地址:
1.选择Spring Initializr 一直点击next,直到创建完成
2.创建spring boot子模块,创建无任何模板的maven项目
3.项目结构
- commone——公共类及工具类存放处,可在该项目中引入其他工具jar包
- entity——实体类层
- dao——数据持久层
- api——service接口,配置double及注册中心可供rpc消费端调用
- service——业务逻辑
- webapp——web项目url请求入口
4.pom.xml文件
- 父类pom文件
4.0.0 pom backstage-common backstage-dao backstage-entiy backstage-api backstage-service backstage-webapp org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.xulong com.xulong.backstage 0.0.1-SNAPSHOT backstage Demo project for Spring Boot 1.8 - common层pom.xml文件
com.xulong.backstage com.xulong 0.0.1-SNAPSHOT 4.0.0 backstage-common - entity层pom文件
com.xulong.backstage com.xulong 0.0.1-SNAPSHOT 4.0.0 backstage-entiy com.github.pagehelper pagehelper 5.1.2 org.codehaus.mojo build-helper-maven-plugin 3.0.0 - dao层pom文件
com.xulong.backstage com.xulong 0.0.1-SNAPSHOT 4.0.0 backstage-dao com.xulong backstage-entiy 0.0.1-SNAPSHOT org.mybatis mybatis-typehandlers-jsr310 1.0.2 org.mybatis mybatis 3.4.5 compile org.codehaus.mojo build-helper-maven-plugin 3.0.0 - api层pom文件
com.xulong.backstage com.xulong 0.0.1-SNAPSHOT 4.0.0 backstage-api com.xulong backstage-entiy 0.0.1-SNAPSHOT com.xulong backstage-common 0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test - service层pom文件
com.xulong.backstage com.xulong 0.0.1-SNAPSHOT 4.0.0 backstage-service com.xulong backstage-api 0.0.1-SNAPSHOT com.xulong backstage-dao 0.0.1-SNAPSHOT com.github.pagehelper pagehelper-spring-boot-starter 1.2.3 org.springframework.boot spring-boot-starter-logging org.mybatis.generator mybatis-generator-core 1.3.6 org.apache.shiro shiro-spring 1.3.2 org.mybatis.generator mybatis-generator-maven-plugin 1.3.6 mysql mysql-connector-java 5.1.44 true true org.codehaus.mojo build-helper-maven-plugin 3.0.0 - webapp层pom文件
com.xulong.backstage com.xulong 0.0.1-SNAPSHOT 4.0.0 com.xulong backstage-webapp 0.0.1-SNAPSHOT war UTF-8 UTF-8 1.8 com.xulong backstage-service 0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test org.springframework.boot spring-boot-test test com.jayway.jsonpath json-path test mysql mysql-connector-java 5.1.44 org.springframework.boot spring-boot-test 1.5.6.RELEASE test org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-tomcat provided backstage-webapp org.springframework.boot spring-boot-maven-plugin com.xulong.backstage.BackstageApplication true repackage org.apache.maven.plugins maven-war-plugin false 2.5
5.配置文件application.properties
#数据库链接配置spring.datasource.url=jdbc:mysql://**.**.***.***:3306/backstage?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=falsespring.datasource.driverClassName=com.mysql.jdbc.Driverspring.datasource.username=rootspring.datasource.password=server.port=8080mybatis.mapper-locations=classpath:mybatis/mapper/*Mapper*.xmlmybatis.configuration.log-prefix=com.xulong.backstage.dao#静态资源#表示所有的访问都经过静态资源路径spring.mvc.static-path-pattern=/static/**#在这里表示配置静态资源根路径spring.resources.static-locations=classpath:/static/#mvc跳转路径Thymeleaf.prefix=classpath:/templates/#热部署生效spring.devtools.restart.enabled=true#静态文件热部署spring.thymeleaf.cache=false#显示sql语句logging.level.com.xulong.backstage.dao.mapper=debug#pagehelper分页插件配置pagehelper.helper-dialect=mysqlpagehelper.offset-as-page-num=truepagehelper.row-bounds-with-count=truepagehelper.page-size-zero=falsepagehelper.reasonable=falsepagehelper.support-methods-arguments=truepagehelper.params=pageNum=page;pageSize=size;count=countSql;
6.mybatis.generator插件配置
- generatorConfig.xml配置
- 引入文件generator.properties配置
jdbc.driverClass = com.mysql.jdbc.Driverjdbc.url = jdbc:mysql://**.**.***.***:3306/backstage?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=falsejdbc.username = rootjdbc.password = module.domain = backstage-entiymodule.dao = backstage-daopackage.mapper = com.xulong.backstage.dao.mapperpackage.domain = com.xulong.backstage.entitydriverPath = D:\repository4\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jarjdk.use_jdk8_time = true
7.shiro框架配置
- java类方式配置
package com.xulong.backstage;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.spring.LifecycleBeanPostProcessor;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 org.springframework.context.annotation.DependsOn;import java.util.LinkedHashMap;/** * @author xulong * shiro 安全框架配置 */@Configurationpublic class ShiroConfiguration { //==============Shiro================ /** * 配置SecurityManager对象(Shiro核心) * @param userUserRealm * @return */ @Bean("securityManager") public DefaultWebSecurityManager newDefaultWebSecurityManager(ShiroUserRealm userUserRealm){ DefaultWebSecurityManager sManager = new DefaultWebSecurityManager(); sManager.setRealm(userUserRealm); return sManager; } @Bean("shiroFilter") public ShiroFilterFactoryBean newShiroFilterFactory( @Autowired SecurityManager securityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager); //未登录跳转的url bean.setLoginUrl("/login.html"); LinkedHashMap
fcMap = new LinkedHashMap<>(); fcMap.put("/login.html", "anon"); fcMap.put("/validateLogin.html","anon"); fcMap.put("/test","anon"); //退出url fcMap.put("/logout.html", "logout"); //放开静态文件权限 fcMap.put("/static/**","anon"); fcMap.put("/**", "authc"); //必须授权才能访问 authc bean.setFilterChainDefinitionMap(fcMap); //登录成功跳转的url bean.setSuccessUrl("/index.html"); return bean; } /** * 配置shiro生命周期管理器 * @return */ @Bean("lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor newLifecycleBeanPostProcessor(){ return new LifecycleBeanPostProcessor(); } /** * 配置shiro注解应用 * */ @DependsOn(value="lifecycleBeanPostProcessor") @Bean public DefaultAdvisorAutoProxyCreator newDefaultAdvisorAutoProxyCreator(){ return new DefaultAdvisorAutoProxyCreator(); } @Bean public AuthorizationAttributeSourceAdvisor newAuthorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor bean= new AuthorizationAttributeSourceAdvisor(); bean.setSecurityManager(securityManager); return bean; }} - 登录验证类
package com.xulong.backstage;import com.xulong.backstage.common.constants.DictCodeConstants;import com.xulong.backstage.dao.mapper.UserMapper;import com.xulong.backstage.entity.User;import org.apache.shiro.authc.*;import org.apache.shiro.authc.credential.CredentialsMatcher;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;/** * @author xulong * shiro 验证登录等类 */@Servicepublic class ShiroUserRealm extends AuthorizingRealm { @Autowired private UserMapper userMapper; @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //1.获取客户端提交的用户信息 UsernamePasswordToken upToken = (UsernamePasswordToken)token; String username = upToken.getUsername(); upToken.getPassword(); User user = userMapper.findUserByUserCode(username); if(user == null){ throw new AuthenticationException("用户名或密码不正确!"); } if(DictCodeConstants.DICT_100002_1.equals(user.getUserStatus())){ throw new AuthenticationException("账户已被冻结,请联系管理员!"); } if(DictCodeConstants.DICT_100002_2.equals(user.getUserStatus())){ throw new AuthenticationException("账户已被禁用,请联系管理员!"); } SimpleAuthenticationInfo simple = new SimpleAuthenticationInfo( user, //传入对象后,后续可以在shiro中获取登录用户的对象信息 user.getPassword(), getName()); return simple;//返回给认证管理器 } /** * 此方法用于获取用户权限信息----执行权限操作 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { return null; } /** * 设置凭证匹配器 */ @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { //密码验证是否成功方法,比如密码错误有其它操作或者有自己的校验要求 CustomCredentialsMatcher cMatcher = new CustomCredentialsMatcher(); super.setCredentialsMatcher(cMatcher); }}
- 密码验证类
package com.xulong.backstage;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;import java.util.Objects;public class CustomCredentialsMatcher extends SimpleCredentialsMatcher { @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { UsernamePasswordToken utoken=(UsernamePasswordToken) token; String dbPassword = (String) info.getCredentials(); String inPassword = new String(utoken.getPassword()); boolean fals = Objects.equals(dbPassword, inPassword); if(fals == false){ //更改当前用户登录错误次数,当错误次数大于3冻结当前用户 throw new AuthenticationException("用户名或密码不正确!"); } return fals; }}
8.thymeleaf部分使用
- 例如:当数据库存储时间格式为20190401092416,在网页中想显示为2091-04-01 09:24:16,但是thtmeleaf未提供方法转换,需要我们写一个转换类
- DateUtil类写一个格式转换方法
package com.xulong.backstage.common.util;import java.text.SimpleDateFormat;import java.util.Date;/** * @author xulong * @date 2019/03/26 */public class DateUtil { /** 模式 :yyyyMMddHHmmss */ public static final String YYYYMMDD_HHMMSS = "yyyyMMddHHmmss"; /** 模式 :yyyyMMdd */ public static final String YYYYMMDD = "yyyyMMdd"; /** 模式 :yyyyMM */ public static final String YYYYMM = "yyyyMM"; /** 模式 :HHmmss */ public static final String HHMMSS = "HHmmss"; /** 模式 :HHmm */ public static final String HHMM = "HHmm"; public static final String FORMAT_YMDHMS = "yyyy-MM-dd HH:mm:ss"; public static final String DATE_FORMAT_DAY = "yyyy-MM-dd"; /** * 获取当前日期的数字格式 * 如20190326 * @return */ public static Long getNowDate(){ Date date = new Date(); return Long.valueOf(date2String(date,YYYYMMDD)); } /** * 获取当前时间的数字格式 * 如20190326141225 * @return */ public static Long getNowDateTime(){ Date date = new Date(); return Long.valueOf(date2String(date,YYYYMMDD_HHMMSS)); } /** * longFormat:(long类型的日期转化为格式化日期字符串,如20160717122121转化为2016-07-17 12:21:21) * @param srcLong long类型的日期如20160717122121 * @param pattern 格式化日期字符串如2016-07-17 12:21:21 * @return */ public static String longFormat(Long srcLong,String pattern){ if (srcLong == null) { return ""; } if (srcLong == 0) { return "0"; } Date date = string2Date(String.valueOf(srcLong)); return date2String(date,pattern); } /** * intFormat:(long类型的日期转化为格式化日期字符串,如20160717转化为2016-07-17) * * @param src Integer 类型的日期如20160717122121 * @param pattern 格式化日期字符串如2016-07-17 12:21:21 * @return * @throws * @since DateUtils.java Ver 1.0 */ public static String intFormat(Integer src, String pattern) { if (src == null) { return ""; } if (src == 0) { return "0"; } Date date = string2Date(String.valueOf(src)); return date2String(date, pattern); } /** * 方法说明:日期类型按照指定格式转成字符串. * * @param date * @param pattern * @return */ public static String date2String(Date date, String pattern) { if (null == date) { date = new Date(); } if (pattern.length() == 0 || pattern == null) { pattern = FORMAT_YMDHMS; } try { return getDateFormat(pattern).format(date); } catch (Exception e) { throw new RuntimeException("日期转换异常"); } } /** * 方法说明:字符串转日期类型. * * @param date * @return */ public static Date string2Date(String date) { try { if (date.length() == 8) { return getDateFormat(YYYYMMDD).parse(date); } else if (date.length() == 14) { return getDateFormat(YYYYMMDD_HHMMSS).parse(date); } else if (date.length() == 6) { return getDateFormat(HHMMSS).parse(date); } else { return null; } } catch (Exception e) { throw new RuntimeException("日期转换异常"); } } /** * 获取指定日期指定格式的日期字符串 * @return */ private static String getDate(String pattern,Date date){ SimpleDateFormat format = getDateFormat(pattern); return format.format(date); } /** * 获取指定模式pattern的SimpleDateFormat对象 * @param str * @return */ private static SimpleDateFormat getDateFormat(String str){ return new SimpleDateFormat(str); }}
- 在控制层封装DateUtil对象
@RequestMapping("/index.html") public String index(Model model){ model.addAttribute("dateUtil",new DateUtil()); Long date = 20160824121425L; model.addAttribute("date",date); return "index"; }
- html页面中书写方式 欢迎来到后台管理页面
- 页面显示的内容