家居网购项目实现012

以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git

29.功能27-Ajax检验注册名

29.1需求分析/图解

用户注册时,后端通过验证,提示用户当前输入的用户名是否可用。

29.2思路分析

29.3代码实现

dao层和service层的方法在之前已经实现过了,这里不必再写

29.3.1web层

MemberServlet添加方法isExistUserName,该方法返回json格式的数据给前端

/**
* 校验某个用户名是否已经存在数据库中
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void isExistUserName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取用户名
String username = req.getParameter("username");
//2.调用service
boolean isExistUsername = memberService.isExistsUsername(username);
//3.返回json格式[按照前端的需求]
//{"isExist":false}
//先使用最简单的拼接,一会使用可拓展的方式
//String resultJson = "{\"isExist\":" + isExistUsername + "}"; //=>将要返回的数据返回map=>json
//使用map可以方便拓展
HashMap<String, Object> resultMap = new HashMap<>();
resultMap.put("isExist", isExistUsername);
String resultJson = new Gson().toJson(resultMap); //4.返回json
resp.getWriter().write(resultJson);
}

29.3.2前端

login.jsp使用Ajax局部请求刷新

//给注册模块的用户名输入框绑定一个失去焦点事件
$("#username").blur(function () {
//获取输入的用户名
var username = this.value;
//发出ajax请求(使用jquery的$.getJSON())
//jQuery.getJSON(url,data,success(data,status,xhr))
$.getJSON(
"memberServlet",
//使用json格式发送数据
{
"action": "isExistUserName",
"username": username,
},
function (data) {
if (data.isExist) {
$("span.errorMsg").text("用户名已经存在,不能使用");
} else {
$("span.errorMsg").text("用户名可用");
}
})
})

29.4完成测试

30.功能28-Ajax添加购物车

30.1需求分析/图解

当前每次添加家居到购物车方式,每次都需要sendRedirect(),会刷新整个页面,数据传输开销大

实际上添加家居到购物车,整个页面只需要刷新购物车的数量

因此使用ajax进行优化,只要刷新购物车的数量即可

30.2思路分析

30.3代码实现

30.3.1web层

CartServlet:

/**
* 添加家居数据到购物车-Ajax方式
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void addItemByAjax(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//得到添加的家居ID
int id = DataUtils.parseInt(req.getParameter("id"), 0);
//获取到id对应的Furn对象
Furn furn = furnService.queryFurnById(id);
if (furn == null || furn.getStock() == 0) {//如果没有对应的家居信息或者该家居库存为0
return;//结束业务
}
//根据furn构建CartItem
CartItem item =
new CartItem(furn.getId(), furn.getName(), furn.getPrice(), 1, furn.getPrice());
//从session获取cart对象
Cart cart = (Cart) req.getSession().getAttribute("cart");
if (null == cart) {//如果当前的session没有cart对象
//创建一个cart对象
cart = new Cart();
//将其放入到session中
req.getSession().setAttribute("cart", cart);
}
//将cartItem加入到cart对象
cart.addItem(item); //添加完毕后,将当前购物车的商品数量以json形式的数据返回
//前端得到json后进行局部刷新即可
//1.规定json格式{"cartTotalcount,3"}
Map<String, Object> resultMap = new HashMap<>();
//2.创建map
resultMap.put("cartTotalcount", cart.getTotalCount());
//3.转为json
String resultJson = new Gson().toJson(resultMap);
resp.getWriter().write(resultJson);
}

30.3.2前端

customer/index.jsp

//给add to cart绑定事件
$("button.add-to-cart").click(function () {
//获取到点击的furn-id
var furnId = $(this).attr("furnId");
//发出一个请求-添加家居=>后面改成ajax
//location.href = "cartServlet?action=addItem&id=" + furnId; //改为ajax请求,得到数据进行局部刷新,解决刷新这个页面的效率低的问题
//jQuery.getJSON(url,data,success(data,status,xhr))
$.getJSON(
"cartServlet",
{
"action": "addItemByAjax",
"id": furnId
},
function (data) {
//刷新局部 <span class="header-action-num">
$("span.header-action-num").text(data.cartTotalCount)
}
)
})

30.3.3解决ajax请求转发失效的问题

测试上面的代码,会发现针对ajax的重定向和请求转发失效了,AuthFilter.java的权限拦截没有用了,即我们点击add to cart,后台服务没有响应,怎么办?

使用ajax向后台发送请求跳转页面无效的原因:

  1. 主要是服务器得到的是ajax发送过来的request,这个请求不是浏览器发送的请求,而是ajax请求的。因此servlet对request进行请求转发或者重定向都不能影响浏览器的跳转
  2. 这时就出现了请求转发和重定向失效的问题
  3. 解决方案:如果想要实现跳转,可以返回url,在浏览器执行window.location(url)


utils包WebUtils:

package com.li.furns.utils;

import javax.servlet.http.HttpServletRequest;

/**
* @author 李
* @version 1.0
*/
public class WebUtils {
/**
* 判断一个请求是否是ajax请求
*
* @param request
* @return
*/
public static boolean isAjaxRequest(HttpServletRequest request) {
return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
}
}

