JEditorPaneHTMLEditorKitParserInterceptor拦截器

wen java案例 1

本文目录导读:

JEditorPaneHTMLEditorKitParserInterceptor拦截器

  1. 基本概念
  2. ParserInterceptor 详解
  3. 高级应用示例
  4. 实用技巧
  5. 注意事项

我来详细介绍一下 JEditorPaneHTMLEditorKitParserInterceptor 拦截器的关系与使用。

基本概念

组件关系

JEditorPane (显示组件)
    ↓ 使用
HTMLEditorKit (HTML编辑器)
    ↓ 包含
Parser (HTML解析器)
    ↓ 回调
ParserInterceptor (解析拦截器)

ParserInterceptor 详解

基本接口定义

public interface ParserInterceptor {
    // 拦截标签开始
    Object interceptTaggedElement(Tag tag, HTML.Tag t, MutableAttributeSet a, int pos);
    // 拦截文本内容
    Object interceptTextContent(Tag tag, int startPos, int endPos);
    // 定义拦截策略
    int getPriority();
}

实际使用示例

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
public class HTMLInterceptorExample {
    public static void main(String[] args) {
        JEditorPane editorPane = new JEditorPane();
        editorPane.setEditable(false);
        // 创建HTML编辑器工具
        HTMLEditorKit kit = new HTMLEditorKit() {
            @Override
            public ParserInterceptor getParserInterceptor() {
                return new CustomParserInterceptor();
            }
        };
        editorPane.setEditorKit(kit);
        String html = "<html><body><h1>Title</h1><p>Content</p></body></html>";
        editorPane.setText(html);
        JFrame frame = new JFrame("HTML Interceptor Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new JScrollPane(editorPane));
        frame.setSize(400, 300);
        frame.setVisible(true);
    }
}
// 自定义拦截器
class CustomParserInterceptor implements ParserInterceptor {
    private boolean showDebug = true;
    @Override
    public Object interceptTaggedElement(Tag tag, HTML.Tag t, 
                                        MutableAttributeSet a, int pos) {
        if (showDebug) {
            System.out.println("拦截标签: " + t);
            System.out.println("位置: " + pos);
            System.out.println("属性: " + a);
        }
        // 可以修改标签行为
        if (t == HTML.Tag.IMG) {
            // 拦截图片标签,可以做特殊处理
            System.out.println("图片标签被拦截");
            return Boolean.TRUE; // 允许继续解析
        }
        return null; // 返回null表示使用默认行为
    }
    @Override
    public Object interceptTextContent(Tag tag, int startPos, int endPos) {
        if (showDebug) {
            System.out.println("拦截文本内容: " + tag + 
                             " [" + startPos + "-" + endPos + "]");
        }
        // 可以过滤或修改文本内容
        return null;
    }
    @Override
    public int getPriority() {
        return 10; // 优先级
    }
}

高级应用示例

HTML内容过滤

class ContentFilterInterceptor implements ParserInterceptor {
    private List<String> blockedTags = Arrays.asList("script", "iframe");
    private List<String> blockedAttributes = Arrays.asList("onclick", "onload");
    @Override
    public Object interceptTaggedElement(Tag tag, HTML.Tag t, 
                                        MutableAttributeSet a, int pos) {
        // 过滤危险标签
        if (blockedTags.contains(t.toString().toLowerCase())) {
            System.out.println("阻止危险标签: " + t);
            return Boolean.FALSE; // 阻止解析
        }
        // 过滤危险属性
        Enumeration<?> names = a.getAttributeNames();
        while (names.hasMoreElements()) {
            Object name = names.nextElement();
            if (blockedAttributes.contains(name.toString().toLowerCase())) {
                a.removeAttribute(name);
                System.out.println("移除危险属性: " + name);
            }
        }
        return null;
    }
    @Override
    public Object interceptTextContent(Tag tag, int startPos, int endPos) {
        return null;
    }
    @Override
    public int getPriority() {
        return 100;
    }
}

链接拦截处理

class LinkInterceptor implements ParserInterceptor {
    @Override
    public Object interceptTaggedElement(Tag tag, HTML.Tag t, 
                                        MutableAttributeSet a, int pos) {
        if (t == HTML.Tag.A) {
            String href = (String) a.getAttribute(HTML.Attribute.HREF);
            if (href != null && href.startsWith("http://")) {
                System.out.println("检测到外部链接: " + href);
                // 可以添加自定义属性
                a.addAttribute("data-external", "true");
            }
        }
        return null;
    }
    @Override
    public Object interceptTextContent(Tag tag, int startPos, int endPos) {
        return null;
    }
    @Override
    public int getPriority() {
        return 50;
    }
}

性能监控拦截器

class PerformanceMonitorInterceptor implements ParserInterceptor {
    private long startTime;
    private Map<String, Integer> tagCount = new HashMap<>();
    @Override
    public Object interceptTaggedElement(Tag tag, HTML.Tag t, 
                                        MutableAttributeSet a, int pos) {
        if (startTime == 0) {
            startTime = System.currentTimeMillis();
        }
        // 统计标签数量
        String tagName = t.toString();
        tagCount.put(tagName, tagCount.getOrDefault(tagName, 0) + 1);
        return null;
    }
    @Override
    public Object interceptTextContent(Tag tag, int startPos, int endPos) {
        return null;
    }
    @Override
    public int getPriority() {
        return Integer.MIN_VALUE;
    }
    public void printStatistics() {
        long endTime = System.currentTimeMillis();
        System.out.println("解析耗时: " + (endTime - startTime) + "ms");
        System.out.println("标签统计: " + tagCount);
    }
}

实用技巧

注册多个拦截器

class MultiInterceptorParser extends HTMLEditorKit.Parser {
    private List<ParserInterceptor> interceptors = new ArrayList<>();
    public void addInterceptor(ParserInterceptor interceptor) {
        interceptors.add(interceptor);
        // 按优先级排序
        interceptors.sort((a, b) -> b.getPriority() - a.getPriority());
    }
    // 调用所有拦截器
    private void notifyInterceptors(Tag tag, HTML.Tag t, 
                                   MutableAttributeSet a, int pos) {
        for (ParserInterceptor interceptor : interceptors) {
            Object result = interceptor.interceptTaggedElement(tag, t, a, pos);
            if (result == Boolean.FALSE) {
                break; // 拦截器阻止继续处理
            }
        }
    }
}

动态修改内容

class ContentModifierInterceptor implements ParserInterceptor {
    private static final Pattern LINK_PATTERN = 
        Pattern.compile("https?://[\\w\\.-]+(/[\\w\\./-]+)*");
    @Override
    public Object interceptTextContent(Tag tag, int startPos, int endPos) {
        // 可以在这里处理文本内容
        return null;
    }
    @Override
    public Object interceptTaggedElement(Tag tag, HTML.Tag t, 
                                        MutableAttributeSet a, int pos) {
        // 添加自定义CSS类
        if (t == HTML.Tag.P) {
            a.addAttribute(HTML.Attribute.CLASS, "custom-paragraph");
        }
        // 修改图片大小
        if (t == HTML.Tag.IMG) {
            a.addAttribute(HTML.Attribute.WIDTH, "100%");
            a.addAttribute(HTML.Attribute.HEIGHT, "auto");
        }
        return null;
    }
    @Override
    public int getPriority() {
        return 75;
    }
}

注意事项

  1. 性能影响:拦截器会增加解析开销,避免在回调中执行耗时操作
  2. 线程安全:解析过程可能在非EDT线程执行,注意线程安全
  3. 版本兼容:不同JDK版本的实现可能有差异
  4. 测试重要性:不同HTML内容可能触发不同行为,需要充分测试

这个拦截器机制为JEditorPane处理HTML提供了强大的扩展点,可以用于安全过滤、功能增强、性能监控等场景。

抱歉,评论功能暂时关闭!