JAVA解析逻辑表达

本文介绍了一个使用JAVA解析动态逻辑表达式的方法,旨在解决菜单显示条件的灵活性问题。通过在菜单表增加一个‘菜单展示条件列’,存储如'{session_mchtType}={1.9}或{session_mchtType}={25}'等表达式,然后通过自定义的解析方法,根据用户会话信息动态过滤菜单,避免了大量的if判断。示例代码展示了如何解析和执行这些逻辑表达式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近公司有项目改版。原先菜单是写死在页面,一个角色一个菜单页,且菜单的显示与否不只是和角色有关。页面里有很多的地方用if去判断该菜单是否显示。上级要求,将菜单放到数据库管理。跟角色有关的菜单通过配置角色的权限就可以了。这个大家都懂得。但这里还有一个问题,菜单不只是和角色有关。写很多if在代码里进行判断,这种方式显然不灵活。而且很容易出问题。于是我想到了在菜单表增加一个列。叫菜单展示条件列。这个列的数据类似下面:({session_mchtType}={ 1.9}或{session_mchtType}={25})且({session_payType}={74}且{session_circleId}={6})。然后,在加载完用户的权限后,解析该规则,过滤掉不满足条件的菜单就可以了。

下面是代码:

测试类:

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.smartpay.ops.cms.dto.MbMenuDto;

