java纳税服务_纳税服务系统【角色模块、包含权限】

需求分析

我们直接来看看原型图,看看需求是怎么样的:

4e056dfcb78d4621d9a8f49de5682107.png

95ce6a87cca8112a560054e252bb1973.png

我们看到上图,就会发现角色模块主要还是CRUD,唯一不同的就是它不再是单独的实体关系。角色与权限是存在关系的。

之前在Servlet+JSP+JavaBean的时候其实我们已经做过了用户-角色-权限之间的操作【权限管理系统】http://blog.csdn.net/hon_3y/article/details/61926175

角色与权限应该是多对多的关系的。

一个角色拥有多个权限

一个权限可以被多个角色使用。

进一步分析

现在我的权限只有5个,有必要使用数据库表吗???没啥必要吧。权限基本就固定下来了。那多对多的关系怎么维护???之前我们使用数据库表就很好做了呀。设计两个实体,使用中间表来描述它们之间的关系就做出来了。

那现在怎么做呢??一个角色对应多个权限

b163f5d1bc26143a3852cced2589d8bf.png

我们在数据库中的表就可以这样设计:即使没有权限表,但是我使用了中间表维护了它们的数据。一样可以做到一个角色对应多个权限这样的功能。

4107ce19117ec2fb4d794ce6ff968585.png

设计实体类

设计权限常量类

我们权限是不需要表的,因此我们把各个权限写下来,使用一个集合装载着就行了。当然啦,他们都应该被设计成常量。我们保存在core模块中【被整个系统用到的】

package zhongfucheng.core.constant;

import java.util.HashMap;

import java.util.Map;

/**

* Created by ozc on 2017/5/26.

*/

public class Constant {

/*----------------------系统权限集合--------------------------*/

public static String PRIVILEGE_XZGL = "xzgl";

public static String PRIVILEGE_HQFW = "hqfw";

public static String PRIVILEGE_ZXXX = "zxxx";

public static String PRIVILEGE_NSFW = "nsfw";

public static String PRIVILEGE_SPACE = "spaces";

//使用一个Map集合来装载着这些权限。

public static Map PRIVILEGE_MAP;

static {

PRIVILEGE_MAP = new HashMap();

PRIVILEGE_MAP.put(PRIVILEGE_XZGL, "行政管理");

PRIVILEGE_MAP.put(PRIVILEGE_HQFW, "后勤服务");

PRIVILEGE_MAP.put(PRIVILEGE_ZXXX, "在线学习");

PRIVILEGE_MAP.put(PRIVILEGE_NSFW, "纳税服务");

PRIVILEGE_MAP.put(PRIVILEGE_SPACE, "我的空间");

}

}

设计角色类

我们的角色类应该使用一个Set集合来保存对应的权限数据的,那么Set集合的元素类型是什么呢???想一下…

之前我们在用的时候,如果有权限表。我们在角色中Set集合的元素应该是Privilege类。但是现在是没有权限表的。我们怎么通过角色来获取所有的权限呢??

再看回这样ER图:我们在角色Set集合中保存着角色与关系表这个不就行了吗!!!

4107ce19117ec2fb4d794ce6ff968585.png

于是我们这样设计:

package zhongfucheng.role.entity;

import java.io.Serializable;

import java.util.Set;

/**

* Created by ozc on 2017/5/26.

*/

public class Role implements Serializable {

private String roleId;

private String state;

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

private Set rolePrivilegeSet;

public static String USER_STATE_VALID = "1";//有效,

public static String USER_STATE_INVALID = "0";//无效

public String getRoleId() {

return roleId;

}

public void setRoleId(String roleId) {

this.roleId = roleId;

}

public String getState() {

return state;

}

public void setState(String state) {

this.state = state;

}

public Set getRolePrivilegeSet() {

return rolePrivilegeSet;

}

public void setRolePrivilegeSet(Set rolePrivilegeSet) {

this.rolePrivilegeSet = rolePrivilegeSet;

}

public static String getUserStateValid() {

return USER_STATE_VALID;

}

public static void setUserStateValid(String userStateValid) {

USER_STATE_VALID = userStateValid;

}

public static String getUserStateInvalid() {

return USER_STATE_INVALID;

}

public static void setUserStateInvalid(String userStateInvalid) {

USER_STATE_INVALID = userStateInvalid;

}

}

