1、通用ConversationBean
前文我们以role管理的页面来说明其他功能的页吧也基本上是这个样子,前面页面中有5个表单,分别要求调用后台的roleBean这个类的5个相关方法(实际上还涉及到roleBean的其他方法)。而且前台页面展示给用户数据时,还需要提前为用户准备好其有权限访问的数据,这样我们利用这种特性,将roleBean声明为一个会话bean的子为,其他所有的view这层其他的bean也都是这个类的之类,这个父类我命名为ConversationBaseBean。这个类的做用是定义在用话与后台代码做会话时,通用的一些方法,比如新建这类的子类时,先做初始化取得数据的操作,结束后释放相关信息的操作,以及这类bean的通用增、删、查改等通用的方法,这个类为所有其他viewBean的父类,定义为抽象类,其主要代码如下:
ackage com.dodow.base.view;
import javax.enterprise.context.Conversation;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dodow.base.entity.BaseEntity;
/**
*
*/
public abstract class ConversationBaseBean<T extends BaseEntity> extends BaseBean<T> implements IBaseBean {
private static final long serialVersionUID = 1L;
protected String readonly = "true";
final Logger logger = LoggerFactory.getLogger(getClass());
@Inject
private Conversation conversation;
public void initConversation() {
if(conversation.isTransient()) {
conversation.begin();
}
this.readonly="true";
}
public void endConversation() {
if(!conversation.isTransient())
conversation.end();
}
public String save() {
super.saveEntity();
this.endConversation();
return listPage==null? "/faces/debug/failed.xhtml":listPage;
}
public String cancel() {
this.endConversation();
return "cancelled";
}
public String delete() {
super.deleteEntity();
this.endConversation();
return listPage==null ? "/faces/debug/failed.xhtml":listPage;
}
public void afterPhaseListener(PhaseEvent phaseEvent) {
try {
if(phaseEvent.getPhaseId()==PhaseId.RENDER_RESPONSE){
this.readonly="false";
}
}catch(Exception e) {
e.printStackTrace();
}
}
public String getReadonly() {
return readonly;
}
public void setReadonly(String readonly) {
this.readonly = readonly;
}
}
2、roleBean的相关方法
在这个类中我们需要定义如下方法,以来对前台role页面list.xhtml相关的几个form里面的事件做出响应,其他代码的结构如下:
@PostConstruct
public void LoadData() {
}
public void search() {
}
public void addOrEdit() {
}
public void del() {
}
public void clear() {
}
public void loadTreeData() {
}
public void saveRoleRes() {
}
public Boolean checkFormItem() {
}
private boolean isEquals(List<Resource> list, Resource resource) {
}
2.1LoadData()方法
@PostConstruct
public void LoadData() {
}
这个方法实现父类的初始化方法时,用来为前台list.xhml的页面展示form中的<p:dataTable>控件准备好需要展示的数据,其实现的代码大约如下:
@PostConstruct
public void LoadData() {
if (roleList.size() == 0) {
search();
}
if (sysItems == null || sysItems.size() == 0) {
sysItems = systemInfoService.findSysItem();
}
}
2.2、search()方法
他的作用是利用和roleBean对应的为其提供服务的RoleService类来获取数据库数据,同时这个方法也对前台页面中如果用户需要查询的时候,对查询按钮做出反应,会根据前台页面传回的查询条件对数据库进行数据查询作用,其主要代码参考如下:
/**
* @Title:search
* @Desc:查找系统id为sysId的系统信息
* @Param:
* @Return:void
* @Throws:
*/
public void search() {
roleList = roleService.findRoleListBySysId(sysId);
for (Role r : roleList) {
r.setSystemInfo(entityService.findUnique(SystemInfo.class, r.getSystemInfo().getId()));
}
}
2.3 public void addOrEdit()
此方法是用于对于前台另外增加表单和修改表单中提交事件做出反应,实现对数据库角色表的新增和修改的功能,其主要代码如下:
/**
* @Title:addOrEdit
* @Desc:写入当前角色并将该角色的系统信息一起写入
* @Param:
* @Return:void
* @Throws:
*/
public void addOrEdit() {
try {
this.getInstance().setSystemInfo(entityService.findUnique(SystemInfo.class, sysId));
roleService.createOrUpdate(this.getInstance());
search();
MessageUtils.addSuccessMessage("messages", "保存角色成功!");
} catch (Exception e) {
MessageUtils.addErrorMessage("messages", "保存角色失败!");
}
}
2.4 del()
看名字就晓得这个方法是用来响应前台页面中删除表单被提交时的响应操作,这里面实现对被选中的角色记录进行删除,其主要代码如下:
/**
* @Title:del
* @Desc:删除当前角色数据
* @Param:
* @Return:void
* @Throws:
*/
public void del() {
try {
entityService.delete(Role.class, this.getInstance().getId());
search();
MessageUtils.addSuccessMessage("messages", "删除角色成功!");
} catch (Exception e) {
MessageUtils.addErrorMessage("messages", "删除角色失败!");
}
}
2.5 clear()
这个方法用于会话结束,会者前台页面需要对某些数据对象清空时所操作的方法,可以参考前面页面(list.xhtml)中调用这个的地方所表达的意义 ,其主要作用释放一些对象,其主要代码如下:
/**
* @Title:clear
* @Desc:清除缓存数据
* @Param:
* @Return:void
* @Throws:
*/
public void clear() {
this.sysId = null;
this.setInstance(new Role());
}
2.6 loadTreeData()
这个类的作用主要是用来为角色设置需要的资源项时,加载资源项的,其主要代码为:
/**
* @Title:loadTreeData
* @Desc:加载资源树
* @Param:
* @Return:void
* @Throws:
*/
public void loadTreeData() {
List<Resource> roleResourceList = this.resourceService.findResouceByRole(currentRole);
root = new DefaultTreeNode("资源树", null);
List<Resource> rList1 = resourceService.findResourceBySysId(sysId, "0");
for (Resource r1 : rList1) {
TreeNode rNode1 = new DefaultTreeNode(r1, root);
rNode1.setExpanded(true);
if (isEquals(roleResourceList, r1)) {
rNode1.setSelected(true);
}
List<Resource> rList2 = resourceService.findResourceBySysId(sysId, r1.getCode());
for (Resource r2 : rList2) {
TreeNode rNode2 = new DefaultTreeNode(r2, rNode1);
rNode2.setExpanded(true);
if (isEquals(roleResourceList, r2)) {
rNode2.setSelected(true);
}
List<Resource> rList3 = resourceService.findResourceBySysId(sysId, r2.getCode());
for (Resource r3 : rList3) {
TreeNode rNode3 = new DefaultTreeNode(r3, rNode2);
rNode3.setExpanded(true);
if (isEquals(roleResourceList, r3)) {
rNode3.setSelected(true);
}
List<Resource> rList4 = resourceService.findResourceBySysId(sysId, r3.getCode());
for (Resource r4 : rList4) {
TreeNode rNode4 = new DefaultTreeNode(r4, rNode3);
rNode4.setExpanded(true);
if (isEquals(roleResourceList, r4)) {
rNode4.setSelected(true);
}
}
}
}
}
}
其他方法都不重要,最后会帖出来。这里为了展示被我把代码搞得有点乱,有的方法应该写在service这一层去实现的,看官老爷就将究看,如果有特殊癖好的,自行把有些方法的实现放在service这一层去。
2.7 其他属性声明,这里就不做特别详细的说明,看前台页面,以及后台需要处理的业务逻辑,将大体上需要的属性做好下声明:
@EJB
private StatelessEntityService entityService;//这是前面定义的数据库操作类,如果需要在这个view中做数据库方面的操作,注入这个类
@EJB
private RoleService roleService; //这个类是封装所有对角色这个类做操作的方法,但我搞得有点乱,在view这一层也在乱搞,请自行修改
@EJB
private ResourceService resourceService;//从业务逻辑上来讲,对角色做操作的时候,也需要对角色资源表中的资源做操作,所以注入这个类
@EJB
private SystemInfoService systemInfoService;//这个类看官不用管,这是多系统用户管理的类,是不为实现多系统的统一认证的,忽略
private Map<String, Object> conditionMap = new HashMap<String, Object>();//这个类是用来为前台页面,把查询条件放入到这个参数中,传入到后台来
private List<Role> roleList = Lists.newArrayList();//这就是为list.xhtml的tableForm表单中<p:dataTable>准备数据的
private List<SelectItem> sysItems = Lists.newArrayList();//这是用来保存对用户指定资源项时的list,
/** @Fields:long:所属系统 **/
private Long sysId;//这个参考上面,不用管,是多系统时需要用到的
private TreeNode root;//这是前台对应primefaces的树形制件准备数据的。可对应到前台list.xhtml一起查看
private TreeNode[] selectedNodes; //用于保存前台页面被用户选中的资源项,同上,对应primefaces的资源树。
/** @Fields:long:当前角色 **/
private Role currentRole=new Role();//这个类比较重要,用来保存前台页面中,被用户通过primefaces选中的需要操作的行(记录)
感觉一辈子也没写这么多注释,以上的属性都要结合前台页面,和后台需要操作的方法对应其来看,下面将我的这个类的完整代码帖出来,供参考你写其他的viewBean
/**
* @Title:RoleBean.java
* @Package:com.dodow.common.view
* @Desc:TODO(角色相关页面cdi类)
* @Author:
* @Date:2024年8月30日 23:26:28
* @Version:V1.0
*/
package com.dodow.common.view;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.ConversationScoped;
import javax.faces.model.SelectItem;
import javax.inject.Named;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import com.dodow.base.entity.SystemInfo;
import com.dodow.base.service.StatelessEntityService;
import com.dodow.base.util.MessageUtils;
import com.dodow.base.view.ConversationBaseBean;
import com.dodow.common.entity.Resource;
import com.dodow.common.entity.Role;
import com.dodow.common.entity.RoleResource;
import com.dodow.common.service.ResourceService;
import com.dodow.common.service.RoleService;
import com.dodow.common.service.SystemInfoService;
import com.google.common.collect.Lists;
/**
* @Desc:TODO
* @Author:
*/
@Named
@ConversationScoped
public class RoleBean extends ConversationBaseBean<Role> {
/** @Fields:long:TODO **/
private static final long serialVersionUID = 1L;
@EJB
private StatelessEntityService entityService;
@EJB
private RoleService roleService;
@EJB
private ResourceService resourceService;
@EJB
private SystemInfoService systemInfoService;
private Map<String, Object> conditionMap = new HashMap<String, Object>();
private List<Role> roleList = Lists.newArrayList();
private List<SelectItem> sysItems = Lists.newArrayList();
/** @Fields:long:所属系统 **/
private Long sysId;
private TreeNode root;
private TreeNode[] selectedNodes;
/** @Fields:long:当前角色 **/
private Role currentRole=new Role();
/**
* @Title:LoadData
* @Desc:初始化页面加载数据
* @Param:
* @Return:void
* @Throws:
*/
@PostConstruct
public void LoadData() {
if (roleList.size() == 0) {
search();
}
if (sysItems == null || sysItems.size() == 0) {
sysItems = systemInfoService.findSysItem();
}
}
/**
* @Title:search
* @Desc:查找系统id为sysId的系统信息
* @Param:
* @Return:void
* @Throws:
*/
public void search() {
roleList = roleService.findRoleListBySysId(sysId);
for (Role r : roleList) {
r.setSystemInfo(entityService.findUnique(SystemInfo.class, r.getSystemInfo().getId()));
}
}
/**
* @Title:addOrEdit
* @Desc:写入当前角色并将该角色的系统信息一起写入
* @Param:
* @Return:void
* @Throws:
*/
public void addOrEdit() {
try {
this.getInstance().setSystemInfo(entityService.findUnique(SystemInfo.class, sysId));
roleService.createOrUpdate(this.getInstance());
search();
MessageUtils.addSuccessMessage("messages", "保存角色成功!");
} catch (Exception e) {
MessageUtils.addErrorMessage("messages", "保存角色失败!");
}
}
/**
* @Title:del
* @Desc:删除当前角色数据
* @Param:
* @Return:void
* @Throws:
*/
public void del() {
try {
entityService.delete(Role.class, this.getInstance().getId());
search();
MessageUtils.addSuccessMessage("messages", "删除角色成功!");
} catch (Exception e) {
MessageUtils.addErrorMessage("messages", "删除角色失败!");
}
}
/**
* @Title:clear
* @Desc:清除缓存数据
* @Param:
* @Return:void
* @Throws:
*/
public void clear() {
this.sysId = null;
this.setInstance(new Role());
}
/**
* @Title:loadTreeData
* @Desc:加载资源树
* @Param:
* @Return:void
* @Throws:
*/
public void loadTreeData() {
List<Resource> roleResourceList = this.resourceService.findResouceByRole(currentRole);
root = new DefaultTreeNode("资源树", null);
List<Resource> rList1 = resourceService.findResourceBySysId(sysId, "0");
for (Resource r1 : rList1) {
TreeNode rNode1 = new DefaultTreeNode(r1, root);
rNode1.setExpanded(true);
if (isEquals(roleResourceList, r1)) {
rNode1.setSelected(true);
}
List<Resource> rList2 = resourceService.findResourceBySysId(sysId, r1.getCode());
for (Resource r2 : rList2) {
TreeNode rNode2 = new DefaultTreeNode(r2, rNode1);
rNode2.setExpanded(true);
if (isEquals(roleResourceList, r2)) {
rNode2.setSelected(true);
}
List<Resource> rList3 = resourceService.findResourceBySysId(sysId, r2.getCode());
for (Resource r3 : rList3) {
TreeNode rNode3 = new DefaultTreeNode(r3, rNode2);
rNode3.setExpanded(true);
if (isEquals(roleResourceList, r3)) {
rNode3.setSelected(true);
}
List<Resource> rList4 = resourceService.findResourceBySysId(sysId, r3.getCode());
for (Resource r4 : rList4) {
TreeNode rNode4 = new DefaultTreeNode(r4, rNode3);
rNode4.setExpanded(true);
if (isEquals(roleResourceList, r4)) {
rNode4.setSelected(true);
}
}
}
}
}
}
/**
* @Title:saveRoleRes
* @Desc:保存角色资源
* @Param:
* @Return:void
* @Throws:
*/
public void saveRoleRes() {
if (selectedNodes != null && selectedNodes.length > 0) {
try {
this.resourceService.deleteRoleResource(currentRole);
RoleResource rr;
for (TreeNode node : selectedNodes) {
rr = new RoleResource();
rr.setResource((Resource) node.getData());
rr.setRole(currentRole);
entityService.create(rr);
}
MessageUtils.addSuccessMessage("messages", "角色权限设置成功!");
} catch (Exception e) {
MessageUtils.addErrorMessage("messages", "角色权限设置失败!");
}
} else {
MessageUtils.addErrorMessage("messages", "请选择权限资源!");
}
}
/**
* @Title:checkFormItem
* @Desc:校验页面项目
* @Param:@return
* @Return:Boolean
* @Throws:
*/
public Boolean checkFormItem() {
boolean checkResult = true;
return checkResult;
}
/**
* @Title:isEquals
* @Desc:是否包含在资源list里
* @Param:@param list
* @Param:@param resource
* @Param:@return
* @Return:boolean
* @Throws:
*/
private boolean isEquals(List<Resource> list, Resource resource) {
for (Resource r : list) {
if (r.getId().equals(resource.getId())) {
return true;
}
}
return false;
}
// ----------------------------- set & get -------------------------------//
/**
* @return the conditionMap
*/
public Map<String, Object> getConditionMap() {
return conditionMap;
}
/**
* @param conditionMap the conditionMap to set
*/
public void setConditionMap(Map<String, Object> conditionMap) {
this.conditionMap = conditionMap;
}
/**
* @param sysList the sysList to set
*/
public void setSysList(List<Role> roleList) {
this.roleList = roleList;
}
/**
* @return the sysItems
*/
public List<SelectItem> getSysItems() {
return sysItems;
}
/**
* @param sysItems the sysItems to set
*/
public void setSysItems(List<SelectItem> sysItems) {
this.sysItems = sysItems;
}
/**
* @return the sysId
*/
public Long getSysId() {
return sysId;
}
/**
* @param sysId the sysId to set
*/
public void setSysId(Long sysId) {
this.sysId = sysId;
}
/**
* @return the root
*/
public TreeNode getRoot() {
return root;
}
/**
* @param root the root to set
*/
public void setRoot(TreeNode root) {
this.root = root;
}
/**
* @return the selectedNodes
*/
public TreeNode[] getSelectedNodes() {
return selectedNodes;
}
/**
* @param selectedNodes the selectedNodes to set
*/
public void setSelectedNodes(TreeNode[] selectedNodes) {
this.selectedNodes = selectedNodes;
}
/**
* @return the sysList
*/
public List<Role> getRoleList() {
return roleList;
}
/**
* @param roleList the roleList to set
*/
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
public Role getCurrentRole() {
return currentRole;
}
public void setCurrentRole(Role currentRole) {
this.currentRole = currentRole;
}
}
另外也把我的RoleService类帖出来,供用户参考写其他的service这一层的类。
/**
* @Title:RoleService.java
* @Package:com.dodow.common.service
* @Desc:TODO(描述文件作用)
* @Author:
* @Date:2024年8月30日 23:30:40
* @Version:V1.0
*/
package com.dodow.common.service;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import com.dodow.base.entity.SystemInfo;
import com.dodow.base.exception.AccessException;
import com.dodow.base.service.StatelessEntityService;
import com.dodow.base.util.Validate;
import com.dodow.common.entity.Role;
import com.dodow.common.entity.User;
import com.dodow.common.entity.UserRole;
/**
* @Desc:TODO
* @Author:
*/
@Stateless
public class RoleService implements Serializable{
/** @Fields:long:TODO **/
private static final long serialVersionUID = 1L;
@EJB
private StatelessEntityService entityService;
public List<Role> findAllSysRole(String sql)throws AccessException{
try {
//String sql="select r from Role r odery by r.id";
return entityService.findList(sql);
}catch(Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @Title:createOrUpdate
* @Desc:添加或更新role到数据库
* @Param:@param role
* @Return:void
* @Throws:
*/
public void createOrUpdate(Role role) {
if(role.getId()!=null && role.getId()>01) {
entityService.update(role);
}else {
entityService.create(role);
}
}
/**
* @Title:findRoleListBySysId
* @Desc:获取sysId下角色数据
* @Param:@param sysId
* @Param:@return
* @Return:List<Role>
* @Throws:
*/
public List<Role> findRoleListBySysId(Long sysId){
String jpql="select r from Role r";
if(sysId!=null && sysId!=0) {
jpql+= " where r.systemInfo.id="+sysId;
}
return entityService.findList(jpql);
}
/**
* @Title:getRoleListByUser
* @Desc:查询角色的资源中间表
* @Param:@param user
* @Param:@return
* @Param:@throws AccessException
* @Return:List<UserRole>
* @Throws:
*/
public List<UserRole> getRoleListByUser(User user) throws AccessException{
Validate.notNull(user,new IllegalArgumentException("角色为空"));
try {
String sql = "select ur from UserRole ur where ur.user.id='"+user.getId()+"'";
List<UserRole> list = this.entityService.findList(sql);
return list;
}catch(Exception e) {
throw new AccessException(e);
}
}
/**
* @Title:getRoleListByUser
* @Desc:按用户的id,查找用户的资源中间表
* @Param:@param userId
* @Param:@return
* @Param:@throws AccessException
* @Return:List<UserRole>
* @Throws:
*/
public List<UserRole> getRoleListByUser(String userId) throws AccessException {
Validate.notNull(userId, new IllegalArgumentException("角色为空"));
try {
String sql = "select ur from UserRole ur where ur.user.id='"+userId+"'";
List<UserRole> list = this.entityService.findList(sql);
return list;
} catch (Exception e) {
throw new AccessException(e);
}
}
/**
* @Title:findRoleByUser
* @Desc:获取用户对应角色资源
* @Param:@param user
* @Param:@return
* @Param:@throws AccessException
* @Return:List<Role>
* @Throws:
*/
public List<Role> findRoleByUser(User user) throws AccessException {
try {
List<UserRole> list1 = this.getRoleListByUser(user);
List<Role> list2 = new ArrayList<Role>();
if (list1.isEmpty()) { return list2;}
for (UserRole ur : list1) {
list2.add(ur.getRole());
}
return list2;
} catch (Exception e) {
System.out.println(e.getMessage());
throw new AccessException(e);
}
}
/**
* @Title:findRoleByUser
* @Desc:找到用户id对应的角色
* @Param:@param userId
* @Param:@return
* @Param:@throws AccessException
* @Return:List<Role>
* @Throws:
*/
public List<Role> findRoleByUser(String userId) throws AccessException {
try {
List<UserRole> list1 = this.getRoleListByUser(userId);
List<Role> list2 = new ArrayList<Role>();
if (list1.isEmpty()) { return list2;}
for (UserRole ur : list1) {
list2.add(ur.getRole());
}
return list2;
} catch (Exception e) {
System.out.println(e.getMessage());
throw new AccessException(e);
}
}
/**
* @Title:getRoleByUser
* @Desc:得到用户的角色名
* @Param:@param userId
* @Param:@return
* @Return:String
* @Throws:
*/
public String getRoleByUser(String userId){
if(userId==null)return "";
List<Role> list2 = findRoleByUser(userId);
String str = "";
for(Role r : list2)
{
str += r.getRoleName() +"【"+entityService.findUnique(SystemInfo.class,r.getSystemInfo().getId()).getName()+"】;";
}
return str;
}
}
通过前面我所有帖子,我就实现了一个应用级的框架代码。
回顾一写,前台页面主要是模板文件和提炼的应用的list.xhtml页面(包含通用的所有操作)。前台页面通过cdi的方式 ,直接调用view这一层的类(例如RoleBean),对前台页面上的所有操作做出响应。service这一层的类主要实现对就view层需要的业务逻辑操作。如果只是对数据库做操作,直接在这个类中注入相应的StatelessEntityService,即可完成对数据的操作。这样就形成了一套实用的框架代码。
其中有些地方没有完善,如有其他需要,可提供相应的支持。希望对你有帮助 ,也请点个赞再走。这个系列就暂时更新到这里。