AuthFilter:

package com.li.furns.filter;

import com.google.gson.Gson;
import com.li.furns.entity.Member;
import com.li.furns.utils.WebUtils; import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List; /**
* 这是用于权限验证的过滤器,对指定的url进行验证
* 如果登录过,就放行;如果没有登录,就返回登录页面
*
* @author 李
* @version 1.0
*/
public class AuthFilter implements Filter {
//后面我们把要排除的url放入到excludedUrls中
private List<String> excludedUrls; public void init(FilterConfig config) throws ServletException {
//获取到配置的excludedUrls
String strExcludedUrls = config.getInitParameter("excludedUrls");
//进行分割
String[] splitUrl = strExcludedUrls.split(",");
//将splitUrl转成List,赋给excludedUrls
excludedUrls = Arrays.asList(splitUrl);
System.out.println("excludedUrls=>" + excludedUrls);
} public void destroy() {
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
//权限验证
HttpServletRequest req = (HttpServletRequest) request;
//得到请求的url
String url = req.getServletPath(); //判断是否要验证
if (!excludedUrls.contains(url)) {//如果url不在配置的规则中,就进行校验
//得到session中的member对象
Member member = (Member) req.getSession().getAttribute("member");
if (member == null) {//说明用户没有登录过
//先判断该请求是否为Ajax请求
if (!WebUtils.isAjaxRequest(req)) {//不是ajax请求
//转发到登录页面
//不要使用重定向,因为重定向的url符合过滤器规则时也会被拦截,
//如果设置不合理就会出现 请求无线循环重定向的 情况
req.getRequestDispatcher("/views/member/login.jsp").forward(request, response);
} else {//如果是ajax请求
//以json格式返回一个url
HashMap<String, Object> resultMap = new HashMap<>();
resultMap.put("url", "views/member/login.jsp");
String resultJson = new Gson().toJson(resultMap);
response.getWriter().write(resultJson);
}
return;//返回
}
}
//否则就放行
chain.doFilter(request, response);
}
}

修改前端接口customer/index.jsp

//给add to cart绑定事件
$("button.add-to-cart").click(function () {
//获取到点击的furn-id
var furnId = $(this).attr("furnId");
//发出一个请求-添加家居=>后面改成ajax
//location.href = "cartServlet?action=addItem&id=" + furnId; //改为ajax请求,得到数据进行局部刷新,解决刷新这个页面的效率低的问题
//jQuery.getJSON(url,data,success(data,status,xhr))
$.getJSON(
"cartServlet",
{
"action": "addItemByAjax",
"id": furnId
},
function (data) {
if (data.url == undefined) {
//说明没有返回url,过滤器没有让跳转到登录页面,即说明已经登录过了
$("span.header-action-num").text(data.cartTotalCount);
} else {
//否则说明当前服务器返回了url,要求定位
location.href = data.url;
}
}
)
})

30.4完成测试

没有登录的情况下,点击add to cart,页面成功跳转到login.jsp

登录后,点击添加购物车,成功添加

31.功能29-上传/更新家居图片

31.1需求分析/图解

  1. 后台修改家居,可以点击图片,选择新的图片
  2. 这里会使用到文件上传功能

31.2思路分析

31.3代码实现

31.4完成测试

