【问题标题】:in spring 4 controllers produce plain text instead of html在 spring 4 中,控制器生成纯文本而不是 html
【发布时间】:2015-11-12 12:06:12
【问题描述】:

我正在从
更新我的应用程序 春季 3.2.5 到 4.2.0
春季安全 3.1.4 到 4.0.2。

我的很多用于显示 HTML 的控制器现在都显示纯文本。 我创建了一些测试方法,以下在版本 3 中显示 HTML,在版本 4 中显示纯文本:

@RequestMapping(value = "/htmltest", method = RequestMethod.GET)
public void test(Writer writer, HttpServletRequest request, HttpServletResponse response) throws IOException {
    writer.append("<html><head></head><body>"); //$NON-NLS-1$
    writer.append("this is a HTML test");
    writer.append("</body></html>"); //$NON-NLS-1$
    writer.flush();
}

我还在@RequestMapping上加了produces = "text/html",没有效果。
我认为这只对使用@ResponseBody 有影响?做了以下测试:

@ResponseBody
@RequestMapping(value = "/htmltest2", method = RequestMethod.GET, produces = "text/html")
public String test2(HttpServletRequest request, HttpServletResponse response) {
    StringBuilder str = new StringBuilder();
    str.append("<html><head></head><body>"); //$NON-NLS-1$
    str.append("this is a HTML test");
    str.append("</body></html>"); //$NON-NLS-1$
    return str.toString();
}

这会显示 HTML,如果我切换到 produces = "text/plain",则会返回文本。

所以问题是如何让控制器在使用编写器的地方生成 HTML?
我发现我可以在响应 response.setContentType("text/html") 上设置内容类型,但我不想为我的所有控制器都这样做。
尤其是在之前的spring版本中可以正常使用,会不会是配置问题?

@RequestMapping(value = "/htmltest3", method = RequestMethod.GET)
public void test3(Writer writer, HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.setContentType("text/html");

    writer.append("<html><head></head><body>"); //$NON-NLS-1$
    writer.append("this is a HTML test");
    writer.append("</body></html>"); //$NON-NLS-1$
    writer.flush();
}

编辑:我刚刚发现只有 Chrome (44.0.2403.155 m) 不显示 HTML,Firefox (40.0.2) 和 InternetExplorer (11.0.9600.17959) 按预期工作。
仍然它可能在旧版浏览器中也不起作用,但也许这给出了提示?

【问题讨论】:

  • 你可以编写一个过滤器来为那些你使用 writer explicility 的 url 设置内容类型 explicility

标签: java spring spring-mvc servlets controller


【解决方案1】:

所以问题出在 Spring Security 3.2.0 中引入的标头:
http://spring.io/blog/2013/08/23/spring-security-3-2-0-rc1-highlights-security-headers/

如果我将以下行添加到我的应用程序上下文中,控制器会再次显示 HTML。

<http>
    ...
    <headers disabled="true"/>
</http>

好吧,但这是个坏主意,因为它会禁用所有额外的安全功能(X-XSS-Protection、X-Frame-Options、HSTS)。

所以一种选择是禁用默认值并配置自己的标题:

<http>
    ...
    <headers defaults-disabled="true">
        <frame-options policy="SAMEORIGIN" />
    </headers>
</http>

缩小范围后,这解决了我的问题:

<http>
    ...
    <headers>
        <content-type-options disabled="true" />
    </headers>
</http>

有一些安全方面需要考虑,但对我来说,这目前可行。 http://docs.spring.io/autorepo/docs/spring-security/4.0.x/reference/html/headers.html#headers-content-type-options

【讨论】:

    【解决方案2】:

    试试:

    @ResponseBody
    @RequestMapping(value = "/htmltest3", method = RequestMethod.GET)
    public void test3(Writer writer, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String html = "<html><head></head><body>this is a HTML test</body></html>";
    
        return html;
    }
    

    【讨论】:

    • 这很可能会起作用,请参阅 /htmltest2,但我想使用 Writer。因为它在我们的系统中被大量使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 2013-01-04
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多