public class Test {
static Map map=new HashMap();
public static void main(String[] args) throws Exception {
map.put("session_mchtType", "1.9");
map.put("session_circleId", 6);
map.put("session_payType", 74);
Test t=new Test();
String ruleStr="   ({session_mchtType}={ 1.9}或{session_mchtType}={25})且({session_payType}={74}且{session_circleId}={6})";
t.parseRule( ruleStr);

List<MbMenuDto> menuList=new ArrayList();
MbMenuDto menu=new MbMenuDto();
menu.setMenuName("密码修改");
menu.setShowCondition("{session_mchtType}!={3}或{session_payType}={7}且{session_circleId}={6}");
menuList.add(menu);
new Test().filteMenu(menuList);


}
public boolean parseRule(String ruleStr){
//没有规则限制
if(ruleStr==null||ruleStr.trim().length()==0){
return true;
}
//把所有的空格去掉
ruleStr=ruleStr.replaceAll(" {1,}", "");
String k1="(";
//1:从最后一个“(”开始解析,将带括号的表达式解析成最基本的逻辑表达式
do{
int indexK1=ruleStr.lastIndexOf(k1);
if(indexK1>-1){
int indexK2=getK2(indexK1, ruleStr);
//2:解析成最基本的逻辑表达式后,将表达式嵌入原规则字符串
if(indexK2>-1){
String rule2=ruleStr.substring(indexK1+1, indexK2);
String logicValue=logic(rule2);
ruleStr=ruleStr.substring(0, indexK1)+logicValue+ruleStr.substring(indexK2+1);
System.out.println("替换后的表达式:"+ruleStr);
}else{
throw new RuleException("表达式格式不正确:"+ruleStr);
}
}else{
break;
}
}while(true);

String logicValue=logic(ruleStr);
System.out.println("最终的逻辑值:"+logicValue);
return Boolean.valueOf(logicValue);
}
/*
* 逻辑运算
*/
public String logic(String ruleStr){
String []rulesOr=ruleStr.split("或");
boolean logicValue=true;
//或运算
for(int i=0;i<rulesOr.length;i++){
String rule=rulesOr[i];
//与运算
String []rulesAnd=rule.split("且");
for(int n=0;n<rulesAnd.length;n++){
logicValue=logic2(rulesAnd[n]);
//与运算,一个为假则为假
if(logicValue==false){
break;
}
}
if(logicValue){//或运算,只要有一个为真,则是真.
break;
}
}
return Boolean.toString(logicValue);
}
/*
* 逻辑运算
*/
public boolean logic2(String rule){
if(rule.equals("true")){
return true;
}
if(rule.equals("false")){
return false;
}
boolean logicValue=true;
int p1=rule.indexOf("{");
int p2=rule.indexOf("}");
int p3=rule.lastIndexOf("{");
int p4=rule.lastIndexOf("}");
if(p1!=0||p2<0||p3<0||p4!=rule.length()-1||
p2<p1||p4<p3||p1==p3||p2==p4){//如果规则格式不正确,就当成不满足条件
throw new RuleException("表达式格式不正确:"+rule);
}
String paramName=rule.substring(p1+1,p2);
String value=rule.substring(p3+1, p4);
String ysf=rule.substring(p2+1,p3);
logicValue=excute(paramName, value,ysf);
System.out.println(paramName+ysf+value+"的结果:"+logicValue);
return logicValue;
}
/*
* 从后获取最近“(”的“)”的下标
*/
public int getK2(int indexK1,String ruleStr){
String ruleStr2=ruleStr.substring(indexK1);
int indexK2=ruleStr2.indexOf(")");
if(indexK2>-1){
return indexK1+indexK2;
}else{
return indexK2;
}
}
/**
* 过滤菜单
*/
public void filteMenu(List<MbMenuDto> menuList){
System.out.println("--------------过滤菜单--------------");
if(menuList==null){
return;
}
Iterator<MbMenuDto> it=menuList.iterator();
while(it.hasNext()){
MbMenuDto menu=it.next();
boolean showed=true;
try{
showed=parseRule(menu.getShowCondition());
}catch(RuleException e){//如果规则设置有异常,就当不满足条件
LoggerUtil.error(e);
showed=false;
}
if(!showed){//不满足显示条件
System.out.println("排除菜单:"+menu.getMenuName());
it.remove();
}
}
}

private boolean excute(String paramName,String value,String ysf){
Object paramObj=map.get(paramName);
String paramVaue=null;
if(paramObj!=null){
paramVaue=paramObj.toString();
}
if("=".equals(ysf)){
if(value!=null&&value.equals(paramVaue)){
return true;
}else{
return false;
}
}else if("!=".equals(ysf)){
if(value!=null&&!value.equals(paramVaue)){
return true;
}else{
return false;
}
}else if(">".equals(ysf)){
return compareBig(paramVaue,value, ysf, paramName);
}else if("<".equals(ysf)){
return compareBig(paramVaue,value, ysf, paramName);
}else if(">=".equals(ysf)){
return compareBig(paramVaue,value, ysf, paramName);
}else if("<=".equals(ysf)){
return compareBig(paramVaue,value, ysf, paramName);
}else{
throw new RuleException("不支持的运算符:"+ysf);
}
}
private boolean compareBig(String localV,String ruleV,String ysf,String paramName){
BigDecimal b1=null;
BigDecimal b2=null;
try{
b1=new BigDecimal(ruleV);
   b2=new BigDecimal(localV);
}catch(NumberFormatException e){
throw new RuleException("规则异常:"+ruleV+"或"+localV+"不是数字");
}
if(">".equals(ysf)){
if(b2.compareTo(b1)>0){
return true;
}else{
return false;
}
}else if("<".equals(ysf)){
if(b2.compareTo(b1)<0){
return true;
}else{
return false;
}
}else if(">=".equals(ysf)){
if(b2.compareTo(b1)>=0){
return true;
}else{
return false;
}
}else{
if(b2.compareTo(b1)<=0){
return true;
}else{
return false;
}
}

}
}


菜单类:

package com.smartpay.ops.cms.dto;


import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.List;


public class MbMenuDto {
private Integer menuId;
private String menuName;
private Integer parentMenuId;
private String url;
/**展示菜单的条件*/
private String showCondition;




public void setMenuId(Integer value) {
this.menuId = value;
}

public Integer getMenuId() {
return this.menuId;
}

public Integer getPk() {
return this.menuId;
}


public void setMenuName(String value) {
this.menuName = value;
}

public String getMenuName() {
return this.menuName;
}



public void setParentMenuId(Integer value) {
this.parentMenuId = value;
}

public Integer getParentMenuId() {
return this.parentMenuId;
}

public void setUrl(String value) {
this.url = value;
}

public String getUrl() {
return this.url;
}

public String getShowCondition() {
return showCondition;
}
public void setShowCondition(String showCondition) {
this.showCondition = showCondition;
}


}

异常类:



public class RuleException extends RuntimeException{


public RuleException(String message){
super(message);
}
public String getMessage(){
return super.getMessage();
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值