已经有一个多月没有更新这个系列的文章了。本期目标是完成基础的手脚架。

号外

本项目github仓库:github.com/pc859107393…

本项目国内码云仓库:git.oschina.net/859107393/M…

本系列为连载文章。当然如果你没有spring基础,建议你先看看我的java手把手教程

当然我的简书访问速度更快

有兴趣交流springboot进行快速开发的同学可以加一下下面的企鹅群。

行走的java全栈

正文开始

首先我们需要简单的看看我们项目需要的支援:

  • 快速部署:spring-boot-devtools
  • 数据库相关:

    • Mybatis
    • Mybatis-plus(常规crud、自带分页)
    • Druid
    • 数据库链接
  • 核心依赖:spring

  • web处理:springMvc
  • 权限和鉴定:Shiro
  • 网络通信:okhttp
  • json解析:gson、fastJson
  • 在线APIDocs:SpringFox
  • 模板引擎:freemarker
  • 等等···

当然仅仅拥有这些,还不足以完成一个项目的搭建,但是这些是我们构建的基石。使我们更加快速的开发。

怎样来组装一个基础的项目,我们在上一期已经讲完了,本期我们接着要完成一个基础项目框架,同时呢还应该有一个基础项目构建的思考。

1.怎么完成安全校验的登录

其实这个在上一季的项目中已经探讨完成了,这一季只是说老生重谈。甚至来讲,登录是一个简单的过程,却不是个容易的东西。

首先我们应该做到:可靠、安全、有效。详细说一下就是:传输过程加密,数据存储加密,信息服务器存放,前端单纯的展示。那么我们常规的处理手段有:

  • 登录密码传输前加密
  • 密文强效验
  • 用户信息缓存到session

具体的代码如下:

