一个spring boots项目

https://www.cnblogs.com/zhangbin1989/p/9473292.html

https://www.cnblogs.com/zhangbin1989/p/9473292.html

返回主页
丰极
内心纯洁的人前途无量!

博客园
首页
新随笔
联系
管理
订阅
订阅

随笔 - 13 文章 - 0 评论 - 5
从零开始搭建SpringBoot项目
一、新建springboot项目
1、

new–>Project–>Spring Initralizr
Group:com.zb
Artifact:zbook
springboot version:2.0.4
2、

org.springframework.boot spring-boot-starter

改成

org.springframework.boot spring-boot-starter-web

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;
@RestController
public 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

登录

用户登录

登录

2、写一个LoginController

package com.zb.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LoginController {
@RequestMapping("/login")
public String login(){
return “login”;
}
}

3、加依赖

org.springframework.boot spring-boot-starter-thymeleaf

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: 8080
mybatis:
type-aliases-package: com.zb.mapper
mapper-locations: classpath:mapping/*.xml

pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
logging:
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"?>
    <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->
    <table tableName="role_permission" domainObjectName="RolePermission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
</context>

5、在pom里面添加plugin

        <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 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;

@Controller
public 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

用户管理
<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>

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 result = userService.selectAll(pageNum, pageSize);
model.addAttribute(“users”, result.getList());
model.addAttribute(“pageInfo”, result);
return “userlist”;
}

页面修改:

    此时目录

    此时重启,输入 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;

    @Controller
    public 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、修改页面让页面显示用户名和退出

    退出

    您好,

    六、权限

    权限管理我们使用现在比较流行的shiro,原理就不说了,直接说怎么使用
    1、加依赖包

        <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的规则和访问权限。
    */
    @Configuration
    public 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 selectRoleByUserId(@Param(“userId”) int userId);

    @Select(“select * from permission where id in (select permission_id from role_permission where role_id = #{roleId})”)
    List 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>

    至此,权限就加好了
    标签: Java, springboot, shiro, thymleaf, mybatis
    好文要顶 关注我 收藏该文
    丰极
    关注 - 0
    粉丝 - 6
    +加关注
    4
    0
    « 上一篇: Java1.8的HashMap源码解析
    » 下一篇: springboot集成springDataJpa
    posted @ 2018-08-14 11:03 丰极 阅读(17866) 评论(5) 编辑 收藏

    Post Comment
    #1楼 2019-08-05 16:22 | 酥酥糖
    刚学习springboot,能不能发一份源码学习一下啊。1293225879@qq.com,谢谢。
    支持(0) 反对(0)

    #2楼 2019-08-22 13:24 | 小小小白白白小
    您好 能发一份源码学习吗1425642758@qq.com
    支持(0) 反对(0)

    #3楼 2019-10-09 13:09 | oneForce
    你好,刚学习springboot,上面示例源码发我一份学习下,谢谢了。1075436220@qq.com
    支持(0) 反对(0)

    #4楼 2019-10-14 11:11 | fire-kylin
    你好 在学习springboot 求一份上面的源码吧 谢谢了。1512002938@qq.com
    支持(0) 反对(0)

    #5楼 2019-10-18 16:17 | Shawn_0108
    您好,在学习springboot 求一份上面的源码吧 谢谢了。Shawn_0108@163.com
    支持(0) 反对(0)

    刷新评论刷新页面返回顶部
    注册用户登录后才能发表评论,请 登录 或 注册, 访问 网站首页。
    【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
    【活动】京东云服务器_云主机低于1折,低价高性能产品备战双11
    【推荐】天翼云双十一提前开抢,1核1G云主机3个月仅需59元
    【活动】魔程社区技术沙龙训练营—大数据主题专场等你来报名
    【优惠】腾讯云 11.1 1智惠上云,爆款提前购与双11活动同价
    【福利】个推四大热门移动开发SDK全部免费用一年,限时抢!
    相关博文:
    · 访客系统项目的总结
    · shiro的使用1 简单的认证
    · Shiro入门之一 -------- Shiro权限认证与授权
    · Spring整合Shiro
    · 详解登录认证及授权–Shiro系列(一)
    » 更多推荐…
    最新 IT 新闻:
    · U盘专利即将过期 中国朗科公司发明
    · 芯片/操作系统/生态计划齐发布,科大讯飞全产品AI化加速
    · 1024特别版:向“程序媛们”致敬!
    · 发布一年后 Android Pie 普及率突破五分之一
    · WeWork新任董事长邮件曝光:必须裁员,现金流转正是当务之急
    » 更多新闻…
    昵称: 丰极
    园龄: 1年3个月
    粉丝: 6
    关注: 0
    +加关注
    < 2019年10月 >
    日 一 二 三 四 五 六
    29 30 1 2 3 4 5
    6 7 8 9 10 11 12
    13 14 15 16 17 18 19
    20 21 22 23 24 25 26
    27 28 29 30 31 1 2
    3 4 5 6 7 8 9
    搜索

    My Tags

    Java(10)
    springboot(2)
    springdatajpa(1)
    thymleaf(1)
    定时任务(1)
    性能调优(1)
    mybatis(1)
    shiro(1)
    spring(1)
    

    随笔档案

    2018年12月(1)
    2018年10月(3)
    2018年9月(4)
    2018年8月(1)
    2018年7月(3)
    2018年6月(1)
    

    Recent Comments

    1. Re:从零开始搭建SpringBoot项目
    --Shawn_0108
    2. Re:从零开始搭建SpringBoot项目
    你好 在学习springboot 求一份上面的源码吧 谢谢了。1512002938@qq.com
    --fire-kylin
    3. Re:从零开始搭建SpringBoot项目
    你好,刚学习springboot,上面示例源码发我一份学习下,谢谢了。1075436220@qq.com
    --oneForce
    4. Re:从零开始搭建SpringBoot项目
    您好 能发一份源码学习吗1425642758@qq.com
    --小小小白白白小
    5. Re:从零开始搭建SpringBoot项目
    刚学习springboot,能不能发一份源码学习一下啊。1293225879@qq.com,谢谢。
    --酥酥糖
    

    Top Posts

    1. 从零开始搭建SpringBoot项目(17865)
    2. Java定时任务(11869)
    3. Java性能调优(1515)
    4. Springboot集成Swagger2(393)
    5. Java1.8的HashMap源码解析(387)
    

    推荐排行榜

    1. 从零开始搭建SpringBoot项目(4)
    2. Java定时任务(2)
    

    Copyright © 2019 丰极
    Powered by .NET Core 3.0.0 on Linux

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

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

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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值