day13-功能实现12的更多相关文章

  1. Docker 1.12 集群

        环境介绍 虚拟机两台,vmware ,网络为NAT node139:192.168.190.139 Node140: 192.168.190.140     设置hostname 以139为例 ...

  2. 转:Nginx RTMP 功能研究

    看点: 1.    Nginx 配置信息与使用.  (支持 rtmp与HLS配置) 2.    有ffmpeg 编译与使用,    命令行方式来测试验证客户端使用. 转自:http://blog.cs ...

  3. Visual Studio 2017十五项新功能体验

    Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP 2017技术峰会将于这个周末(3.17)在北京举办,由 ...

  4. YouTube视频下载的12个软件(Win和Mac)

    如今,观看视频已经成为人们生活中重要的一部分.很多时候,我们都需要用到视频,比如教育用途.会议报告.休闲娱乐以及广告宣传等.如果你觉得有时候资源不好找的话,不放去看下YouTube.YouTube是世 ...

  5. Nginx-rtmp模块实现流媒体play、push、pull功能

    官方wiki:https://github.com/arut/nginx-rtmp-module#readme Nginx rtmp 功能特点 1.   支持音视频直播 2.   支持flv/mp4视 ...

  6. VS2017十五项新功能体验

    Visual Studio 2017十五项新功能体验 Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP ...

  7. 个人永久性免费-Excel催化剂功能第20波-Excel与Sqlserver零门槛交互-数据上传篇

    Excel作为众多数据存储的交换介质,在不同的系统内的数据很少可以很连贯地进行整合分析,一般的业务系统都会提供导出Excel作为标配功能供用户使用系统内生成的数据. 此时最大的问题是,Excel很维去 ...

  8. 个人永久性免费-Excel催化剂功能第19波-Excel与Sqlserver零门槛交互-查询篇

    对频繁使用Excel的高级应用的尝试用户来说,绕不过的一个问题Excel的性能问题,对于几万条数据还说得过去,上了10万行的数据量,随便一个函数公式的运算都是一个不小的负荷,有些上进一点的用户会往Ac ...

  9. 个人永久性免费-Excel催化剂功能第18波-在Excel上也能玩上词云图

    这年头数据可视化日新月异,在Excel上做数据分析,最后一步,难免要搞个图表输出高大上一回,微软也深知此道,在Excel2016上更新了一大波图表功能,市场上很耀眼的词云图还是没加进来,虽然在各大的在 ...

  10. 个人永久性免费-Excel催化剂功能第17波-批量文件改名、下载、文件夹创建等

    前几天某个网友向我提出催化剂的图片功能是否可以增加导出图片功能,这个功能我一直想不明白为何有必要,图片直接在电脑里设个文件夹维护着不就可以了么?何苦还要把Excel上的图片又重新导出到文件夹中?这个让 ...

随机推荐

  1. 一文讲清楚 JVM Safe Point

    大家好,我是树哥. 关于 Safe Point 是 JVM 中很关键的一个概念,但我估计有不少同学不是很懂.于是今天跟大家来深入聊聊 Safe Point,希望通过这篇文章能解答这样几个问题: 什么是 ...

  2. C++ 栈和典型迷宫问题

    C++ 栈和迷宫问题 1. 前言 栈是一种受限的数据结构,要求在存储数据时遵循先进后出(Last In First Out)的原则.可以把栈看成只有一个口子的桶子,进和出都是走的这个口子(也称为栈顶) ...

  3. Gson的使用与理解

    当今社会下,前后端分离,不同系统的信息交互,消息队列的数据传递,微服务的不同服务之间的数据处理,越来越多地方用到了序列化.序列化作为不同系统不同服务之间的数据桥梁.那么方便快捷的序列化工具还是必要的. ...

  4. Can not set int field xxx to java.lang.Long 错误

    Can not set int field xxx to java.lang.Long 错误 这个错误其实是因为Java程序和MySQL表中字段的属性匹配不一致 我的报错是Can not set ja ...

  5. rabbitmq原理和应用

    0.1.索引 https://blog.waterflow.link/articles/1663772504649 RabbitMQ 是一个轻量级且易于部署的消息队列.它支持开箱即用的多种消息传递协议 ...

  6. C# 7.0 添加和增强的功能【基础篇】

    C# 7.0 版是与 Visual Studio 2017 一起发布. 虽然该版本继承和发展了C# 6.0,但不包含编译器即服务. 一.out 变量 以前我们使用out变量必须在使用前进行声明,C# ...

  7. 三、Go环境安装

    3.1.Go编译器的下载  官网:https://golang.google.cn/go中文网:https://studygolang.com/dl 3.2.安装 for Mac 3.2.1. mac ...

  8. python3使用libpcap库进行抓包及数据处理

    python版本:python 3.9 libpcap版本:1.11.0b7 python libpcap库是底层绑定c语言libpcap库的开发包,旨在提供python应用可访问的unix c li ...

  9.  iOS App 上架App Store及提交审核详细教程

    上架App Store审核分7步进行: 1.安装iOS上架辅助软件Appuploader 2.申请iOS发布证书(p12) 3.申请iOS发布描述文件(mobileprovision) 4.打包ipa ...

  10. 想开发DAYU200,我教你

    摘要:本文主要介绍OpenHarmony富设备DAYU200开发板的入门指导. 本文分享自华为云社区<DAYU200开发指导>,作者: 星辰27. 1 概述 DAYU200开发板属于Ope ...