一、新建springboot我的项目

1、

new-->Project-->Spring Initralizr
Group:com.zb
Artifact:zbook
springboot version:2.0.4

2、

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

改成

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

3、此时我的项目构造

maven clean一下,右键ZbookApplication运行,我的项目就跑起来了,就是这么简略,真正做到了开箱即用。

二、RestFul Api接口

1、在controller包下新建HomeController

package com.zb.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HomeController {    @RequestMapping("/")    public String home(){        return "Hello, Zbook!";    }}

注:RestController和Controller注解的区别是:RestController是返回的内容就是返回的内容,相当于加个@ResponseBody,而controller个别是返回的页面

此时关上网页,输出 http://localhost:8080/
就会看到Hello,Zbook!

三、集成Thymleaf

1、

下面的能够当作是提供服务的接口,假如咱们要开发一个web利用,springboot默认是集成的thymleaf。
springboot是约定大于配置的,咱们来看看对于thymleaf的约定
(1)默认动态文件(js,css,jpg等)放在resources上面的static文件夹上面
(2)页面文件放在templates文件夹上面
咱们采纳bootstrap来渲染页面,如下图

login.html<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>    <meta charset="UTF-8" />    <title>登录</title>    <link href="/css/bootstrap.min.css" rel="stylesheet"></head><body>    <div class="container">            <form action="login_in" method="post" class="form-horizontal" role="form" >                <div class="form-group">                    <h2 class="col-sm-offset-5 col-sm-4">用户登录</h2>                </div>                <div class="form-group">                    <label for="username" class="col-sm-offset-3 col-sm-2 control-label">用户名:</label>                    <div class="col-sm-3">                        <input type="text" class="form-control" id="username" name="username" placeholder="请输出用户名" />                    </div>                </div>                <div class="form-group">                    <label for="password" class="col-sm-offset-3 col-sm-2 control-label">明码:</label>                    <div class="col-sm-3">                        <input type="text" class="form-control" id="password" name="password" placeholder="请输出明码" />                    </div>                </div>                <div class="form-group">                    <div class="col-sm-offset-5 col-sm-4">                        <button type="submit" class="btn btn-default">登录</button>                    </div>                </div>            </form>    </div>    <script src="/js/jquery-2.2.1.min.js"></script>    <script src="/js/bootstrap.min.js"></script></body></html>

2、写一个LoginController

package com.zb.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class LoginController {    @RequestMapping("/login")    public String login(){        return "login";    }}

3、加依赖

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

4、

重启, http://localhost:8080/login
则会看到登录页面

四、集成mybatis

1、

springboot的配置文件分为两种:application.properties和application.yml
咱们把它改成application.yml这种更直观

