首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SiteMesh:更改响应的内容类型

SiteMesh:更改响应的内容类型
EN

Stack Overflow用户
提问于 2010-02-23 20:47:27
回答 2查看 1.4K关注 0票数 2

我正在尝试说服一个SiteMesh装饰者更改响应的内容类型,但没有得到joy的响应。内容类型最终总是与装饰的JSP相同,而不是装饰器的内容类型。

例如,假设我有一个带有标头的JSP

代码语言:javascript
复制
<%@ page contentType="application/xhtml+xml" %>

我还有一个SiteMesh装饰器JSP,它定义了以下内容:

代码语言:javascript
复制
<%@ page contentType="application/vnd.wap.xhtml+xml" %>

我希望修饰的响应具有修饰器的mime类型(这里使用的实际MIME类型并不重要,这只是为了说明问题)。

对SiteMesh 2.4.1源代码的深入研究表明,问题出在ContentBufferingResponse类上,该类负责捕获目标的输出。这会覆盖setContentType()方法,记录值供以后使用,但它还会调用super.setContentType(),有效地将目标JSP type直接传递给响应。一旦这样做了,再多的哄骗也不会说服对方做其他的事情。

那么有没有解决这个问题的办法呢?是否可以隐藏目标JSP的content-type,而从装饰器中获取?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-04-15 18:04:34

ContentBufferingResponse.setContentType将触发对HttpServletResponseWrapper.setContentType的调用。稍后,使用不能更改状态代码或设置标头的RequestDispatcher.include将装饰器包含在响应中(任何更改的尝试都将被忽略)。所以基本上,一旦你设置了内容类型,它的游戏结束了,你就不能改变它了。

在我看来,SiteMeshFilter.obtainContent方法是ContentBufferingResponse类唯一被实例化的地方,因此SiteMeshFilterContentBufferingResponse将是寻找变通方法的地方。

一种可能的解决方法是在SiteMeshFilter的子类中重写obtainContent,并通过使用多态性在运行时调用正确的方法。这样做只有一个问题:obtainContent被标记为私有,所以多态性不起作用。要调用不同的obtainContent方法,您必须在过滤器中重写比此方法多得多的内容,我担心这将包括doFilter方法本身。

另一种解决方法是以某种方式调用另一个版本的setContentType方法,该方法不使用修饰页的mime类型调用super.setContentType。但是您不能更改对另一个方法的调用,因为在obtainContent的代码中,我们使用“ContentBufferingResponse”实例化了一个新实例。

此时,您可以在项目中创建ContentBufferingResponse类的副本(在相同的包声明下),其中setContentType方法使用所需的mime类型调用super.setContentType,而不是来自修饰页面的mime类型。然后,您可以欺骗服务器加载您的类,而不是原来的类,方法是使用类路径并确保您的类在SiteMesh的jar中的类之前加载。如果你有多个装饰器(我确信你有:D),这里的主要问题将是在不同的mime类型之间进行管理。

第三个(也很难看)的解决办法就是破解SiteMesh的代码,然后随心所欲(不确定你是否会遇到许可证的问题)。

因此,在我看来,除非你愿意求助于一些丑陋的变通方法,否则一旦设置了内容类型,你就不能改变它。

票数 1
EN

Stack Overflow用户

发布于 2011-02-22 13:12:29

编写一个应用于页面的servlet过滤器,覆盖setContentType()以不调用super,然后在装饰器中将内容类型设置为您想要的任何类型。

您需要再编写一个servlet筛选器来完成此任务,但它应该非常简单。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2318165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档