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