1.前台商品类型导航栏功能
采用异步读取数据(使用gson将集合转换json数据),并使用redis缓存技术实现
该功能需要启动redis-server.exe服务器。
关键技术:
(后台)
// 处理ajax
public void findAllCategory(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 转成json格式 list对应json格式[{"":""},{"":""},{"":""}] map
// object对应json格式{"":"","":""}
// 方式1 Gson
// Gson gson = new Gson();
// String json_list = gson.toJson(list);
// System.out.println(json_list);
// 方式2 Jsonlib
// JsonArray JsonObject
// 获取redis连接
Jedis jedis = JedisPoolUtils.getJedis();
// 获取json_list
String json_list = jedis.get("json_list");
System.out.println(json_list);
if (json_list == null) {
List<Category> list = cs.findAllCategories();
json_list = JSONArray.fromObject(list).toString();
// 缓存json_list
jedis.set("json_list", json_list);
// del删除
// jedis.del("json_list");
}
response.getWriter().println(json_list);
}
(前台)
<script type="text/javascript">
$(function(){
$.ajax({
url:"${pageContext.request.contextPath}/category?method=getAllCategory",
type:"post",
dataType:"json",
success:function(data){
var str = "";
$.each(data, function(i, n) {
str += "<li><a href='${pageContext.request.contextPath}/product?method=getCategoryProduct&&cid="+n.cid+"'>"
+ n.cname + "</a></li>";
$("#ul").html(str);
});
},
error:function(error){
alert(status.status);
}
});
});
</script>
2.实现商品浏览记录
// 通过PID查找单商品
public void findProductByPid(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String pid = request.getParameter("pid");
Product product = ps.findProductByPid(pid);
request.setAttribute("product", product);
// 浏览记录
String pids = pid;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
// 找到key为pids的cookie
if (cookie.getName().equals("pids")) {// 如果有pids的cookie说明不是第一次点击商品详情了
// 拼接pid们组成的pids字符串
String[] pid_stirngs = cookie.getValue().split("!");
// 将字符串数组转化为linkList
List<String> list = Arrays.asList(pid_stirngs);
LinkedList<String> linkedList = new LinkedList<String>(list);
// 此次点击的产品的pid在不在linkedList内,如果不在,那么直接添加到首位,如果在,之前一样的再添加到首位
if (linkedList.contains(pid)) {
// 删除之前一样的
linkedList.remove(pid);
// 添加至首位
linkedList.addFirst(pid);
} else {
// 添加至首位
linkedList.addFirst(pid);
}
// 只保留5个
if (linkedList.size() > 5) {
linkedList.subList(5, linkedList.size()).clear();
}
// //将linkedlist转换为字符串数组
// StringBuffer sbuffer = new StringBuffer();
// for (String string : linkedList) {
// sbuffer.append(string);
// sbuffer.append("!");
// }
// //去掉最后的!
// sbuffer.deleteCharAt(sbuffer.length() - 1);
// //将新的字符串赋给pids
// pids = sbuffer.toString();
pids = StringUtils.join(linkedList, "!");
}
}
}
Cookie cookie = new Cookie("pids", pids);
response.addCookie(cookie);
request.getRequestDispatcher("/product_info.jsp").forward(request,
response);
}
3.注册用户功能(实现电子邮箱激活)
public void register(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException,
IllegalAccessException, InvocationTargetException {
// 封装user对象
Map<String, String[]> properties = request.getParameterMap();
User user = new User();
// 自定义类型转换器
// 参数1:类型转换器
// 参数2:要转换至的类型
ConvertUtils.register(new Converter() {
@Override
// 参数一:要转换成的类型
// 参数二:要转换的对象
public Object convert(Class arg0, Object arg1) {
// TODO Auto-generated method stub
// 将字符串转data
System.out.println(arg0);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(arg1.toString());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}, Date.class);
// 封装属性
BeanUtils.populate(user, properties);
// 校验验证码
if (request.getParameter("code").equals(
request.getSession().getAttribute("sRand"))) {
boolean result = us.addUser(user);
// code与uid一致 方便验证
String emailMsg = "恭喜您注册成功,请点击下面的连接进行激活账户"
+ "<a href='http://localhost:8081/ShopStore/user?method=validate&&activeCode="
+ user.getCode() + "'>"
+ "http://localhost:8081/ShopStore/login.jsp</a>";
if (result) {
try {
MailUtils.sendMail(user.getEmail(), emailMsg);
response.sendRedirect("/ShopStore/registerSuccess.jsp");
} catch (Exception e) {
// 发送失败
response.sendRedirect("/ShopStore/registerFail.jsp");
}
} else {
response.getWriter()
.println(
"<script>confirm('注册失败');location.href='/ShopStore/register.jsp';</script>");
}
}else{
response.setContentType("text/html;charset=UTF-8");
response.getWriter()
.println(
"<script>alert('succes哈哈哈');location.href='/ShopStore/register.jsp';</script>");
}
}
// 激活
public void validate(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException,
IllegalAccessException, InvocationTargetException {
String activeCode = request.getParameter("activeCode");
// 激活码与uid一致
us.updateState(activeCode);
response.sendRedirect("/ShopStore/login.jsp");
}
4.自动登录功能
//登录
public void login(HttpServletRequest request,
HttpServletResponse response) throws IOException, IllegalAccessException, InvocationTargetException, ServletException{
Map<String,String[]> map = request.getParameterMap();
User user = new User();
BeanUtils.populate(user,map);
if (map.get("autoLogin")!=null){
Cookie username = new Cookie("username", map.get("username")[0]);
username.setMaxAge(60*60);
Cookie password = new Cookie("password", map.get("password")[0]);
password.setMaxAge(60*60);
response.addCookie(username);
response.addCookie(password);
}
user = us.login(user);
if (user != null){
request.getSession().setAttribute("user", user);
response.sendRedirect("/ShopStore/default.jsp");
}
else{
request.setAttribute("message", "用户或密码错误!");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
//登出
public void logout(HttpServletRequest request,
HttpServletResponse response) throws IOException, IllegalAccessException, InvocationTargetException, ServletException
{
Cookie[] cookies = request.getCookies();
if (cookies != null){
for (Cookie cookie : cookies) {
if (cookie.getName().equals("username") || cookie.getName().equals("password")){
//删除cookie
cookie.setMaxAge(0);
response.addCookie(cookie);//必须,否则实现不了
}
}
}
request.getSession().removeAttribute("user");
response.sendRedirect("/ShopStore/");
}
}
//自动登录采用cookie的方式,并且设有有效时间。
5.前台修改购物车商品的数量
public void updateItemAjax(HttpServletRequest request, HttpServletResponse response)
throws IOException {
Cart cart = (Cart) request.getSession().getAttribute("cart");
Map<String, CartItem> map = cart.getCartItems();
String pid = request.getParameter("pid");
int quantity = Integer.parseInt(request.getParameter("quantity"));
CartItem ci = map.get(pid);
// 移除ci的subTotal
cart.setTotal(cart.getTotal() - ci.getSubTotal());
ci.setBuyNum(quantity);
ci.setSubTotal(ci.getBuyNum() * ci.getProduct().getShop_price());
// 加上ci的subTotal
cart.setTotal(cart.getTotal() + ci.getSubTotal());
String jsonStr = "{'subTotal':"+ci.getSubTotal()+",'total':"+cart.getTotal()+"}";
System.out.println(jsonStr);
response.getWriter().println(jsonStr);
}
前台代码:
<script type="text/javascript">
function deleteItem(pid){
location.href = "${pageContext.request.contextPath}/product?method=deleteItem&&pid="+pid;
}
function updateItem(pid){
var quantity = document.getElementById("quantity").value;
location.href = "${pageContext.request.contextPath}/product?method=updateItem&&pid="+pid+"&&quantity="+quantity;
}
function update(pid){
var quantity = $("#"+pid+"quantity").val();
if (quantity == ""){
$("#"+pid+"quantity").val(1);
quantity = 1;
}
$.ajax({
url: "${pageContext.request.contextPath}/product?method=updateItemAjax",
data:{"pid":pid,"quantity":quantity},
type:"post",
dataType:"json",
success:function(data){
$("#"+pid).text("¥"+data.subTotal);
$("#total").text("¥"+data.total+"元");
},
error:function(e){
alert(e.status);
}
});
}
</script>
注意:
当存在多个商品时,需要区分商品对应的pid
<td width="10%"><input type="text" name="quantity"
value="${carItem.buyNum}" maxlength="4" id="${carItem.product.pid}quantity" size="10" οninput="update(${carItem.product.pid})"></td>
<td width="15%"><span class="subtotal" id="${carItem.product.pid}">¥${carItem.subTotal}</span></td>
//修改数量的同时自动修改总计价钱