今天学习Cookie对象的时候发现一个问题,跟着视频的代码敲,发现自己的代码运行时出现了问题.
HTTP Status 500
An invalid character [44] was present in the Cookie value
查阅了资料发现,Cookie对象的name和value属性中不可以包含空格和一下一些字符
[ ] ( ) = , " / ? @ : ;
如果需要保存的话,有个解决办法.使用URLEncoder的encode方法编码,使用时使用URLDecoder的decode方法解码.
两个方法都是传入字符串,以及编/解码使用的编码集.注意使用前千万要解码.容易忽视掉的就是循环内再次使用编码后的值.(其实是我自己忘了)
放今天学到使用到了特殊字符的代码
需求是点击之后会将图片添加到浏览记录中,并按最新浏览的显示在最前,删除记录会删除所有记录.
<%@ page import="com.relic.utils.MyCookieUtil" %> <%@ page import="java.net.URLDecoder" %> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> <html> <head> <title>Title</title> <style type="text/css"> .img1 { width: 160px; height: 120px; } .img2 { width: 60px; height: 45px; } .font { font-size: xx-small; } </style> </head> <body> <img class="img1" src="/day11/img/1.jpg"><a href="/day11/product?ID=1">手电筒</a> <img class="img1" src="/day11/img/2.jpg"><a href="/day11/product?ID=2">手机</a> <img class="img1" src="/day11/img/3.jpg"><a href="/day11/product?ID=3">电视</a><br/> <img class="img1" src="/day11/img/4.jpg"><a href="/day11/product?ID=4">冰箱</a> <img class="img1" src="/day11/img/5.jpg"><a href="/day11/product?ID=5">手表</a> <img class="img1" src="/day11/img/6.jpg"><a href="/day11/product?ID=6">笔记本</a> <h3>浏览记录 <a href="/day11/remove" class="font">清除记录</a></h3> <hr/> <% Cookie cookie = MyCookieUtil.getCookieByName(request.getCookies(), "product"); if (cookie != null) { String value = URLDecoder.decode(cookie.getValue(), "UTF-8"); String[] values = value.split(","); for (int i = values.length - 1; i >= 0; i--) { %> <img class="img2" src="/day11/img/<%= values[i] %>.jpg"> <% } } %> </body> </html>
package com.relic.servlet; import com.relic.utils.MyCookieUtil; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLDecoder; import java.net.URLEncoder; public class ProductServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { //获取传过来ID的值 String id = req.getParameter("ID"); //获取cookie数组 Cookie[] cookies = req.getCookies(); //通过cookie名称获取cookie对象 Cookie cookie = MyCookieUtil.getCookieByName(cookies, "product"); //判断cookie是否为空 if (cookie == null) { //如果第一次访问,添加新的cookie resp.addCookie(new Cookie("product", id)); } else { String value = cookie.getValue(); //注意操作之前需要解码 value = URLDecoder.decode(value, "UTF-8"); //不是第一次,获取每个id的值 String[] ids = value.split(","); if (checkID(ids, id)) { //创建StringBuilder对象便于修改字符串 //以下目的是将已有的id值删除,以达到所有都能按顺序添加进去 StringBuilder sb = new StringBuilder(value); int index = sb.indexOf("," + id); if (index != -1) { sb.delete(index, index + 2); }else if(sb.indexOf(id)!=-1){ sb.delete(0,2); } //最后转为字符串 value=sb.toString(); } String newStr = URLEncoder.encode(value + "," + id, "UTF-8"); cookie.setValue(newStr); resp.addCookie(cookie); } resp.sendRedirect("/day11/jsp/item.jsp"); } //查询ids中是否包含id private boolean checkID(String[] ids, String id) { for (String tmp : ids) { if (id.equals(tmp)) { return true; } } return false; } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { doGet(req, resp); } }
package com.relic.utils; import javax.servlet.http.Cookie; public class MyCookieUtil { public static Cookie getCookieByName(Cookie[] cookies, String name) { if (cookies == null) { return null; } else { for (Cookie cookie : cookies) { if (cookie.getName().equals(name)) { return cookie; } } return null; } } }
package com.relic.servlet; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RemoveCookieServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie = new Cookie("product", ""); cookie.setMaxAge(0); resp.addCookie(cookie); resp.sendRedirect("/day11/jsp/item.jsp"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }