Custom XML encoder with Axis 1 and Tomcat
The documentation on this page indicates that I can override Axis's default XML encoder b开发者_如何学Goy providing a file with this path:
myapp.war/META-INF/services/org.apache.axis.components.encoding.XMLEncoder
The file contents of this file are:
com.myapp.CustomEncoder
Where com.myapp.Customer is in myapp.war/WEB-INF/classes/com/myapp/CustomEncoder.class.
Note that myapp.war is actually exploded as a full directory when I deploy but I don't think that should make a difference.
In any case, this doesn't seem to work on Apache Tomcat 7.0 but strangely enough does work on JBoss 4.2.3. Alternatively I tried setting a system property by adding this to Tomcat's startup script:
-Dorg.apache.axis.components.encoding.XMLEncoder=com.myapp.CustomEncoder
Still not seeing my CustomEncoder code being called, and only on Tomcat. Why should this work on JBoss and not Tomcat? Is the classpath different somehow on Tomcat? How can I make this work?
Thanks.
---- Update ----
Since it was mentioned, the source code that seems to load the custom provider appears to exist in org.apache.axis.components.encoding.XMLEncoderFactory:
public static final String ENCODING_UTF_8 = "UTF-8";
public static final String ENCODING_UTF_16 = "UTF-16";
public static final String DEFAULT_ENCODING = ENCODING_UTF_8;
private static Map encoderMap = new HashMap();
private static final String PLUGABLE_PROVIDER_FILENAME = "org.apache.axis.components.encoding.XMLEncoder";
static {
encoderMap.put(ENCODING_UTF_8, new UTF8Encoder());
encoderMap.put(ENCODING_UTF_16, new UTF16Encoder());
encoderMap.put(ENCODING_UTF_8.toLowerCase(), new UTF8Encoder());
encoderMap.put(ENCODING_UTF_16.toLowerCase(), new UTF16Encoder());
try {
loadPluggableEncoders();
} catch (Throwable t){
String msg=t + JavaUtils.LS + JavaUtils.stackToString(t);
log.info(Messages.getMessage("exception01",msg));
}
}
...
/**
Look for file META-INF/services/org.apache.axis.components.encoding.XMLEncoder
in all the JARS, get the classes listed in those files and add them to
encoders list if they are valid encoders.
Here is how the scheme would work.
A company providing a new encoder will jar up their encoder related
classes in a JAR file. The following file containing the name of the new
encoder class is also made part of this JAR file.
META-INF/services/org.apache.axis.components.encoding.XMLEncoder
By making this JAR part of the webapp, the new encoder will be
automatically discovered.
*/
private static void loadPluggableEncoders() {
ClassLoader clzLoader = XMLEncoder.class.getClassLoader();
ClassLoaders loaders = new ClassLoaders();
loaders.put(clzLoader);
DiscoverServiceNames dsn = new DiscoverServiceNames(loaders);
ResourceNameIterator iter = dsn.findResourceNames(PLUGABLE_PROVIDER_FILENAME);
while (iter.hasNext()) {
String className = iter.nextResourceName();
try {
Object o = Class.forName(className).newInstance();
if (o instanceof XMLEncoder) {
XMLEncoder encoder = (XMLEncoder) o;
encoderMap.put(encoder.getEncoding(), encoder);
encoderMap.put(encoder.getEncoding().toLowerCase(), encoder);
}
} catch (Exception e) {
String msg = e + JavaUtils.LS + JavaUtils.stackToString(e);
log.info(Messages.getMessage("exception01", msg));
continue;
}
}
}
Just for fun, I tried packaging up META-INF/services/org.apache.axis.components.encoding.XMLEncoder in a separate jar and storing it in myapp.war/WEB-INF/lib; still nothing.
I don't get it.
make new project say encoder which contain your custom encoder then make it jar.Under jar under meta -inf create services folder and under it create file org.apache.axis.components.encoding.XMLEncoder and in this file mention your class name of your encoder (fully qualified) .place this jar in your class path .
精彩评论