Wicket中使用use标签加载SVG Sprite报错的解决方案问询
Wicket框架加载SVG Sprite资源的实现方案
原有写法失效原因
- 直接给
<use>标签绑定Image组件报错:Wicket内置Image组件的渲染目标仅为<img>标签,不支持<svg>内嵌<use>元素的资源绑定逻辑 - 路径带
#抛出解析错误/访问拒绝:Wicket资源加载逻辑会将#识别为URL片段分隔符,若将#spriteName写在资源路径参数中,会被判定为非法资源路径触发安全拦截,且不会自动将锚点拼接到最终渲染的资源地址后 - 用
<img>标签加载失效:<img>标签本身不支持解析SVG文件内的锚点片段,只能加载完整SVG文件,天生无法用于SVG Sprite单符号引用场景
注意:问题描述里的wicked:id为笔误,Wicket组件绑定的正确属性为wicket:id
可运行实现代码
方案1:资源存放在webapp上下文目录(对应原ContextRelativeResource写法)
HTML模板代码:
<svg class="icon"> <use wicket:id="myResSprite"></use> </svg>
Java逻辑:
@Override protected void onInitialize() { super.onInitialize(); // 仅加载sprite文件本身,路径不要带#和后续的Sprite标识 ContextRelativeResource spriteFile = new ContextRelativeResource("images/mysprite.svg"); CharSequence spriteBaseUrl = urlFor(spriteFile, null); WebMarkupContainer spriteUse = new WebMarkupContainer("myResSprite"); // 手动拼接Sprite锚点,同时兼容新旧浏览器的属性写法 spriteUse.add(AttributeModifier.replace("xlink:href", spriteBaseUrl + "#someSprite")); spriteUse.add(AttributeModifier.replace("href", spriteBaseUrl + "#someSprite")); add(spriteUse); }
方案2:资源存放在类路径resources目录(对应原PackageResourceReference写法)
HTML模板和方案1一致,Java逻辑调整为:
@Override protected void onInitialize() { super.onInitialize(); // 资源路径仅指向sprite文件本身,不要携带#片段 PackageResourceReference spriteRef = new PackageResourceReference(YourPageClass.class, "images/mysprite.svg"); CharSequence spriteBaseUrl = urlFor(spriteRef, null); WebMarkupContainer spriteUse = new WebMarkupContainer("myResSprite"); spriteUse.add(AttributeModifier.replace("xlink:href", spriteBaseUrl + "#someSprite")); spriteUse.add(AttributeModifier.replace("href", spriteBaseUrl + "#someSprite")); add(spriteUse); }
额外说明
- Wicket 9+版本的现代浏览器环境下,可以省略
xlink:href属性,仅保留href属性即可正常渲染 - 不需要自定义专门的Sprite资源组件,核心逻辑就是先拿到Sprite文件的合法Wicket资源URL,再手动拼接Sprite锚点赋值给
<use>标签的对应属性,避开Wicket资源解析器对#的拦截逻辑
内容的提问来源于stack exchange,提问作者Uwe Hafner
相关产品推荐
相关产品推荐