@Controller
@Api(description = "外层信息,无需Shiro接管,集成文件下载控制器")
public class MainController{@PostMapping(value = "/login", produces = MediaType.TEXT_HTML_VALUE)@ApiOperation(value = "/login", notes = "登录后台系统")public String login(@ApiParam(hidden = true) ModelMap map,@ApiParam(hidden = true) ShiroHttpServletRequest request,@ApiParam(value = "用户名不能为空,否则不允许登录", required = true) @RequestParam(value = "userLogin", required = false) String userLogin,@ApiParam(value = "用户密码不能为空且必须为16位小写MD5,否则不允许登录", required = true) @RequestParam(value = "userPass", required = false) String userPass) {User result = null;try {//1.得到SubjectSubject subject = SecurityUtils.getSubject();//2.调用登录方法UsernamePasswordToken token = new UsernamePasswordToken(userLogin, userPass);subject.login(token);//当这一代码执行时,就会自动跳入到AuthRealm中认证方法result = (User) subject.getPrincipal();subject.getSession().setAttribute("userInfo", result);return "redirect:/endSys/index";} catch (Exception e) {e.printStackTrace();LogE.getInstance(this.getClass()).logOutLittle(e.getMessage());map.addAttribute("msg", e.getMessage());return "login";}}@GetMapping(path = "logOut", produces = MediaType.TEXT_HTML_VALUE)@ApiOperation(value = "退出登录", notes = "退出登录,清空session")public String logOut() {Subject subject = SecurityUtils.getSubject();if (subject.isAuthenticated()) {subject.getSession().removeAttribute("userInfo");subject.logout(); // session 会销毁,在SessionListener监听session销毁,清理权限缓存}return "redirect:/";}
}public class ShiroRealm extends AuthorizingRealm {@Autowiredprivate UserServiceImpl userService;/** 登录信息和用户验证信息验证(non-Javadoc)* @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken user = (UsernamePasswordToken) token;LogE.getInstance(ShiroRealm.class).logOutLittle("开始登录====>\n用户为:" + user.getUsername());String userLogin = user.getUsername();char[] password = user.getPassword();User loginResult = null;try {loginResult = userService.login(userLogin, new String(password));} catch (Exception e) {e.printStackTrace();LogE.getInstance(ShiroRealm.class).logOutLittle("登录异常结束====>\n用户为:" + user.getUsername());throw new AuthenticationException(e.getMessage());}LogE.getInstance(ShiroRealm.class).logOutLittle("登录成功====>\n用户为:" + user.getUsername());return new SimpleAuthenticationInfo(loginResult, user.getPassword(), this.getName());}
}public class MyCredentialsMatcher extends SimpleCredentialsMatcher {/*** 密码比较方法,有自己的登录校验方法,故此绕过校验** @param token* @param info* @return*/@Overridepublic boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {return true;}
}复制代码

当然,其他的代码,都不是那么核心,我们主要是围绕着Shiro来阐述我们的登录。

为什么我们的登录和注销地址不要Shiro接管呢?因为无论在登录或注销的时候有没有用户,我们都会执行对应的操作来分别存放用户信息或者清除用户信息。

但是仅仅有这个就能完成登陆校验?错!错!错! 我们需要把shiro接管的页面都纳入管理范围内。也就会产生spring相关的设置,这些,在我们上一季都是有讲到过。但是上一季是XML配置,这一次我们是java配置。


@Configuration
public class ShiroConfig {@Beanpublic ShiroRealm realm() {ShiroRealm myShiroRealm = new ShiroRealm();MyCredentialsMatcher matcher = new MyCredentialsMatcher();myShiroRealm.setCredentialsMatcher(matcher); //设置解密规则return myShiroRealm;}//SecurityManager 是 Shiro 架构的核心,通过它来链接Realm和用户(文档中称之为Subject.)@Beanpublic DefaultSecurityManager securityManager() {DefaultSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(realm()); //将Realm注入到SecurityManager中。DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();sessionManager.setGlobalSessionTimeout(1800000);   //默认三十分钟//        Cookie cookie = new SimpleCookie();     //设置cookie
//        cookie.setName("sid");  //java默认值是JSESSIONID
//        cookie.setDomain("acheng1314.cn");  //cookie作用域
//        cookie.setMaxAge(1800); //cookie超时时间30分钟
//        cookie.setHttpOnly(true);
//
//        sessionManager.setSessionIdCookie(cookie);
//        sessionManager.setSessionIdCookieEnabled(true);//session会话验证
//        ExecutorServiceSessionValidationScheduler sessionValidationScheduler = new ExecutorServiceSessionValidationScheduler();
//        sessionValidationScheduler.setInterval(3600000);
//        sessionValidationScheduler.setSessionManager(sessionManager);
//
//        sessionManager.setSessionValidationScheduler(sessionValidationScheduler);
//        sessionManager.setSessionValidationSchedulerEnabled(true);securityManager.setSessionManager(sessionManager);    //此处已经自动持有DefaultWebSessionManagerreturn securityManager;}//在这里配置url访问规则@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();filterChainDefinitionMap.put("/logout", "logout");filterChainDefinitionMap.put("/favicon.ico", "anon");filterChainDefinitionMap.put("/static/*/**", "anon");//authc表示需要验证身份才能访问,还有一些比如anon表示不需要验证身份就能访问等。filterChainDefinitionMap.put("/druid/*/**", "authc");filterChainDefinitionMap.put("/endSys/*/**", "authc");filterChainDefinitionMap.put("/swagger-ui.html/*/**", "authc");shiroFilterFactoryBean.setLoginUrl("/login");shiroFilterFactoryBean.setSuccessUrl("/endSys/index");
//        shiroFilterFactoryBean.setUnauthorizedUrl("/403"); //这里设置403并不会起作用,参考http://www.jianshu.com/p/e03f5b54838cshiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}}复制代码

我们首先告诉spring框架这个是我们框架的设置,需要载入。 然后接着在这个设置里面配置对应的bean(ShiroRealm、DefaultSecurityManager、ShiroFilterFactoryBean)来实现相应的调度规则。

一些具体的细节,如:前端登录页面、数据库操作等等,请查阅github仓库代码或者访问码云

到目前这里,我们可以实现登录到系统首页了:http://localhost:8181/login

登录成功后,简单的主页如下:

登录成功后的

悄悄的告诉你,我后端主页使用了zDrag来实现网页内部窗体管理。

当然到了这里还是有点小问题,那就是我们用户信息过期后,我们点击菜单会产生内部窗体登录(登录成功后再点击菜单会回到正确界面)我们添加一个js方法就能解决这个小问题。

总结

这一期主要讨论了手脚脚需要的东西。

  • 项目基础依赖
  • 较为安全的登录

下期预告

下期目标是产生代码生成器和菜单树。


如果你认可我所做的事情,并且认为我做的事对你有一定的帮助,希望你也能打赏我一杯咖啡,谢谢。

支付宝捐赠

springBoot探索(2)——构建手脚架相关推荐