spring:  application:    name: myspringboot  output:    ansi:      enabled: always  profiles:    active: dev  thymeleaf:    encoding: UTF-8    prefix: classpath:/templates/server:  tomcat:    uri-encoding: UTF-8    max-connections: 500    min-spare-threads: 25    max-threads: 300    accept-count: 200  port: 8080mybatis:  type-aliases-package: com.zb.mapper  mapper-locations: classpath:mapping/*.xmlpagehelper:  helper-dialect: mysql  reasonable: true  support-methods-arguments: true  params: count=countSqllogging:  level:    com.zb.mapper: debug---#开发配置spring:  profiles: dev  datasource:    url: jdbc:mysql://localhost:3306/zb_db?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&useSSL=false    username: root    password: 123456    driver-class-name: com.mysql.jdbc.Driver    type: com.alibaba.druid.pool.DruidDataSource    filters: stat    maxActive: 20    initialSize: 1    maxWait: 60000    minIdle: 1    timeBetweenEvictionRunsMillis: 60000    minEvictableIdleTimeMillis: 300000    validationQuery: select 'x'    testWhileIdle: true    testOnBorrow: false    testOnReturn: false    poolPreparedStatements: true    maxOpenPreparedStatements: 20

2、增加依赖

        <dependency>            <groupId>org.mybatis.spring.boot</groupId>            <artifactId>mybatis-spring-boot-starter</artifactId>            <version>1.3.2</version>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>        </dependency>        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid</artifactId>            <version>RELEASE</version>        </dependency><!-- 分页插件 -->        <dependency>            <groupId>com.github.pagehelper</groupId>            <artifactId>pagehelper-spring-boot-starter</artifactId>            <version>1.2.3</version>        </dependency>

3、建表

CREATE datebase zb_db;
CREATE TABLE `user` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `username` varchar(255) DEFAULT NULL,  `password` varchar(255) DEFAULT NULL,  `mobile` varchar(255) DEFAULT NULL,  `email` varchar(255) DEFAULT NULL,  `sex` varchar(255) DEFAULT NULL,  `nickname` varchar(255) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(1, 'admin', '123456', '13918891675','mmc@163.com', '男', '管理员');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(2, 'lisi2', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(3, 'lisi3', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(4, 'lisi4', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(5, 'lisi5', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(6, 'lisi6', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(7, 'lisi7', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(8, 'lisi8', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(9, 'lisi9', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(10, 'lisi10', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(11, 'lisi11', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(12, 'lisi12', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(13, 'lisi13', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(14, 'lisi14', '123456', '13918891675','mmc@163.com', 'm', 'lisi1');

4、用mybatisgenerator主动生成文件

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE generatorConfiguration        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration>    <!-- 数据库驱动:抉择你的本地硬盘下面的数据库驱动包-->    <classPathEntry  location="C:\Users\DELL\Downloads\mysql-connector-java-5.1.22-bin.jar"/>    <context id="DB2Tables"  targetRuntime="MyBatis3">        <commentGenerator>            <property name="suppressDate" value="true"/>            <!-- 是否去除主动生成的正文 true:是 : false:否 -->            <property name="suppressAllComments" value="true"/>        </commentGenerator>        <!--数据库链接URL,用户名、明码 -->        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1/zb_db" userId="root" password="123456">        </jdbcConnection>        <javaTypeResolver>            <property name="forceBigDecimals" value="false"/>        </javaTypeResolver>        <!-- 生成模型的包名和地位-->        <javaModelGenerator targetPackage="com.zb.model" targetProject="src/main/java">            <property name="enableSubPackages" value="true"/>            <property name="trimStrings" value="true"/>        </javaModelGenerator>        <!-- 生成映射文件的包名和地位-->        <sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources">            <property name="enableSubPackages" value="true"/>        </sqlMapGenerator>        <!-- 生成DAO的包名和地位-->        <javaClientGenerator type="XMLMAPPER" targetPackage="com.zb.mapper" targetProject="src/main/java">            <property name="enableSubPackages" value="true"/>        </javaClientGenerator>        <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->        <table tableName="role_permission" domainObjectName="RolePermission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>    </context></generatorConfiguration>

5、在pom外面增加plugin

<!-- mybatis generator 主动生成代码插件 -->            <plugin>                <groupId>org.mybatis.generator</groupId>                <artifactId>mybatis-generator-maven-plugin</artifactId>                <version>1.3.2</version>                <configuration>                    <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>                    <overwrite>true</overwrite>                    <verbose>true</verbose>                </configuration>            </plugin>

6、用mvn mybatis-generator:generate -e命令生成文件

此时目录构造

7、写dao和service,controller,mapper

mapper减少了几个办法

@Select("Select * from user")List<User> selectAll();@Select("Select * from user where username = #{username} and password = #{password}")User selectByUsernamePass(@Param("username") String username, @Param("password") String password);@Select("Select * from user where username = #{username}")User selectByUsername(@Param("username") String username);

dao和service都是失常调用,上面是controller

package com.zb.controller;import com.github.pagehelper.PageInfo;import com.zb.model.User;import com.zb.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;@Controllerpublic class UserController {    @Autowired    private UserService userService;    @RequestMapping("/user")    @ResponseBody    public User getUserById(int id){        User user = userService.selectByPrimaryKey(id);        return user;    }    @RequestMapping("/userlist")    public String getUserList(Model model, PageInfo pageInfo){        int pageNum  = (pageInfo.getPageNum() == 0)? 1 : pageInfo.getPageNum();        int pageSize  = (pageInfo.getPageSize() == 0)? 10 : pageInfo.getPageSize();        PageInfo<User> result = userService.selectAll(pageNum, pageSize);        model.addAttribute("users", result.getList());        model.addAttribute("pageInfo", result);        return "userlist";    }    @RequestMapping("/userdelete")    public String userdelete(int id){        userService.deleteByPrimaryKey(id);        return "redirect:/userlist";    }    @RequestMapping("/useredit")    public String useredit(int id, Model model){        User user = userService.selectByPrimaryKey(id);        model.addAttribute("user", user);        return "useredit";    }    @RequestMapping(value = "/userupdateoradd", method = RequestMethod.POST)    public String userUpdateOrAdd(User user){        if(user.getId() == 0){            userService.insertSelective(user);        } else {            userService.updateByPrimaryKeySelective(user);        }        return "redirect:/userlist";    }}

页面userlist.html

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>    <meta charset="UTF-8" />    <title>用户治理</title>    <link href="/css/bootstrap.min.css" rel="stylesheet"></head><body><div class="container">    <div>        <nav class="navbar navbar-default" role="navigation">            <div class="container-fluid">                <div>                    <ul  class="nav navbar-nav" >                        <li><a href="/userlist">用户治理</a></li>                        <li><a href="#">书籍治理</a></li>                    </ul>                </div>            </div>        </nav>    </div>    <div>        <h2>用户治理</h2>        <table width="100%" border="0" cellpadding="0" cellspacing="0" class="table_list">            <thead>            <tr>                <th width="20%">编号</th>                <th width="20%">用户名</th>                <th width="20%">电子邮箱</th>                <th width="20%">手机</th>                <th width="20%">操作</th>            </tr>            </thead>            <tbody>            <tr th:each="user:${users}">                <td height="40px"><a th:text="${user.id}" data-toggle="modal" data-target="#myModal" onclick="values(this)"></a></td>                <td th:text="${user.username}"></td>                <td th:text="${user.email}"></td>                <td th:text="${user.mobile}"></td>                <td><a href="#" class="delete_a" th:value="${user.id}">删除</a></td>            </tr>            </tbody>        </table>    </div></div><script src="/js/jquery-2.2.1.min.js"></script><script src="/js/bootstrap.min.js"></script></body></html>

8,在ZbookApplication上加上注解扫描

@ComponentScan(basePackages = {"com.zb"})@MapperScan("com.zb.mapper")

9、顺便把分页加上(依赖包之前曾经加了)

service层

    @Override    public PageInfo<User> selectAll(int pageNum, int pageSize) {        PageHelper.startPage(pageNum, pageSize);        List<User> users = userDao.selectAll();        PageInfo<User> pageInfo = new PageInfo<>(users);        return pageInfo;    }

controller层

public String getUserList(Model model, PageInfo pageInfo){        int pageNum  = (pageInfo.getPageNum() == 0)? 1 : pageInfo.getPageNum();        int pageSize  = (pageInfo.getPageSize() == 0)? 10 : pageInfo.getPageSize();        PageInfo<User> result = userService.selectAll(pageNum, pageSize);        model.addAttribute("users", result.getList());        model.addAttribute("pageInfo", result);        return "userlist";    }

页面批改:

<div id="example" style="text-align: center"> <ul id="pageLimit"></ul> </div><input type="hidden" id="pageNum" name="pageNum" th:value="${pageInfo.pageNum}" /><input type="hidden" id="pages" name="pages" th:value="${pageInfo.pages}" />
<script src="/js/bootstrap-paginator.min.js"></script><script>    $('#pageLimit').bootstrapPaginator({        currentPage: $("#pageNum").val(),        totalPages: $("#pages").val(),        size: "normal",        bootstrapMajorVersion: 3,        alignment: "right",        numberOfPages: 5,        itemTexts: function (type, page, current) {            switch (type) {                case "first": return "首页";                case "prev": return "上一页";                case "next": return "下一页";                case "last": return "末页";                case "page": return page;            }        },        onPageClicked: function (event, originalEvent, type, page){//给每个页眉绑定一个事件,其实就是ajax申请,其中page变量为以后点击的页上的数字。            window.location.href = "userlist?pageNum=" + page;        }    });    $(function(){        $(".delete_a").click(function(){            var userId=$(this).attr("value");            if(confirm("确认删除吗?")){                window.location.href="/userdelete?id=" + userId;                return ;            }        });    });</script>

此时目录

此时重启,输出 http://localhost:8080/userlist
就会看到user列表,也能够分页。

五、简略登录,用filter实现

1、

package com.zb.filter;import com.zb.model.User;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.IOException;@WebFilter(filterName = "sessionFilter",urlPatterns = {"/*"})public class SessionFilter implements Filter {    String NO_LOGIN = "您还未登录";    String[] includeUrls = new String[]{"/login","/login_in"};    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest)servletRequest;        HttpServletResponse response = (HttpServletResponse)servletResponse;        HttpSession session = request.getSession();        String url = request.getRequestURI();        boolean needFilter = isNeedFilter(url);        //动态资源放行        if(url.endsWith(".css")||url.endsWith(".js")||url.endsWith(".jpg")                ||url.endsWith(".gif")||url.endsWith(".png")){            filterChain.doFilter(servletRequest, servletResponse);            return;        }        if(!needFilter){            filterChain.doFilter(servletRequest, servletResponse);        } else {            User user = (User)session.getAttribute(session.getId());            if(user != null){                filterChain.doFilter(servletRequest, servletResponse);            } else {                String requestType = request.getHeader("X-Requested-With");                //判断是否是ajax申请                if(requestType!=null && "XMLHttpRequest".equals(requestType)){                    response.getWriter().write(this.NO_LOGIN);                }else{                    //重定向到登录页(须要在static文件夹下建设此html文件)                    response.sendRedirect(request.getContextPath()+"/login");                }                return;            }        }    }    public boolean isNeedFilter(String uri) {        for (String includeUrl : includeUrls) {            if(includeUrl.equals(uri)) {                return false;            }        }        return true;    }    @Override    public void destroy() {    }}

2、在ZbookApplication上加注解

@ServletComponentScan

3、在LoginController下写登录逻辑

package com.zb.controller;import com.zb.model.User;import com.zb.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;@Controllerpublic class LoginController {    @Autowired    private UserService userService;    @RequestMapping("/login")    public String login(){        return "login";    }    @RequestMapping(value = "/login_in", method = RequestMethod.POST)    public String login_in(User user, HttpServletRequest request, Model model){        User user1 = userService.validateUser(user.getUsername(), user.getPassword());        if(user1 == null){            return "login";        }                HttpSession session = request.getSession();        session.setAttribute(session.getId(), user1);        return "redirect:/userlist";    }    @RequestMapping("/logout")    public String logout(HttpServletRequest request){        request.getSession().removeAttribute(request.getSession().getId());        return "login";    }}

当初就能够简略的登录了

4、批改页面让页面显示用户名和退出

<div>    <a href="logout" style="display: inline-block; float: right">退出</a>    <p th:text="${#httpSession.getAttribute(#httpSession.getId()).username}" style="display: inline-block; float: right"></p>    <p style="display: inline-block; float: right">您好,</p></div>

六、权限

权限治理咱们应用当初比拟风行的shiro,原理就不说了,间接说怎么应用

1、加依赖包

<!--shiro权限-->        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-core</artifactId>            <version>1.2.4</version>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-web</artifactId>            <version>1.2.4</version>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-spring</artifactId>            <version>1.2.4</version>        </dependency>        <dependency>            <groupId>com.github.theborakompanioni</groupId>            <artifactId>thymeleaf-extras-shiro</artifactId>            <version>2.0.0</version>        </dependency>

2、建表

shiro须要5张表:用户、角色、权限、用户角色关联表,角色权限关联表
用户表已建设,当初续建4张表

CREATE TABLE `role` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `rolename` varchar(255) DEFAULT NULL,  `description` varchar(255) DEFAULT NULL,  `status` varchar(255) DEFAULT NULL,  `create_time` DATE DEFAULT NULL,  `update_time` DATE DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE `permission` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `permissionname` varchar(255) DEFAULT NULL,  `resourceType` varchar(255) DEFAULT NULL,  `url` varchar(255) DEFAULT NULL,  `permission` varchar(255) DEFAULT NULL,  `status` varchar(255) DEFAULT NULL,  `create_time` DATE DEFAULT NULL,  `update_time` DATE DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE `user_role` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `user_id` varchar(255) DEFAULT NULL,  `role_id` varchar(255) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE `role_permission` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `role_id` varchar(255) DEFAULT NULL,  `permission_id` varchar(255) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (1, 'admin', '管理员', 'use', '2018-08-10', '2018-08-10');insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (2, 'manage', '经理', 'use', '2018-08-10', '2018-08-10');insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (3, 'user', '普通用户', 'use', '2018-08-10', '2018-08-10');INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (1,'用户治理','menu', 'userlist','user:list','use','2018-08-10', '2018-08-10');INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (2,'用户批改','menu', 'useredit','user:edit','use','2018-08-10', '2018-08-10');INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (3,'用户删除','menu', 'userdelete','user:delete','use','2018-08-10', '2018-08-10');INSERT INTO `user_role` (id, user_id, role_id) VALUES (1, 1 ,1);INSERT INTO `user_role` (id, user_id, role_id) VALUES (2, 1 ,2);INSERT INTO `user_role` (id, user_id, role_id) VALUES (3, 1 ,3);INSERT INTO `user_role` (id, user_id, role_id) VALUES (4, 2 ,2);INSERT INTO `user_role` (id, user_id, role_id) VALUES (5, 3 ,3);INSERT INTO `user_role` (id, user_id, role_id) VALUES (6, 4 ,3);INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (1, 1, 1);INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (2, 1, 2);INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (3, 1, 3);INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (4, 2, 1);INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (5, 2, 2);INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (6, 3, 1);

3、加载bean

package com.zb.shiro;import java.util.LinkedHashMap;import java.util.Map;import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;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.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.filter.DelegatingFilterProxy;/** * Shiro 配置 * Apache Shiro 外围通过 Filter 来实现,就如同SpringMvc 通过DispachServlet 来主控制一样。 既然是应用 Filter 个别也就能猜到,是通过URL规定来进行过滤和权限校验,所以咱们须要定义一系列对于URL的规定和拜访权限。 */@Configurationpublic class ShiroConfiguration {    private static final Logger logger = LoggerFactory.getLogger(ShiroConfiguration.class);    @Bean    public FilterRegistrationBean delegatingFilterProxy(){        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();        DelegatingFilterProxy proxy = new DelegatingFilterProxy();        proxy.setTargetFilterLifecycle(true);        proxy.setTargetBeanName("shiroFilter");        filterRegistrationBean.setFilter(proxy);        return filterRegistrationBean;    }    /**     * ShiroFilterFactoryBean 解决拦挡资源文件问题。     * 留神:独自一个ShiroFilterFactoryBean配置是或报错的,认为在     * 初始化ShiroFilterFactoryBean的时候须要注入:SecurityManager     *     Filter Chain定义阐明     1、一个URL能够配置多个Filter,应用逗号分隔     2、当设置多个过滤器时,全副验证通过,才视为通过     3、局部过滤器可指定参数,如perms,roles     *     */    @Bean("shiroFilter")    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){        logger.info("ShiroConfiguration.shirFilter()");        ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();        // 必须设置 SecurityManager        shiroFilterFactoryBean.setSecurityManager(securityManager);        //拦截器.        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();        //配置退出过滤器,其中的具体的退出代码Shiro曾经替咱们实现了        filterChainDefinitionMap.put("/logout", "logout");        filterChainDefinitionMap.put("/*/*.js", "anon");        filterChainDefinitionMap.put("/*/*.css", "anon");        filterChainDefinitionMap.put("/login_in", "anon");        filterChainDefinitionMap.put("/login", "anon");        //<!-- 过滤链定义,从上向下程序执行,个别将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;        //<!-- authc:所有url都必须认证通过才能够拜访; anon:所有url都都能够匿名拜访-->        filterChainDefinitionMap.put("/**", "authc");        // 如果不设置默认会主动寻找Web工程根目录下的"/login.jsp"页面        shiroFilterFactoryBean.setLoginUrl("/login");        // 登录胜利后要跳转的链接        shiroFilterFactoryBean.setSuccessUrl("/userlist");        //未受权界面;        shiroFilterFactoryBean.setUnauthorizedUrl("/login");        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);        return shiroFilterFactoryBean;    }    @Bean    public SecurityManager securityManager(){        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();        securityManager.setRealm(myShiroRealm());        return securityManager;    }    @Bean    public MyShiroRealm myShiroRealm(){        MyShiroRealm myShiroRealm = new MyShiroRealm();        return myShiroRealm;    }    /**     *  开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描应用Shiro注解的类,并在必要时进行平安逻辑验证     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此性能     * @return     */    @Bean    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();        advisorAutoProxyCreator.setProxyTargetClass(true);        return advisorAutoProxyCreator;    }    /**     * 开启aop注解反对     * @param securityManager     * @return     */    @Bean    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);        return authorizationAttributeSourceAdvisor;    }    @Bean    public ShiroDialect shiroDialect() {        return new ShiroDialect();    }}

4、写Realm

package com.zb.shiro;import com.zb.model.Permission;import com.zb.model.Role;import com.zb.model.User;import com.zb.service.UserService;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.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.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.annotation.Resource;/** *  身份校验外围类; * * @version v.0.1 */public class MyShiroRealm extends AuthorizingRealm{    private static final Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);    private static String SALT = "mySlalt";    @Resource    private UserService userService;    /**     * 认证信息.(身份验证)     * :     * Authentication 是用来验证用户身份     * @param token     * @return     * @throws AuthenticationException     */    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {        logger.info("MyShiroRealm.doGetAuthenticationInfo()");        //获取用户的输出的账号.        String username = (String)token.getPrincipal();        //通过username从数据库中查找 User对象,如果找到,没找到.        //理论我的项目中,这里能够依据理论状况做缓存,如果不做,Shiro本人也是有工夫距离机制,2分钟内不会反复执行该办法        User user = userService.selectByUsername(username);        logger.info("----->>userInfo=" + user.toString());        if(user == null){            return null;        }       /*        * 获取权限信息:这里没有进行实现,        * 请自行依据UserInfo,Role,Permission进行实现;        * 获取之后能够在前端for循环显示所有链接;        */        //userInfo.setPermissions(userService.findPermissions(user));        userService.findRoleAndPermissions(user);        //账号判断;        //加密形式;        //交给AuthenticatingRealm应用CredentialsMatcher进行明码匹配,如果感觉人家的不好能够自定义实现        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(                user, //用户名                user.getPassword(), //明码                ByteSource.Util.bytes(user.getUsername() + SALT),//salt=username+salt                getName()  //realm name        );        //明文: 若存在,将此用户寄存到登录认证info中,无需本人做明码比照,Shiro会为咱们进行明码比照校验//      SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(//           userInfo, //用户名//           userInfo.getPassword(), //明码//             getName()  //realm name//      );        return authenticationInfo;    }    /**     * 此办法调用  hasRole,hasPermission的时候才会进行回调.     *     * 权限信息.(受权):     * 1、如果用户失常退出,缓存主动清空;     * 2、如果用户非正常退出,缓存主动清空;     * 3、如果咱们批改了用户的权限,而用户不退出零碎,批改的权限无奈立刻失效。     * (须要手动编程进行实现;放在service进行调用)     * 在权限批改后调用realm中的办法,realm曾经由spring治理,所以从spring中获取realm实例,     * 调用clearCached办法;     * :Authorization 是受权访问控制,用于对用户进行的操作受权,证实该用户是否容许进行以后操作,如拜访某个链接,某个资源文件等。     * @param principals     * @return     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {        logger.info("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();        User userInfo  = (User)principals.getPrimaryPrincipal();        ///在认证胜利之后返回.        //设置角色信息.        //反对 Set汇合,        //用户的角色对应的所有权限        for(Role role:userInfo.getRoleList()){            authorizationInfo.addRole(role.getRolename());            for(Permission p:role.getPermissionList()){                authorizationInfo.addStringPermission(p.getPermission());            }        }        return authorizationInfo;    }}

5、主动生成那四个表的代码,加相干的

@Select("select * from Role where id in (select role_id from user_role where user_id = #{userId})")List<Role> selectRoleByUserId(@Param("userId") int userId);
@Select("select * from permission where id in (select permission_id from role_permission where role_id = #{roleId})")List<Permission> selectPermissionIdByRoleId(@Param("roleId") int roleId);

6、批改LoginController

批改登录办法

    @RequestMapping(value = "/login_in", method = RequestMethod.POST)    public String login_in(User user, HttpServletRequest request, Model model){        User user1 = userService.validateUser(user.getUsername(), user.getPassword());        if(user1 == null){            return "login";        }        // (1) session//        HttpSession session = request.getSession();//        session.setAttribute(session.getId(), user1);//        return "redirect:/userlist";        // (3) shiro        String msg ;        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());        token.setRememberMe(true);        Subject subject = SecurityUtils.getSubject();        try {            subject.login(token);            if (subject.isAuthenticated()) {                //shiro 的session和request的session封装的是一个,就是说两个都能够//                request.getSession().setAttribute(request.getSession().getId(),user);                subject.getSession().setAttribute(subject.getSession().getId(),user);                return "redirect:/userlist";            } else {                return "login";            }        } catch (IncorrectCredentialsException e) {            msg = "登录明码谬误. Password for account " + token.getPrincipal() + " was incorrect.";            model.addAttribute("message", msg);            System.out.println(msg);        } catch (ExcessiveAttemptsException e) {            msg = "登录失败次数过多";            model.addAttribute("message", msg);            System.out.println(msg);        } catch (LockedAccountException e) {            msg = "帐号已被锁定. The account for username " + token.getPrincipal() + " was locked.";            model.addAttribute("message", msg);            System.out.println(msg);        } catch (DisabledAccountException e) {            msg = "帐号已被禁用. The account for username " + token.getPrincipal() + " was disabled.";            model.addAttribute("message", msg);            System.out.println(msg);        } catch (ExpiredCredentialsException e) {            msg = "帐号已过期. the account for username " + token.getPrincipal() + "  was expired.";            model.addAttribute("message", msg);            System.out.println(msg);        } catch (UnknownAccountException e) {            msg = "帐号不存在. There is no user with username of " + token.getPrincipal();            model.addAttribute("message", msg);            System.out.println(msg);        } catch (UnauthorizedException e) {            msg = "您没有失去相应的受权!" + e.getMessage();            model.addAttribute("message", msg);            System.out.println(msg);        }        return "login";    }    @RequestMapping("/logout")    public String logout(HttpServletRequest request){//        request.getSession().removeAttribute(request.getSession().getId());        SecurityUtils.getSubject().getSession().removeAttribute(SecurityUtils.getSubject().getSession().getId());        return "login";    }

7、批改contorller办法,或者在页面外面加权限

@RequestMapping("/userlist")@RequiresPermissions("user:list")
@RequestMapping("/userdelete")@RequiresPermissions("user:delete")

这种或者
页面上

<shiro:hasPermission name="user:delete"></shiro:hasPermission>

至此,权限就加好了

欢送关注微信公众号:丰极,回复:springboot1,有我的项目的github地址。