【问题标题】:How do I get URLs of other servlets from within a servlet如何从 servlet 中获取其他 servlet 的 URL
【发布时间】:2009-07-31 09:00:39
【问题描述】:

我有两个 servlet(S1 和 S2)。 S1 呈现一个通过 URL (img src="URL") 访问 S2 的 HTML 页面。我知道 S2 的 servlet 名称,但不知道 URL。 URL 当然是在 web.xml 中配置的,但是如何从 S1 访问呢?

【问题讨论】:

  • 为什么必须在运行时得到这个?这不能是一个修复映射,你把它硬编码到 S1 servlet 中吗?
  • 这整件事没有多大意义。你可以发布你的 web.xml 吗?第二个 servlet (S2) 是否返回图像?除非 S2 映射到一个完整的随机上下文,否则您可以像 Nick Holt 发布的那样使用:“/S2”

标签: java servlets


【解决方案1】:

用途:

HttpServletResponse.encodeURL(String)

在你的情况下应该是这样的:

response.encodeURL("/S2");

此方法将负责维护会话状态所需的任何 URL 重写,我认为会将必要的路径信息添加到 URL。

这些天我使用 JSTL,所以我对最后一点有点生疏,但如果路径信息没有预先添加,您可以从请求中获取并自己添加。

【讨论】:

  • 我认为我们中的一个人把问题弄错了。我是这样理解的:他想在 HTML 页面中呈现指向名为“S2”的 servlet 的 URL。他需要阅读 S2 的映射,因为它可以是任何东西,例如“/something/*”。
  • 是的,看起来像这样:-z 为了避免对 URL 进行硬编码,我会使用一个 servlet 属性文件来指定 URL(或其中的一部分),但我怀疑硬编码路由会在这种情况下工作。
【解决方案2】:

我猜想,ServletConfig 的大多数实现都包含映射信息(org.apache.catalina.core.StandardWrapper 确实如此),但由于 ServletConfig-Interface 不提供 getter,你必须做一些获取它并将您的应用程序绑定到特定实现或应用程序服务器的技巧。

也许您只是从 web.xml 中读取它。只需选择具有给定“servlet-name”的所有“servlet-mapping”元素并阅读“url-pattern”。由于这是规范中的内容,因此应该可以在任何应用服务器上运行。

编辑:

这是一个肮脏的例子。使用 refelction 获取 URL 映射:

@Override
public void init(ServletConfig config) throws ServletException {
    super.init(config);

    try {

        Class<?> clazz = config.getClass();
        Field configField = clazz.getDeclaredField("config");
        configField.setAccessible(true);
        StandardWrapper standardWrapper = (StandardWrapper) configField.get(config);

        clazz = standardWrapper.getClass();
        Field mappingsField = clazz.getDeclaredField("mappings");
        mappingsField.setAccessible(true);
        List<?> mappings = (List<?>) mappingsField.get(standardWrapper);

        System.out.println(mappings);

    }catch (Exception e) {
        logger.error("", e);
    }
}

这适用于我的 JSF、Tomcat 环境。 config 对象是“org.apache.catalina.core.StandardWrapperFacade”,并有一个名为“config”的字段,其中包含一个“org.apache.catalina.core.StandardWrapper”,其中有一个名为“mappings”的字段。

但正如我所说,这是一个肮脏的黑客!

【讨论】:

    【解决方案3】:

    也许您应该将第二个 servlet 的 URL 作为 servlet 参数提供给第一个。我意识到这意味着在 web.xml 中编码 URL 两次 (我真的很讨厌),但是为了避免问题,您始终可以将 web.xml 构建为构建的一部分,并从属性中填充文件。

    有点讨厌和繁琐,我很欣赏,但在没有任何跨容器 API 解决方案的情况下,也许它是最实用的解决方案。

    【讨论】:

    • 我最终遇到了类似的问题。同意这是 hokey,但迄今为止我发现的唯一 servlet-standards-complaint 方式。我不明白他们为什么不将 servlet 映射信息作为标准 ServletConfig 或 ServletContext 的一部分,因为 web.xml 格式是同一标准的一部分。
    【解决方案4】:

    您可以在您的 doGet() 或 doPost() 方法中轻松完成以下是要在 servlet 的 doGet() 或 doPost() 方法中编写的代码,以获取与 servlet 关联的映射。

    public void doGet(HttpServletRequest request,HttpServletResponse response){
    
    String nameOfServlet = "S2";
    
    ServletContext context = getServletContext();
    
    String[] mappinggs=context.getServletRegistration(nameOfServlet).getMappings().toArray();
    
    //mappings will contain all the mappings associated with servlet "S2"
    
    //print take the first one if there is only one mapping 
    
    System.out.println(mappings[0]);
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-10
      • 2014-06-02
      • 2011-10-31
      • 2012-05-24
      • 1970-01-01
      • 2013-04-20
      • 2011-07-23
      • 1970-01-01
      相关资源
      最近更新 更多