  1. SpringBoot | 用 IDEA构建第一个SpringBoot工程

    SpringBoot | 用 IDEA构建第一个SpringBoot工程 本文链接:http://blog.battcn.com/2018/04/20/springboot/v2-introducin ...

  2. Springboot 基于CXF构建WebService服务

    前言 最近因为系统需要接入了一个新的支付通道,一般来说都是使用RestApi 来接入,但是本次接入的支付通道为境外支付,使用的WebService,对于WS我们在实际业务中基本上不会用到,所以查阅了一 ...

  3. 小程序+springboot+vue技术构建分帐式多商户入驻商城系统开发,引入lombok简化项目代码

    网页设计中使用了三种语言:HTML.CSS和JavaScript.HTML和CSS一直是网页设计的基础,而JavaScript则被用于添加网站的动态视图. 在提供吸引人的UI/UX时,JavaScri ...

  4. DA LAO:SpringBoot讲述 快速构建微服务体系。

    在当今互联网时代,技术圈最火的名词大概就是微服务了.国内外的互联网技术会议上,但凡分享题目中包含"MicroService",不论内容质量如何,一定人山人海.摩肩接踵. 而今天分享 ...

  5. dubbo yml配置_利用springboot+dubbo,构建分布式微服务,全程注解开发(一)

    随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 一.先来一张图 说起 Dubbo,相信大家都不 ...

  6. 5分钟实现SpringBoot整合Dubbo构建分布式服务

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:jaycekon cnblogs.com/jaycekon/ ...

  7. springboot集成swagger2构建RESTful API文档

    在开发过程中,有时候我们需要不停的测试接口,自测,或者交由测试测试接口,我们需要构建一个文档,都是单独写,太麻烦了,现在使用springboot集成swagger2来构建RESTful API文档,可 ...

  8. 《SpringBoot揭秘 快速构建微服务体系》读后感(三)

    SpringApplication:SpringBoot程序启动的一站式解决方案 深入探索SpringApplication执行流程 因为书上的版本是1.2的,比较老,这里参考http://blog. ...

  9. SpringBoot 精通系列-构建一个RESTful Web 服务

    导语   现在越来越多的企业推荐使用的是RESTful风格来构建企业应用接口,那么什么是RESTful呢? 文章目录 什么是RESTful SpringBoot对于RESTful有哪些支持 快速实例 ...

最新文章

  1. Android中与Intent相关的还有,Android中Intent的相关用法
  2. iOS标准时间与时间戳相互转换
  3. 这半年来的飞秋官网磕磕碰碰
  4. 无公网ip远程访问调试-内网穿透工具
  5. (c语言)求满足表达式1+2+3+.......+n<=1000的最大的n
  6. 怎么一秒钟给微信头像戴上圣诞帽,我教你啊
  7. 好的网站收藏---长期更新---长期更新---长期更新---长期更新--
  8. 2016年10月20日 .NET Core 1.0.2 更新
  9. python学习之老男孩python全栈第九期_day012知识点总结
  10. eclipse汉化包安装步骤
  11. wd移动硬盘不能识别_wd移动硬盘读不出来怎么办
  12. APP推广渠道ROI预测
  13. ShellServiceObjectDelayLoad中的webcheck疑问
  14. python dataframe是什么_【Python-pandas】核心数据结构DataFrame介绍
  15. Origin画图标签常见语法
  16. 【C++】VAL树的旋转(左单旋、右单旋、双旋)
  17. centos6下安装配置NFS
  18. 网站流量排名分析:SEO如何诊断排名不佳的页面!
  19. CoralGloba珊瑚跨境的“全银行通道结算”,是创举还是噱头?
  20. 弘辽科技:淘宝销量数据从哪查?销量怎么提升?

热门文章

  1. poj 2485 Highways
  2. 关于数组集合之间的转换
  3. 清除NT Kernel System占用80端口
  4. linux 内核调整相关参数
  5. .net 4.0下载
  6. 话里话外:论持续跟踪和及时反馈
  7. 剑指offer5 从尾到头打印链表
  8. IBM 存储RAID硬盘离线和数据库损坏的恢复处理办法
  9. eclipse hibernate配置文件(*.hbm.xml)加上自动提示功能
  10. Android开发之dp转像素,像素转换为dp工具类,详细代码,带有源文件下载地址。...