如何使用 EL 正确解码 JSP 中的 cookie 值?
How to properly decode cookie values in a JSP using EL?
我想在 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>
[...]
我做错了什么?
${fn:escapeXml()}
escapes predefined XML entities. It does not have any associations with URL encoding nor decoding. See also XSS prevention in JSP/Servlet web application.
如果你使用的是EL 3.0(Tomcat8支持),那么你可以使用ELContext#getImportHandler()
to import packages, classes and constants into EL scope. You can make use of it to import the java.net.URLDecoder
class which contains the 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>
是的,导入 class 的 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");
}
});
}
// ...
}
另请参阅:
- How to reference constants in EL?
- Slide from Reza Rahman about what's new in Java EE 7's EL 3.0
- Java EE 7 tutorial - Chapter 9: EL 3.0
我想在 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>
[...]
我做错了什么?
${fn:escapeXml()}
escapes predefined XML entities. It does not have any associations with URL encoding nor decoding. See also XSS prevention in JSP/Servlet web application.
如果你使用的是EL 3.0(Tomcat8支持),那么你可以使用ELContext#getImportHandler()
to import packages, classes and constants into EL scope. You can make use of it to import the java.net.URLDecoder
class which contains the 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>
是的,导入 class 的 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");
}
});
}
// ...
}
另请参阅:
- How to reference constants in EL?
- Slide from Reza Rahman about what's new in Java EE 7's EL 3.0
- Java EE 7 tutorial - Chapter 9: EL 3.0