在春季4控制器生成纯文本而不是HTML

时间:2015-08-19 09:15:13

标签: java spring spring-mvc servlets controller

我正在更新我的申请 弹簧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();
}

我还在produces = "text/html"添加了@RequestMapping,没有效果。
我认为这只会影响使用@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")上设置内容类型,但不希望所有控制器都这样做。
特别是因为它在之前的春季版本中有效,它可能是配置问题吗?

@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米)不显示HTML,Firefox(40.0.2)和InternetExplorer(11.0.9600.17959)按预期工作。
它仍然可能不适用于较旧的浏览器版本,但也许这会给出一个提示?

2 个答案:

答案 0 :(得分:0)

尝试:

@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;
}

答案 1 :(得分:0)

所以问题是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>

嗯,但这是个坏主意,因为它会禁用所有额外的seurity功能(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