编程语言
首页 > 编程语言> > Marco's Java【Shiro进阶(一) 之 Shiro+SMM集成Maven项目串烧篇(上)】

Marco's Java【Shiro进阶(一) 之 Shiro+SMM集成Maven项目串烧篇(上)】

作者:互联网

前言

经过前面阶段的学习,我们已经对Spring、SpringMVC、Maven非常熟悉了,Shiro也入了个门,可能单个知识点理解起来没有那么困难,但是一旦将所有的东西做"串烧",就感觉没啥头绪?
那么本节开始的Shiro+SMM集成项目串烧的上中下篇呢,我们就将这所有的知识结合起来,串成一串,做一个"小项目",本"项目"呢意不在有多复杂多难,比较适合不熟悉集成流程的朋友,所以大家有选择性的观阅就Ok啦。废话不多说,那我们就开始吧~

构建数据库及Maven项目初始搭建

项目搭建的初始阶段,我们需要思考的第一个问题就是,我有哪些数据可以操作?这些数据该怎么划分并体现在数据库中?哪些数据该规划在哪张表中?每张表与表之间是什么关系?每张表的赋能是什么?等等,那么在脑海中首先得有一个草图,最好是能够在纸上打个草稿再上手,这样项目搭建之后有了清晰的思路会比空手上战场要容易的多,古话说得好,“知己知彼,百战百胜”,编程也不例外。

那么本节就从这破解项目的"降龙十八式"的第一式开始吧!
第一式:创建Maven Web项目
我们第一步要做的事很简单,创建一个Maven的Web项目,这里我不弄复杂了,因此没有像之前一样按MVC来分配拆分多个项目,因为暂时也还没有涉及到分布式,Maven的Web搭建准备工作不熟悉的朋友可以参考博文
Marco’s Java【Maven入门(三) 之 Eclipse下创建Maven的WEB项目及创建后常见问题的解决方案】
在这里插入图片描述

第二式:准备数据库
我们这里一共准备了5张表,由于权限、角色和用户之间都是多对多的关系,因此除了三张主表,对应的还添加了两张关系连接表,当然表名大家可以随意取,但是这几张表是RBAC(Role Based Access Controll)结构所必须的。
在这里插入图片描述
permission权限表
在这里插入图片描述
role角色表
在这里插入图片描述
role_permission角色权限表
在这里插入图片描述
user用户表
在这里插入图片描述
user_role用户角色表
在这里插入图片描述
通过下面的这张图大家应该可以更加直观的认清这5张表的关系了吧,最左边一栏是关系表,中间是我们的三张主表,最右边是对用户所对应的角色和权限的示例说明,表与表之间相关联的字段在关系表中也能够清晰的体现
在这里插入图片描述

