我想在JSP页面上显示cookie的值。使用EL,我精心制作了这个:
<c:set var="errorFlash" value="${cookie['error']}"/>
<c:if test="${null != errorFlash}">
<p>${fn:escapeXml(errorFlash.value)}</p>
</c:if>
这似乎有效,但我不确定这是否会正确解码cookie值中的特殊URL字符。我使用curl做了一个快速测试:
$ curl http://localhost:8080/login -v -b 'error=Hello%20World'
[...]
> Cookie: error=Hello%20World
[...]
<p>Hello%20World</p>
[...]
因此它似乎无法正确解码%20字符序列。但是,这可能是curl的问题,而不是我的Tomcat实例。这是另一个需要:
$ curl http://localhost:8080/login -v -b 'error=Hello World'
[...]
> Cookie: error=Hello World
[...]
<p>Hello</p>
[...]
我做错了什么?
答案 0 :(得分:1)
${fn:escapeXml()}
转义predefined XML entities。它与URL encoding nor decoding没有任何关联。另请参阅XSS prevention in JSP/Servlet web application。
如果您使用的是EL 3.0(Tomcat 8支持它),那么您可以使用ELContext#getImportHandler()
将packages,classes和constants导入EL范围。您可以使用它来导入包含所需java.net.URLDecoder
方法的decode()
类。
将它放在JSP的顶部:
${pageContext.ELContext.importHandler.importClass('java.net.URLDecoder')}
然后您可以解码cookie,如下所示:
<c:if test="${not empty cookie.error}">
<p>${URLDecoder.decode(cookie.error.value, 'UTF-8')}</p>
</c:if>
是的,导入该类的EL表达式以一种可怕的方式提醒遗留的 Scriptlets 。幸运的是,您可以在ServletContextListener
的帮助下全局配置,如下所示:
@WebListener
public class Config implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
JspFactory.getDefaultFactory().getJspApplicationContext(event.getServletContext()).addELContextListener(new ELContextListener() {
@Override
public void contextCreated(ELContextEvent event) {
event.getELContext().getImportHandler().importClass("java.net.URLDecoder");
}
});
}
// ...
}