【问题标题】:How to set dynamically scheme attribute in s:url tag?如何在 s:url 标签中动态设置方案属性?
【发布时间】:2013-03-22 11:45:18
【问题描述】:

我正在尝试使用scheme 属性使用s:url 标记构建一些URL,其值会根据某些条件动态变化(例如,对于某些请求,将使用httphttps 构建相同的URL对于其他一些人)。对于给定的请求,应用程序中的所有s:url 都将使用httphttps 构建。

我已经编写了此条件的逻辑并将要使用的架构(httphttps)存储为我的操作中的字符串字段,但似乎我不能在 scheme 属性中使用表达式s:url 标签:

当我尝试使用以此构建的 URL 呈现 HTML 锚点时:

<s:url scheme="%{myScheme}" id="myUrl" action="MyAction" includeParams="none">
   <s:param name="someParam" value="blah"/>
</s:url>

<s:a href="%{myUrl}">click me</s:a>

我明白了:

<a href="%{myScheme}://myhost.com/mywebapp/MyAction.action?someParam=blah">click me</a>

还尝试做一件丑陋的事情,即使不使用实际的操作属性(如果有效,我会更改实际值的文字)。尝试使用脚本:

<s:url scheme="<%= "https" %>" id="myUrl" action="MyAction" includeParams="none">
   <s:param name="someParam" value="blah"/>
</s:url>

但是收到了500 错误和这条日志消息:

org.apache.jasper.JasperException: /path/to/my/file.jsp(123,456) According to TLD or attribute directive in tag file, attribute scheme does not accept any expressions

我也尝试了以下丑陋的选项,但没有奏效:

<s:url scheme="<s:property value="myScheme"/>" id="myUrl" action="MyAction" includeParams="none">
   <s:param name="someParam" value="blah"/>
</s:url>

和:

<s:url scheme="<c:out value="${myScheme}"/>" id="myUrl" action="MyAction" includeParams="none">
   <s:param name="someParam" value="blah"/>
</s:url>

所以我没有主意了。有人遇到同样的问题吗?问题的其余部分解释了为什么我需要这样做:

我的应用程序位于接收 HTTPS 请求的负载平衡器后面,但使用 HTTP 将它们转发到应用程序服务器,然后使用 HTTPS 将响应发送回互联网。所以应用服务器总是收到HTTP 流量。

应用程序中的链接必须在通过负载均衡器请求时使用 https 方案生成(这样互联网上的用户将受到保护),在直接请求时使用 http(当我们的开发人员需要访问我们内部的特定前端时)内部网络)。我无法控制服务器配置,也无法对系统管理员产生太大影响,因此更改服务器或网络配置似乎相当成问题。

更新

似乎如果我扩展 org.apache.struts2.components.ServletUrlRenderer Struts2 类覆盖 renderUrl 方法,我将能够做我想做的事。但我不知道如何告诉 Struts2 使用我的自定义实现 UrlRenderer 而不是默认的 ServletUrlRenderer

【问题讨论】:

    标签: java http https struts2


    【解决方案1】:

    当我更新问题时,我找到了答案。

    我的发现是:

    • s:url 标签中的scheme 属性不支持表达式,只支持文字值。
    • 我需要更改 Struts2 的默认行为。

    所以我做了什么:

    • 删除了我的应用程序中所有 JSP 中所有 s:url 标记中的所有 scheme 属性。
    • 使用自定义类实现UrlRenderer,几乎使用了ServletUrlRenderer 的副本。我更改了renderUrl 方法检索方案默认值的行:String scheme = ActionContext.getContext().getValueStack().findString("scheme");。这会将方案的默认值设置为当前操作的“方案”属性。
    • 将以下属性添加到struts.properties。这个属性告诉 Struts2 使用我的自定义实现:

    struts.urlRenderer = fully.qualified.name.for.my.CustomUrlRendererImplementation

    此解决方案引入了可维护性问题,因为我从 Struts 2.3.8 版本中复制粘贴了一些代码。如果有人提供更好的解决方案,我很乐意对其进行测试:)

    【讨论】:

    • 这可能是应用程序中的安全漏洞。最好在 标签中请求更改。
    • @LukaszLenart 感谢您的评论。我正在考虑更改要使用的协议的存储位置,因此使用“方案”参数发出的任何请求都不会改变应用程序的预期行为。无论如何,我受系统管理员和 CIO 制定的指导方针的约束,所以我只是想确保我的应用程序生成“https”链接,尽管架构不是很好。
    • 请注册一个的问题,这是一个有效的用例:-) issues.apache.org/jira/browse/WW
    • 还有一个请求,你能分享一下UrlRenderer的实现吗?我想检查扩展 ServletUrlRenderer 的难易程度。
    • @LukaszLenart 明天将在 ASF jira 做;现在我无权访问代码。但是当我尝试扩展ServletUrlRenderer 时发现了一些问题,所以最后我没有扩展该类,而是根据我的需要复制并修改它,因为可见性问题,将包“破解”为org.apache.struts2.components
    【解决方案2】:

    很难弄清楚这个...尝试使用 s:set 设置 myscheme 的值并使用 jsp 变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      • 2012-10-29
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多