EL 获取 cookie 中的中文值乱码问题

1、问题由来

众所知周,因为编码问题,如果向 Cookie 中放入中文字符串,将会引发 java.lang.IllegalArgumentException: Control character in cookie value or attribute 异常。要解决这个问题,需要对中文字符串进行 base64 或者 URLEncoder 编码。而这样又引发新的问题:如果用 EL 表达式获取 Cookie 中的值,得到的将是编码后的字符串,譬如:%E5%BC%A0%E4%B8%89

public class LoginServlet extends HttpServlet
{

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		String username = request.getParameter("username");

		/* 将参数中的用户名经过 URL 编码后添加到 cookie 中 */
		response.addCookie(new Cookie("username", URLEncoder.encode(username, "utf-8")));
	}
}

2、解决办法

(1) 在 JSP 页面中使用 Java 代码获取

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="java.net.URLDecoder" %> <!-- 导入 URL 包 -->

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>登录</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
</head>

<body>
    <%
        String username = "";
	
        Cookie[] cookies = request.getCookies();
	
        if(cookies != null)
        {
            for(Cookie cookie : cookies)
            {
                if(cookie.getName().equals("username"))
                {
                    if(cookie.getValue() != null)
                    {
                        /* 获取名为 username 的 Cookie 中的值并用 URL 解码 */
                        username = URLDecoder.decode(cookie.getValue(), "utf-8");
                    }

                    break;
                }
            }
        }
    %>

    <h1><%=username %></h1>
</body>  
</html>

(2) 在 JSP 页面中使用 EL 表达式获取

大家都知道,用 EL 表达式获取 Cookie 的代码更加简洁,只需要 ${cookie.username.value }一句代码即可获取到名为 username 这个 Cookie 对象的值,但是这样获取到的内容是 %E5%BC%A0%E4%B8%89 这样编码后的值,所以我们需要对  ${cookie.username.value } 的内容进行解码,要做到这一点,我们需要自定义 EL 函数库或者 JSTL 标签,这里我们以自定义 EL 函数库为例

Ⅰ定义名为 URLFunctions.java 

public class URLFunctions
{
	/**
	 * 以指定的编码方式对字符串进行解码
	 * @param s:要解码的字符串
	 * @param enc:解码的编码方式,如 utf-8
	 * @return 解码后的字符串
	 */
	public static String decode(String s, String enc)
	{
		try
		{
			return URLDecoder.decode(s, enc);
		} 
		catch (UnsupportedEncodingException e)
		{
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 以指定的编码方式对字符串进行编码
	 * @param s:要编码的字符串
	 * @param enc:解码的编码方式,如 utf-8
	 * @return 编码后的字符串
	 */
	public static String encode(String s, String enc)
	{
		try
		{
			return URLEncoder.encode(s, enc);
		} 
		catch (UnsupportedEncodingException e)
		{
			throw new RuntimeException(e);
		}
	}
}

在 WEB-INF/tlds/ 目录下创建 urlFunctions.tld 文件

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
  version="2.0">
    
  <description>url function library</description>
  <display-name>url functions</display-name>
  <tlib-version>1.0</tlib-version>
  <short-name>ufn</short-name>
  <uri>http://www.zwj.com/jsp/jstl/urlFunctions</uri>

  <function>
    <description>
      	以 enc 编码方式编码输入的字符串 s
    </description>
    <name>encode</name>
    <function-class>com.zwj.web.el.URLFunctions</function-class>
    <function-signature>String encode(java.lang.String, java.lang.String)</function-signature>
  </function>
  
   <function>
    <description>
      	以 enc 编码方式解码输入的字符串 s
    </description>
    <name>decode</name>
    <function-class>com.zwj.web.el.URLFunctions</function-class>
    <function-signature>String decode(java.lang.String, java.lang.String)</function-signature>
  </function>
</taglib>

Ⅲ 在 JSP 中使用函数库

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="ufn" uri="WEB-INF/tlds/urlFunctions.tld" %> <!-- 导入自定义 EL 函数库 -->

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>登录</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
</head>

<body>
    <h1>${ufn:decode(cookie.username.value,"utf-8") }</h1>
</body>   
</html>

 


版权声明:本文为u010031883原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。