需求
- 访问一个Servlet,如果是第一次访问,则提示:第一次见面,请多指教 ! ! !
- 如果不是第一次访问,则提示:欢迎回来 >_< ! 上次见到你是在 + 上一次访问时间
.
思路和细节
- 在访问Servlet时,对其request请求的Cookie进行判断——
如果有name为lastTime的Cookie,则响应"第一次见面",写回Cookie
如果没有name为lastTime的Cookie,则响应"上一次见面是在…",写回Cookie - request.getCookies()返回的是个Cookie数组而非集合,没有直接get到lastTime的方法,只能遍历,看其是否存在
- 不管有没有,都可以直接new一个Cookie返回,因为同名Cookie会发生覆盖
(虽然写回(response)的Cookie的响应头中没有覆盖,但其实在下一次的发出的request的请求头中,会发现已经覆盖了) response.setContentType("text/html;charset=utf-8")
解决服务器输出到浏览器的字符流(响应体)中文乱码问题- 新版本的Cookie虽然已经支持中文,但仍有一些特殊字符(比如space空格)出现乱码——因此最好在生成Cookie时,用URL编码多转化一次(
URLEncoder
);读取Cookie时,用URL解码多转化一次(URLDecoder
)—— 参数是字符串返回值也是字符串,用起来很方便(★)
代码
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应体的数据格式以及编码
response.setContentType("text/html;charset=utf-8");
Cookie[] cookies = request.getCookies();
boolean hasVisited = false;
for (Cookie cookie : cookies) {
if (cookie.getName().equals("lastTime")) {
// 如果已经被访问过(有了Cookie)
hasVisited = true;
response.getWriter().write("欢迎回来 >_< ! 上次见到你是在" + URLDecoder.decode(cookie.getValue(), "utf-8"));
break;
}
}
if(!hasVisited){
// 如果第一次被访问
response.getWriter().write("第一次见面,请多指教 ! ! !");
}
Cookie cookie = new Cookie("lastTime", getCurrentTime()); // new就完事了,不用setValue,反正能覆盖
cookie.setMaxAge(60 * 60 * 24 * 30); // 持久化存储(硬盘存储)一个月
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* 返回此刻的时间(已经格式化的字符串,且被URL编码方式转化过;响应的在读取时也要用URL解码转化一次)
*/
private String getCurrentTime() {
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String dateString = simpleDateFormat.format(date);
try {
dateString = URLEncoder.encode(dateString, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return dateString;
}
}