第三式:修改pom.xml文件
在前面学习Maven的时候,在博文 Marco’s Java【Maven入门(四) 之 按MVC三层结构分配Maven项目】的末尾提供了一份比较齐全pom.xml,但是我们知道在Maven中很多jar包都是可以依赖传递的,比如说我们导入spring-jdbc,那么spring-core、spring-beans等等也会被导入进来,那么在这里我稍微精简了一下,利用Maven的以来传递关系,尽可能的少配置。

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.marco</groupId>
	<artifactId>shiro_ssm_layui</artifactId>
	<packaging>war</packaging>
	<version>1.0</version>
	<name>shiro_ssm_layui</name>
	<url>http://maven.apache.org</url>
	<!-- 声明版本号 -->
	<properties>
		<servlet.version>3.1.0</servlet.version>
		<jsp.version>2.3.1</jsp.version>
		<spring.version>4.3.24.RELEASE</spring.version>
		<mybatis.version>3.5.1</mybatis.version>
		<mybatis-spring.version>2.0.1</mybatis-spring.version>
		<mysql.version>5.1.47</mysql.version>
		<pagehelper.version>5.1.10</pagehelper.version>
		<druid.version>1.1.19</druid.version>
		<slf4j.version>1.7.26</slf4j.version>
		<log4j.version>1.2.17</log4j.version>
		<jackson.version>2.9.9</jackson.version>
		<jstl.version>1.1.2</jstl.version>
		<shiro.version>1.4.1</shiro.version>
	</properties>
	<!-- 依赖的jar包 -->
	<dependencies>
		<!-- servlet-api -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>${servlet.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- jsp-api -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>${jsp.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>
		<!-- mybatis-spring -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>${mybatis-spring.version}</version>
		</dependency>
		<!-- mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>
		<!-- pagehelper -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>${pagehelper.version}</version>
		</dependency>
		<!-- druid -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>${druid.version}</version>
		</dependency>
		<!-- slf4j-api -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<!-- log4j-api -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
		</dependency>
		<!-- jackson-core -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		<!-- jstl -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>
		<!--taglibs/standard -->
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>${jstl.version}</version>
		</dependency>
		<!-- shiro.version -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>${shiro.version}</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>carrent_plus</finalName>
		<plugins>
			<!-- 加入tomcat运行插件 -->
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<!--解决页面提交数据乱码问题 -->
					<!-- <uriEncoding>UTF-8</uriEncoding> -->
					<!-- tomcat插件的请求端口 --> 
					<!-- <port>8080</port> -->
					<!-- 项目的请求路径 -->
					<!-- <path>/marco</path> -->
					<uriEncoding>UTF-8</uriEncoding><!--  解决页面提交数据乱码问题 -->
                    <port>8080</port><!-- tomcat插件的请求端口 -->
                    <!-- <path>/marco</path> --><!-- 项目的请求路径 -->
                    <!-- 指tomcat的manager项目的访问地址     
                    http://127.0.0.1:8080/manager
                    text必须要加,不加的话,使用maven打包的话不能帮我们把项目部署到tomcat7里面
                     -->
                    <url>http://localhost:8080/manager/text</url>
                    <!-- tomcat的登陆名和密码 -->
                    <username>admin</username>
                    <password>admin</password>
                    <!-- 打成war包的名字 -->
                    <path>/marco</path>
				</configuration>
			</plugin>


			<!-- 指定当前项目的jdk版本 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<!-- 指定source和target的版本 -->
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

这样一来,我们这个"小项目"依赖的jar包就都导入进来的,事到如今,是不是觉得Maven使用起来还是很简单呢?毕竟不用我们一个个的去下载,一个个去文件夹中翻,可能版本还有问题,那就更头疼啦~

第四式:创建UserRealm
本次我们要做的登录操作和之前的大有不同啦,因为我们需要使用到Shiro框架来实施我们的安全策略,因为我们需要实现认证和授权的功能,因此UserRealm需要集成AuthorizingRealm并重写doGetAuthorizationInfo()doGetAuthenticationInfo()方法,我们先创建好这个类,后面再来修改完善,思路会更加清晰。
在这里插入图片描述


Shiro集成SSM的基本MVC模型搭建

第五式:创建实体类
根据我们上面的数据库表,可以看出我们需要创建的实体类有三个,我这边先将项目创建的目录全部列出来,domain里面的代码很简单,我在这里就不多赘述啦~
在这里插入图片描述

第六式:创建UserMapper并修改UserMapper.xml
因为我这里使用的是Mybatis逆向工程自动生成的domain、mapper、和Mapper.xml,因此UserMapper和Mapper.xml有些细节还需要修改

package com.marco.mapper;

import com.marco.domain.User;

public interface UserMapper {
    int deleteByPrimaryKey(Integer userid);

    int insert(User record);

    int insertSelective(User record);

    User selectByPrimaryKey(Integer userid);

    int updateByPrimaryKeySelective(User record);

    int updateByPrimaryKey(User record);
    
    //根据用户的username查询用户信息
    User queryUserByUserName(String username);
}

因为逆向工程其他的增删改查已经都生成好了,接下来我的Mapper.xml代码都只会添加一些我们所需要的功能对应的sql

<mapper namespace="com.marco.mapper.UserMapper">
  <resultMap id="BaseResultMap" type="com.marco.domain.User">
    <id column="userid" jdbcType="INTEGER" property="userid" />
    <result column="username" jdbcType="VARCHAR" property="username" />
    <result column="userpwd" jdbcType="VARCHAR" property="userpwd" />
    <result column="sex" jdbcType="VARCHAR" property="sex" />
    <result column="address" jdbcType="VARCHAR" property="address" />
  </resultMap>
  <sql id="Base_Column_List">
    userid, username, userpwd, sex, address
  </sql>
  <select id="queryUserByUserName" resultMap="BaseResultMap">
  	select <include refid="Base_Column_List" />
  	from user
    where username = #{value}
  </select>
</mapper>

第七式:创建UserServiceImpl及UserService
UserService的代码我就略了哈~ 比较占空间

@Service
public class UserServiceImpl implements UserService{
	
	@Autowired
	UserMapper userMapper;
	
	@Override
	public User queryUserByUserName(String username) {
		return userMapper.queryUserByUserName(username);
	}
}

第八式:创建UserController
一样的道理,在这里先把架子给打好,后面我们再慢慢的填充需要的东西,这是实际开发的时候一定要有的一种思维方式,否则想到一个写好了,再去写另外一个,思路会很混乱。

package com.marco.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
@RequestMapping("user")
public class UserController {
	
	@RequestMapping("query")
	public Map<String,Object> query() {
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("msg", "query");
		return map;
	}
	
	@RequestMapping("add")
	public Map<String,Object> add() {
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("msg", "add");
		return map;
	}
	
	@RequestMapping("update")
	public Map<String,Object> update() {
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("msg", "update");
		return map;
	}
	
	@RequestMapping("delete")
	public Map<String,Object> delete() {
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("msg", "delete");
		return map;
	}
	
	
	@RequestMapping("export")
	public Map<String,Object> export() {
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("msg", "export");
		return map;
	}
}

第九式:创建RoleMapper并修改RoleMapper.xml
和UserMapper和UserMapper.xml一样的,我这里还是仅做修改,因为后面做权限和角色管理要查询用户的角色,因此我们将这个方法写在RoleMapper中,通过用户的ID来查询用户所有的角色(一对多的关系)。

package com.marco.mapper;

import java.util.List;

import com.marco.domain.Role;

public interface RoleMapper {
    int deleteByPrimaryKey(Integer roleid);

    int insert(Role record);

    int insertSelective(Role record);

    Role selectByPrimaryKey(Integer roleid);

    int updateByPrimaryKeySelective(Role record);

    int updateByPrimaryKey(Role record);
    
    //根据用户的id查询用户所拥有的角色
    List<Role> queryRolesByUserId(Integer userid);
}

修改RoleMapper.xml

<mapper namespace="com.marco.mapper.RoleMapper">
  <resultMap id="BaseResultMap" type="com.marco.domain.Role">
    <id column="roleid" jdbcType="INTEGER" property="roleid" />
    <result column="rolename" jdbcType="VARCHAR" property="rolename" />
  </resultMap>
  <sql id="Base_Column_List">
    roleid, rolename
  </sql>
  <!-- 根据用户的id查询用户所拥有的角色 -->
  <select id="queryRolesByUserId" resultMap="BaseResultMap">
  	 select t1.* from role t1 inner join user_role t2 
  	 on (t1.roleid = t2.roleid) 
  	 where t2.userid = #{value}
  </select>
</mapper>

第十式:创建RoleService和RoleServiceImpl
注意,这里我们只需要查询用户角色的名称就可以了

package com.marco.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.marco.domain.Role;
import com.marco.mapper.RoleMapper;
import com.marco.service.RoleService;
@Service
public class RoleServiceImpl implements RoleService {
	@Autowired
	RoleMapper roleMapper;
	//根据用户的id查询用户拥有的所有角色的名称
	@Override
	public List<String> queryRolesByUserId(Integer userid) {
		List<Role> roleList = roleMapper.queryRolesByUserId(userid);
		List<String> roles = new ArrayList<String>();
		for (Role role : roleList) {
			roles.add(role.getRolename());
		}
		return roles;
	}
}	

第十一式:创建PermissionMapper 并修改PermissionMapper .xml

package com.marco.mapper;

import java.util.List;

import com.marco.domain.Permission;

public interface PermissionMapper {
    int deleteByPrimaryKey(Integer perid);

    int insert(Permission record);

    int insertSelective(Permission record);

    Permission selectByPrimaryKey(Integer perid);

    int updateByPrimaryKeySelective(Permission record);

    int updateByPrimaryKey(Permission record);
    
    //根据用户的id查询用所拥有的所有权限
    List<Permission> queryPermissionByUserId(Integer userid);
}

queryPermissionByUserId(String userid)这个方法则需要联合三个表查询

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.marco.mapper.PermissionMapper">
  <resultMap id="BaseResultMap" type="com.marco.domain.Permission">
    <id column="perid" jdbcType="INTEGER" property="perid" />
    <result column="pername" jdbcType="VARCHAR" property="pername" />
    <result column="percode" jdbcType="VARCHAR" property="percode" />
  </resultMap>
  <sql id="Base_Column_List">
    perid, pername, percode
  </sql>
  <!-- 根据用户id查询用户的权限 -->
  <select id="queryPermissionByUserId" resultMap="BaseResultMap">
  	 select t1.* from permission t1 inner join role_permission t2 inner join user_role t3 
  	 on (t1.perid = t2.perid and t2.roleid = t3.roleid) 
  	 where t3.userid = #{value}
  </select>
</mapper>

第十二式:创建PermissionService和PermissionServiceImpl
这里我们要查询的就不是Permission的名字了,而是它的percode,percode就是我们对应的操作的名称(比如说用的添加、修改、删除等等),大家看下面的数据应该就明白了
在这里插入图片描述

package com.marco.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.marco.domain.Permission;
import com.marco.mapper.PermissionMapper;
import com.marco.service.PermissionService;

@Service
public class PermissionServiceImpl implements PermissionService{
	@Autowired
	PermissionMapper permissionMapper;
	//根据用户的id查询用户拥有的所有权限的percode
	@Override
	public List<String> queryPermissionByUserId(Integer userid) {
		List<Permission> permissionList = permissionMapper.queryPermissionByUserId(userid);
		List<String> permissions = new ArrayList<String>();
		for (Permission permission : permissionList) {
			permissions.add(permission.getPercode());
		}
		return permissions;
	}
}

第十三式:创建ActiverUser
ActiverUser就是一个容器,存储用户的信息,包含基本信息、角色和权限,在前面几章我们也提到过ActiverUser的用途和使用方式

package com.marco.utils;

import java.util.List;

import com.marco.domain.User;

public class ActiveUser{
	private User user;
	
	private List<String> roles;
	
	private List<String> permissions;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public List<String> getRoles() {
		return roles;
	}

	public void setRoles(List<String> roles) {
		this.roles = roles;
	}

	public List<String> getPermissions() {
		return permissions;
	}

	public void setPermissions(List<String> permissions) {
		this.permissions = permissions;
	}
}

到此,基础的部分已经都搭建好了,"降龙十八式"的前13式已经打完,累了… 中场休息一下吧,下一节我们会构建Shiro与SMM集成的核心部分,鼓足干劲继续吧~

标签:Marco,Java,version,List,marco,import,com,public,Shiro
来源: https://blog.csdn.net/weixin_44698119/article/details/98194472