You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat9 Axis环境下SOAP服务无法写入XML文件问题咨询

写入失败的核心原因
  • ClassLoader.getResource()本质是读取类路径下的只读资源,返回的URL对应Tomcat部署的war包内部路径,不管war包是否解压,该路径默认仅支持读操作,不支持写入。你读取逻辑走的是只读的openStream(),所以正常,写入时调用URLConnection的getOutputStream()会被JVM拒绝,你捕获的InvocationTargetException是Axis反射调用服务方法的外层包装异常,查看e.getCause()即可看到底层的IO不支持写入错误。
  • 即便部分测试环境下Tomcat解压了war包,WEB-INF目录对Tomcat运行用户一般也仅开放读权限,没有写入权限,也会触发写入失败。
  • 如果是写入新的XML文件,getResource()会直接返回null,后续调用openConnection()会触发空指针异常,也是常见报错原因。
  • 额外注意:WEB-INF属于应用部署目录,每次重新部署war包都会清空覆盖该目录下的所有内容,即便临时写入成功,重启或者重新部署应用后写入的文件也会全部丢失,不适合存储业务数据。
正确实现方案

不要通过ClassLoader操作可写入的业务文件,选择服务器上独立于Tomcat部署目录的专属路径存储XML文件,比如/data/app_business/xml/(Windows环境可以配置D:/app_business/xml/),将该路径配置为应用的可配置常量,直接用标准文件IO进行读写即可。

示例代码如下:

写入方法

// 配置项,可从properties配置文件/web.xml上下文参数中读取
private static final String XML_STORAGE_PATH = "/data/app_business/xml/";

public boolean serialize(Station s) {
    File xmlFile = new File(XML_STORAGE_PATH, s.getName() + ".xml");
    // 自动创建不存在的父目录
    if (!xmlFile.getParentFile().exists()) {
        xmlFile.getParentFile().mkdirs();
    }
    try (OutputStream out = new FileOutputStream(xmlFile);
         XMLEncoder encoder = new XMLEncoder(out)) {
        encoder.writeObject(s);
        return true;
    } catch (Exception e) {
        Main.LOGGER.info("Station serialization was not successful!", e);
        return false;
    }
}

对应读取方法(也同步修改为从独立目录读取,保持路径一致)

public Station deserialization(String name) {
    File xmlFile = new File(XML_STORAGE_PATH, name + ".xml");
    if (!xmlFile.exists()) {
        Main.LOGGER.info("Station XML file not found: " + name);
        return null;
    }
    try (InputStream is = new FileInputStream(xmlFile);
         XMLDecoder decoder = new XMLDecoder(is)) {
        return (Station) decoder.readObject();
    } catch (Exception e) {
        Main.LOGGER.info("Station deserializaton was not successful!", e);
        return null;
    }
}

如果确实有临时写入WEB-INF目录的需求(非常不推荐),可以通过ServletContext的getRealPath()方法获取磁盘真实路径后再做文件操作,注意该方法在Tomcat配置unpackWARs="false"时会返回null,且部署时文件会丢失:

// Axis环境可从MessageContext获取ServletContext实例
String realXmlPath = servletContext.getRealPath("/WEB-INF/resources/" + s.getName() + ".xml");
File xmlFile = new File(realXmlPath);
// 后续IO逻辑和上面示例一致

内容的提问来源于stack exchange,提问作者Aleksandar Cvisic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:42:00