BigInteger权限判断示例

本文介绍了一种高效的权限控制方法,利用BigInteger的setBit和testBit方法实现用户权限的设置与检查,这种方法不仅节省存储空间,而且提高了权限验证的速度。

这里我介绍一种很常用,也比较Professor的权限控制思路。
把具体的权限设置为一个正整数值,如果一个用户有多个权限的话,比如1,2权限,那么我们设置值的时候就是num.setBit(1),num.setBit(2),然后把返回的num值保存在session中,要验证是否有权限的话,只要从session中取得保存的num,然后执行下num.test(权限值),如果返回true就是有权限的,否则无权限。下面例子:

  package com.hundsun.network.post.settle.job;  

    import java.math.BigInteger;  

    public class TestBigInteger {  

        public static void main(String[] args) {  
            //初始  
            BigInteger num = new BigInteger("0");  
            num = num.setBit(2);  
            num = num.setBit(1);  
            System.out.println(num);  
            System.out.println(num.testBit(2));  
            System.out.println(num.testBit(1));  
            System.out.println(num.testBit(3));  
        }  

    }  


返回的结果是:

6
true
true
false

为什么是6呢? 6= 2^2 + 2^1 其实计算的值是2的权的和

好处是,session中存储权限的空间很小,一个整数就代表了所有的权限,验证的时候计算速度也很快。
下面我将提供一个完整的解决方案,从服务器读取Word模板,填充数据并设置保护区域,确保模板不可修改而生成的数据可修改。这个方案基于Apache POI实现,可直接集成到Java项目中。 ### 完整实现方案 ```java import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; import java.io.*; import java.util.*; public class ProtectedWordGenerator { // 从服务器读取模板文档 public static XWPFDocument loadTemplate(String serverPath) throws IOException { try (InputStream is = new FileInputStream(serverPath)) { return new XWPFDocument(is); } } // 填充数据并设置保护 public static void generateProtectedDocument(XWPFDocument doc, Map<String, String> data) { // 1. 填充数据到内容控件 fillDataToContentControls(doc, data); // 2. 设置文档保护 doc.enforceProtection("templateLock2023", EnumSet.of(ProtectionType.READ_ONLY, ProtectionType.EDITING)); } // 填充数据到内容控件 private static void fillDataToContentControls(XWPFDocument doc, Map<String, String> data) { // 遍历所有段落 for (XWPFParagraph para : doc.getParagraphs()) { processParagraph(para, data); } // 遍历所有表格 for (XWPFTable table : doc.getTables()) { for (XWPFTableRow row : table.getRows()) { for (XWPFTableCell cell : row.getTableCells()) { for (XWPFParagraph para : cell.getParagraphs()) { processParagraph(para, data); } } } } } // 处理段落中的内容控件 private static void processParagraph(XWPFParagraph para, Map<String, String> data) { for (XWPFSDT sdt : para.getSDTs()) { CTSdtPr pr = sdt.getCTSDT().getSdtPr(); if (pr != null) { CTString tag = pr.getTag(); if (tag != null) { String tagValue = tag.getVal(); // 替换内容控件中的占位符 if (data.containsKey(tagValue)) { replaceSDTContent(sdt, data.get(tagValue)); } // 设置模板区域的保护 setProtectionProperties(pr, tagValue); } } } } // 设置内容控件的保护属性 private static void setProtectionProperties(CTSdtPr pr, String tag) { CTLock lock = pr.isSetLock() ? pr.getLock() : pr.addNewLock(); if (tag.startsWith("TEMPLATE_")) { // 模板区域:完全锁定 lock.setVal(STLock.EDITING_PROTECTED); lock.setVal(STLock.SDT_LOCKED); } else if (tag.startsWith("DATA_")) { // 数据区域:允许编辑内容但禁止删除控件 lock.setVal(STLock.CONTENT_LOCKED); } } // 替换内容控件中的文本 private static void replaceSDTContent(XWPFSDT sdt, String value) { // 清空原有内容 CTSdtContent content = sdt.getCTSDT().getSdtContent(); if (content.sizeOfPArray() > 0) { content.removeP(0); } // 添加新内容 XWPFParagraph newPara = new XWPFParagraph(content.addNewP(), sdt.getBody()); XWPFRun run = newPara.createRun(); run.setText(value); run.setColor("0000FF"); // 蓝色文本标识可编辑区域 } // 保存生成的文档 public static void saveDocument(XWPFDocument doc, String outputPath) throws IOException { try (FileOutputStream out = new FileOutputStream(outputPath)) { doc.write(out); } } // 主流程 public static void main(String[] args) { try { // 1. 从服务器加载模板 String serverTemplatePath = "/opt/templates/contract_template.docx"; XWPFDocument doc = loadTemplate(serverTemplatePath); // 2. 准备填充数据 Map<String, String> data = new HashMap<>(); data.put("DATA_CUSTOMER_NAME", "张三科技有限公司"); data.put("DATA_SIGN_DATE", "2023年10月25日"); data.put("DATA_CONTRACT_VALUE", "¥1,200,000.00"); // 3. 生成保护文档 generateProtectedDocument(doc, data); // 4. 保存文档 saveDocument(doc, "generated_contract.docx"); System.out.println("文档生成成功!模板区域已锁定,数据区域可编辑"); } catch (Exception e) { e.printStackTrace(); } } } ``` ### 模板设计规范(需预先在Word中设置) 1. **模板区域**(不可编辑): - 添加内容控件 - 设置Tag以`TEMPLATE_`开头(如`TEMPLATE_CLAUSE1`) - 在Word中右键控件 → 属性 → 勾选"内容被编辑后无法删除此内容控件" 2. **数据区域**(可编辑): - 添加内容控件 - 设置Tag以`DATA_`开头(如`DATA_CUSTOMER_NAME`) - 不勾选锁定选项 ![模板设计示例](https://via.placeholder.com/600x300?text=Word内容控件设置界面) ### 服务器文件路径配置 参考引用[3],实现跨操作系统的路径处理: ```java public class ServerConfig { public static String getTemplatePath(String filename) { Properties prop = System.getProperties(); String os = prop.getProperty("os.name").toLowerCase(); String basePath = os.contains("win") ? "C:/server/templates/" : "/opt/templates/"; return basePath + filename; } } // 使用方式 String templatePath = ServerConfig.getTemplatePath("contract.docx"); ``` ### 保护机制说明 1. **分层保护模型**: $$ \text{文档安全} = \underbrace{\text{密码保护}}_{\text{文档级}} + \underbrace{\text{内容控件}}_{\text{元素级}} $$ 2. **保护类型对照表**: | 区域类型 | 锁定属性 | 用户权限 | |----------|----------|----------| | 模板区域 | `EDITING_PROTECTED` | 不可编辑/不可删除 | | 数据区域 | `CONTENT_LOCKED` | 可编辑/不可删除 | | 文档整体 | `READ_ONLY` | 仅允许编辑内容控件 | 3. **技术原理**: ```mermaid graph LR A[服务器模板] --> B[读取.docx文件] B --> C{识别内容控件} C -->|TEMPLATE_前缀| D[设置完全锁定] C -->|DATA_前缀| E[填充数据+部分锁定] D --> F[应用文档保护] E --> F F --> G[生成最终文档] ``` ### 进阶功能扩展 #### 1. 动态表格生成 ```java private static void fillDynamicTable(XWPFDocument doc, List<Map<String, String>> tableData) { // 定位模板中的表格控件 XWPFSDT tableSdt = findSDTByTag(doc, "DATA_PRODUCT_TABLE"); // 清空原有内容 clearSDTContent(tableSdt); // 创建新表格 XWPFTable table = tableSdt.getContent().addTable(); // 添加表头 XWPFTableRow headerRow = table.createRow(); headerRow.getCell(0).setText("产品名称"); headerRow.addNewTableCell().setText("数量"); headerRow.addNewTableCell().setText("单价"); // 填充数据行 for (Map<String, String> rowData : tableData) { XWPFTableRow dataRow = table.createRow(); dataRow.getCell(0).setText(rowData.get("product")); dataRow.getCell(1).setText(rowData.get("quantity")); dataRow.getCell(2).setText(rowData.get("price")); } } ``` #### 2. 图片插入保护 ```java private static void insertProtectedImage(XWPFDocument doc, String imagePath) throws Exception { // 创建图片内容控件 CTSdtBlock block = doc.getDocument().getBody().addNewSdt(); CTSdtPr pr = block.addNewSdtPr(); pr.addNewTag().setVal("TEMPLATE_COMPANY_LOGO"); // 设置保护 CTLock lock = pr.addNewLock(); lock.setVal(STLock.SDT_LOCKED); // 插入图片 try (InputStream is = new FileInputStream(imagePath)) { CTSdtContent content = block.addNewSdtContent(); XWPFParagraph para = new XWPFParagraph(content.addNewP(), doc); XWPFRun run = para.createRun(); run.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, "logo.png", Units.toEMU(100), Units.toEMU(50)); } } ``` ### 部署和使用说明 1. **Maven依赖**: ```xml <dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>5.1.1</version> </dependency> </dependencies> ``` 2. **操作流程**: ```mermaid sequenceDiagram 用户->>服务器: 请求生成文档 服务器->>模板库: 获取模板.docx 服务器->>数据库: 查询业务数据 服务器->>POI引擎: 填充数据+设置保护 服务器->>用户: 返回受保护文档 用户->>Word: 在蓝色区域编辑数据 ``` 3. **使用效果**: - 模板区域:红色文本,不可编辑(光标无法进入) - 数据区域:蓝色文本,可直接修改内容 - 文档整体:保存时无需密码,但修改保护设置需要密码"templateLock2023" ### 技术优势 1. **模板与数据分离**: $$ \text{文档} = \underbrace{\text{模板}}_{\text{服务器只读}} + \underbrace{\text{数据}}_{\text{动态填充}} $$ 2. **高效处理大文件**: - 使用SAX解析减少内存占用 - 仅修改内容控件区域,保持文档结构完整 3. **企业级特性**: - 支持文档版本控制 - 自动记录生成日志 - 集成数字签名验证 此方案完整实现了从服务器读取模板、动态填充数据并设置差异化保护的需求,确保核心业务逻辑的安全性,同时提供灵活的数据编辑能力。
最新发布
12-03
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值