设计角色与权限关系类

角色与权限关系类只有两个属性:角色的id和权限的code….这两个是外键列。一张表中一定是要有主键列的,于是我们采用的是复合主键的方式。

对于复合主键,它是要让该类维护一个复合主键类的:

将主键所对应属性提取出一个类(称之为主键类),并且主键类需要实现Serializable接口,重写hashCode和equals()方法

public class RolePrivilege implements Serializable {

private CompositeKey compositeKey;

public CompositeKey getCompositeKey() {

return compositeKey;

}

public void setCompositeKey(CompositeKey compositeKey) {

this.compositeKey = compositeKey;

}

}

复合主键类

按照ER图,我们复合主键就两个属性:role_id和code。。

但是呢,我们想一下需求:在获取角色所有权限的时候,Set集合装载着角色与权限的关系,而角色与权限的关系装载着role_id和code。而很有可能:在我查看用户所拥有角色的时候,想要得到角色的名称。这里仅仅查出来的是角色id,还要通过角色id得到角色的名称…这样就有点麻烦了。于是我们写成Role对象。到时候就能直接获取了。

package zhongfucheng.role.entity;

import java.io.Serializable;

/**

* Created by ozc on 2017/5/26.

*/

public class CompositeKey implements Serializable {

private String code;

private Role role;

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

CompositeKey that = (CompositeKey) o;

if (code != null ? !code.equals(that.code) : that.code != null) return false;

return role != null ? role.equals(that.role) : that.role == null;

}

@Override

public int hashCode() {

int result = code != null ? code.hashCode() : 0;

result = 31 * result + (role != null ? role.hashCode() : 0);

return result;

}

public String getCode() {

return code;

}

public void setCode(String code) {

this.code = code;

}

public Role getRole() {

return role;

}

public void setRole(Role role) {

this.role = role;

}

}

角色映射表配置

/p>

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

角色与权限映射表配置

/p>

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

Role模块的CRUD

没啥好说的,我们在User模块中已经写过了。我们可以直接复制过来,然后将不要的功能去掉。

将全部的User改成Role

将全部的user改成role

dao–>service—>action这样改完,就有了Role模块的CRUD了。

最后:

Spring总配置文件中加载role模块实体映射文件,加载role模块的bean文件。

Struts总配置文件中加载role模块的Struts配置文件。

添加模块

把权限的集合带过去给JSP页面显示出来,JSP使用Struts的checkbox进行遍历【很好用】

public String addUI() {

ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP);

return "addUI";

}

使用checkbox标签遍历

角色权限:

checkboxlist:自动把Map集合遍历出来,生成对应的key value,Map集合的key作为checkbox的key,value作为checkbox的value

list:集合

name:把数据带过去给服务器

--%>

fad080bad497aa68a4e95bf4fc36403c.png

2389e8f57aed4ba168b8373bb5b2e581.png

/************数据自动封装权限的id*************************/

private String[] privilegeIds;

public String[] getPrivilegeIds() {

return privilegeIds;

}

public void setPrivilegeIds(String[] privilegeIds) {

this.privilegeIds = privilegeIds;

}

处理角色与权限的关系。在配置中使用了级联保存,因此可以直接保存数据

public String add() throws IOException {

if (role != null) {

//处理角色与权限的关系

if (privilegeIds != null) {

HashSet set = new HashSet<>();

//得到每一个权限的值--->entity给出对应的构造方法...

for (int i = 0; i < privilegeIds.length; i++) {

set.add(new RolePrivilege(new CompositeKey(role, privilegeIds[i])));

}

role.setRolePrivilegeSet(set);

}

roleServiceImpl.save(role);

//跳转到列表显示页面

return "list";

}

return null;

}

