创建工程
创建dynamic Web Project 取名 shoppingcart
建立工程目录如下:
工具类
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* 生成一个随机的验证码图片
* @author footprint
*
*/
public final class DrawPicUtils {
/**
* 图片宽度
*/
private int width;
/**
* 图片高度
*/
private int height;
/**
* 验证码长度
*/
private int num;
/**
* 验证码的字典
*/
private String code;
/**
* 取随机数的对象
*/
private static final Random RANDOM = new Random();
/**
* 单例模式
*/
private static DrawPicUtils drawPicUtils;
/**
* 私有化构造
*/
private DrawPicUtils() {
code = "123456789abcdefghijklmnopqrstvwxyz";
num = 4;
}
/**
* 单例模式获取对象
* @return
*/
public static DrawPicUtils getDrawPicUtils() {
if(null == DrawPicUtils.drawPicUtils) {
DrawPicUtils.drawPicUtils = new DrawPicUtils();
}
return DrawPicUtils.drawPicUtils;
}
/**
* 设置属性
* @param width
* @param height
* @param num
* @param code
*/
public void set(int width, int height, int num, String code) {
this.width = width;
this.height = height;
this.num = num;
this.code = code;
}
/**
* 设置属性
* @param width
* @param height
*/
public void set(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
/**
* 生成随机验证码
* @return
*/
public String generateCheckCode() {
StringBuffer str = new StringBuffer();
for(int i = 0; i < num; i++) {
str.append(code.charAt(DrawPicUtils.RANDOM.nextInt(this.code.length())));
}
return str.toString();
}
/**
* 画出需要的图片返回
* @param checkCode
* @return
*/
public BufferedImage generateCheckImage(String checkCode) {
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//获取图片对象的画笔
Graphics2D graphic = img.createGraphics();
graphic.setColor(Color.WHITE);
graphic.fillRect(0, 0, width, height);
graphic.setColor(Color.BLACK);
graphic.drawRect(0, 0, width-1, height-1);
Font font = new Font("宋体", Font.BOLD+Font.ITALIC, (int)(height*0.8));
graphic.setFont(font);
for(int i = 0; i < num; i++) {
graphic.setColor(new Color(RANDOM.nextInt(155), RANDOM.nextInt(155), RANDOM.nextInt(155)));
graphic.drawString(String.valueOf(checkCode.charAt(i)), i * (width / 4) + 4, (int)(height * 0.8));
}
//加一些点
for(int i = 0; i < (width+height)/2; i++) {
graphic.setColor(new Color(RANDOM.nextInt(155), RANDOM.nextInt(155), RANDOM.nextInt(155)));
graphic.drawOval(RANDOM.nextInt(width), RANDOM.nextInt(height), 1, 1);
}
//加一些线
for(int i = 0; i < 2; i++) {
graphic.setColor(new Color(RANDOM.nextInt(155), RANDOM.nextInt(155), RANDOM.nextInt(155)));
graphic.drawOval(0, RANDOM.nextInt(height), width, RANDOM.nextInt(height));
}
return img;
}
}
Servlet类
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//另一种配置方法
@WebServlet(urlPatterns= {"*.pdo"})
public final class ShopController extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
String mn = req.getServletPath();
mn = mn.substring(1);
mn = mn.substring(0, mn.length()-4);
//利用反射
try {
Method method = this.getClass().getDeclaredMethod(mn, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("unused")
private void shopping(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String pname = req.getParameter("pname");
req.setAttribute("pname", pname);
req.getRequestDispatcher("/productdetails.jsp").forward(req, resp);//转发
}
@SuppressWarnings("unused")
private void addcar(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//模拟网络延时 会造成重复提交
/*
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
String pname = req.getParameter("pname");
String cc = req.getParameter("checkcode");
String scc = (String) req.getSession().getAttribute("checkcode");
if(!cc.equals(scc)) {
req.setAttribute("pname", pname);
req.getRequestDispatcher("/productdetails.jsp").forward(req, resp);//转发
return;
}
//防止网页回滚不刷新提交,360浏览器多次提交
String token = req.getParameter("token");//提交的令牌
String sessionUuid = (String) req.getSession().getAttribute("uuid");//获取本地session的uuid(token)令牌
req.getSession().removeAttribute("uuid");//要删除 只能使用一次
if(token.equals(sessionUuid)) {//令牌有效 加入购物车
HttpSession session = req.getSession();
@SuppressWarnings("unchecked")
List<String> list = (List<String>)session.getAttribute("car");
if(null == list) {
list = new ArrayList<>();
}
list.add(pname);
session.setAttribute("car", list);
}
resp.sendRedirect(req.getContextPath() + "/productcars.jsp");
}
/**
* 画一张图片验证码
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@SuppressWarnings("unused")
private void drawCheckCode(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("img/jpg");
DrawPicUtils pic = DrawPicUtils.getDrawPicUtils();
pic.set(100, 30);
String checkCode = pic.generateCheckCode();//获取随机验证码
req.getSession().setAttribute("checkcode", checkCode);//session需要记录该验证码
OutputStream os = resp.getOutputStream();//输出流
ImageIO.write(pic.generateCheckImage(checkCode), "jpg", os);//写入浏览器
}
}
productcars.jsp
<%@page import="javafx.scene.control.Alert"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>这里是购物车</title>
</head>
<body>
<%
@SuppressWarnings("unchecked")
List<String> list = (List<String>)session.getAttribute("car");
if(list != null && list.size() > 0) {
for(String str : list) {
out.print("<br><br>" + str);
}
}
%>
</body>
</html>
productdetails.jsp ##
<%@page import="java.util.UUID"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>购物车防止重复提交</title>
<script type="text/javascript">
window.onload = function() {
var btn = documnet.getElementById("submitbtn");
btn.onclick = function() {
this.disabled = true;
this.parentNode.submit();
}
}
</script>
</head>
<body>
<%
String uuid= UUID.randomUUID().toString();
session.setAttribute("uuid", uuid);
%>
<br><br>
该产品的详细信息。
<br><br>
<form action="<%=request.getContextPath()%>/addcar.pdo?psso=<%=request.getAttribute("pname")%>" ><!-- 提交一次 -->
<!-- form中的?pname=<%=request.getAttribute("pname")%>被input的内容覆盖 -->
<input type="hidden" name="pname" value="<%=request.getAttribute("pname")%>">
<input type="hidden" name="token" value="<%=uuid %>"> <!-- 再次提交,覆盖之前的 因为都是pname -->
<input type="text" name="checkcode">
<br><br>
<img alt="" src="<%=request.getContextPath()%>/drawCheckCode.pdo">
<br><br>
<input id="submitbtn" style="width: 120px; height: 30px; background: red; color: #fff;" type="submit" value="加入购物车" >
</form>
<br><br>
<br><br>
</body>
</html>
productlist.jsp ##
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>简易购物车</title>
</head>
<body>
<br><br>
<a href="<%=request.getContextPath()%>/shopping.pdo?pname=联想笔记本">联想笔记本</a>
<br><br>
<a href="<%=request.getContextPath()%>/shopping.pdo?pname=华硕主板">华硕主板</a>
<br><br>
<a href="<%=request.getContextPath()%>/shopping.pdo?pname=金士顿优盘">金士顿优盘</a>
<br><br>
<a href="<%=request.getContextPath()%>/shopping.pdo?pname=飞行棋">飞行棋</a>
<br><br>
<a href="<%=request.getContextPath()%>/shopping.pdo?pname=TCL显示屏">TCL显示屏</a>
<br><br>
<a href="<%=request.getContextPath()%>/shopping.pdo?pname=火星土豆">火星土豆</a>
<br><br>
</body>
</html>