栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

不使用NamespacePrefixMapper定义Spring JAXB名称空间

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

不使用NamespacePrefixMapper定义Spring JAXB名称空间

[提供JAXB-RI替代品的一些编辑在本文的结尾]

在花了很多力气之后,我终于不得不接受针对我的环境(在Windows XP上为JDK1.6.0_12,在Mac
Leopard上为JDK1.6.0_20),我只是在不诉诸于NamespacePrefixMapper这个邪恶的前提下才能完成这项工作。为什么它是邪恶的?因为它强制您的生产代码中依赖内部JVM类。这些类不构成JVM与您的代码之间可靠接口的一部分(即,它们在JVM更新之间进行更改)。

我认为Sun应该解决此问题,或者有更深入知识的人可以添加此答案-请这样做!

继续。因为不应在JVM外部使用NamespacePrefixMapper,所以它不包含在javac的标准编译路径(由ct.sym控制的rt.jar的子部分)中。这意味着任何依赖于它的代码都可以在IDE中正常编译,但是在命令行(例如Maven或Ant)失败。为了克服这个问题,必须在构建中显式包含rt.jar文件,即使在路径中包含空格的情况下,Windows似乎也会遇到麻烦。

如果您处于这个位置,那么以下是Maven片段,它将帮助您摆脱麻烦:

<dependency>  <groupId>com.sun.xml.bind</groupId>  <artifactId>jaxb-impl</artifactId>  <version>2.1.9</version>  <scope>system</scope>  <!-- Windows will not find rt.jar if it is in a path with spaces -->  <systemPath>C:/temp/rt.jar</systemPath></dependency>

注意rt.jar到一个奇怪的地方的垃圾硬编码路径。您可以使用{java.home}
/lib/rt.jar的组合来解决此问题,该组合在大多数操作系统上都可以使用,但是由于Windows空间问题,不能保证。是的,您可以使用配置文件并进行相应的激活…

或者,在Ant中,您可以执行以下操作:

<path id="jre.classpath">  <pathelement location="${java.home}lib" /></path>// Add paths for build.classpath and define {src},{target} as usual<target name="compile" depends="copy-resources">  <mkdir dir="${target}/classes"/>  <javac bootclasspathref="jre.classpath" includejavaruntime="yes" debug="on" srcdir="${src}" destdir="${target}/classes" includes="**/*">    <classpath refid="build.classpath"/>  </javac></target>

以及Jaxb2Marshaller Spring的配置是什么?好的,这里是我自己的NamespacePrefixMapper:

弹簧:

<!-- JAXB2 marshalling (domain objects annotated with JAXB2 meta data) --><bean id="jaxb2Marshaller" ><property name="contextPaths">  <list>    <value>org.example.domain</value>  </list></property><property name="marshallerProperties">  <map>    <!-- Good for JDK1.6.0_6+, lose 'internal' for earlier releases - see why it's evil? -->    <entry key="com.sun.xml.internal.bind.namespacePrefixMapper" value-ref="myCapabilitiesNamespacePrefixMapper"/>    <entry key="jaxb.formatted.output"><value type="boolean">true</value></entry>  </map></property></bean><!-- Namespace mapping prefix (ns1->abc, ns2->xlink etc) --><bean id="myNamespacePrefixMapper" />

然后是我的NamespacePrefixMapper代码:

public class MyNamespacePrefixMapper extends NamespacePrefixMapper {  public String getPreferredPrefix(String namespaceUri,         String suggestion,         boolean requirePrefix) {    if (requirePrefix) {      if ("http://www.example.org/abc".equals(namespaceUri)) {        return "abc";      }      if ("http://www.w3.org/1999/xlink".equals(namespaceUri)) {        return "xlink";      }      return suggestion;    } else {      return "";    }  }}

好吧。我希望这可以帮助某人避免我经历的痛苦。哦,顺便说一句,如果您在Jetty中使用上述邪恶方法,则可能会遇到以下异常:

java.lang.IllegalAccessError:类sun.reflect.GeneratedConstructorAccessor23无法访问其超类sun.reflect.ConstructorAccessorImpl

真是太幸运了,整理出一个。提示:Web服务器的引导类路径中的rt.jar。

[进行额外编辑以显示JAXB-RI(参考实现)方法]

如果您能够在代码中引入JAXB-RI库,则可以进行以下修改以获得相同的效果:

主要:

// Add a new property that implies external accessmarshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new MyNamespacePrefixMapper());

MyNamespacePrefixMapper:

// Change the import to thisimport com.sun.xml.bind.marshaller.NamespacePrefixMapper;

从/ lib文件夹中添加JAXB-RI下载中的以下JAR(跳过许可环后):

jaxb-impl.jar

运行Main.main()会产生所需的输出。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/486892.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号