4f6be33bc6530099ffd3dcdad2a62814.png

d749d7f4852d7561c30e0c8905beb8ad.png

显示模块

在显示模块中,主要是显示角色的权限中有点绕…..

角色的权限用set集合保存起来,set集合元素是角色与权限的关系,角色与权限是一个类,该类保存着主键类,主键类存储的是角色和权限code。

我们的目的是:得到角色含有的权限。而目前为止,我们最多只能得到每个权限code值:

b48d814cce7a9fa8e0ff300c17f6292b.png

而我们想要显示的是权限的名称,于是我们得把权限集合传过去,根据code得到权限的名称:

public String listUI() {

roleList = roleServiceImpl.findObjects();

ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP);

return "listUI";

}

JSP页面取值:注意懒加载的问题,设定不要懒加载。不然会出现: java.io.IOException: Stream closed

2eb76a5f781db7600bfd03ac2a5db92c.png

单个删除功能

跳转到Action中处理,把id传递过去…

function doDelete(id) {

document.forms[0].action = "${basePath}role/role_delete.action?role.roleId="+id;

document.forms[0].submit();

}

判断是否为空,不为空就删除。返回到列表页面

2017/5/31 12:59:27 //删除

public String delete() {

if (role != null && role.getRoleId() != null) {

roleServiceImpl.delete(role.getRoleId());

}

return "list";

}

修改模块

数据回显页面,主要就是角色的权限那里怎么回显。我们把所有的权限带过去,用字符串数组记录当前角色有什么权限

//得到所有的权限

ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP);

//外边已经传了id过来了,我们要找到id对应的Role

if (role != null && role.getRoleId() != null) {

//直接获取出来,后面JSP会根据Role有getter就能读取对应的信息!

role = roleServiceImpl.findObjectById(role.getRoleId());

//得到角色所有的权限,把它封装到privilegeIds字符数组中。

//处理权限回显

if (role.getRolePrivilegeSet() != null) {

privilegeIds = new String[role.getRolePrivilegeSet().size()];

int i = 0;

for (RolePrivilege rp : role.getRolePrivilegeSet()) {

privilegeIds[i++] = rp.getCompositeKey().getCode();

}

}

}

return "editUI";

在JSP页面,使用checkboxlist标签进行遍历。

1447e52b35ec12c4ca0c379047a09d73.png

得到JSP传递过来的ids,封装成一个set集合。将set集合赋值给role对象。

public String edit() throws IOException {

//Struts2会自动把JSP带过来的数据封装到Role对象上

if (role.getRoleId() != null && role != null) {

Set set = new HashSet<>();

//得到修改的权限id,封装到set集合中。

for (String privilegeId : privilegeIds) {

set.add(new RolePrivilege(new CompositeKey(role, privilegeId)));

}

role.setRolePrivilegeSet(set);

roleServiceImpl.update(role);

}

return "list";

}

仅仅是使用update(role)方法是不够的,因此Hibernate在更新操作的时候,会先把数据查询出来。当我们更改角色权限的时候,它会将我们已有的权限保留下来,如果有新的就继续添加。它不会把我们没勾选的剔除的。

因此,我们需要在更新的之前,把当前角色所有的权限给删了。

//在修改之前,把角色的所有权限给删除了。不然会遗留之前的权限下来。

roleDaoImpl.deleteRolePrivilegeByRoleId(role.getRoleId());

/***

* 根据角色id删除所有的权限

* */

@Override

public void deleteRolePrivilegeByRoleId(String roleId) {

String sql = "DELETE FROM RolePrivilege WHERE compositeKey.role.roleId= ?";

Query query = getSession().createQuery(sql);

query.setParameter(0, roleId);

query.executeUpdate();

}

效果:

ab8f27655a5091e79329fc4aaa6a1b3f.gif

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值