黑马商城01

商城项目第一天

黑马商城项目功能演示

功能模块

  • 用户模块
    • 登录
    • 注册
    • 退出
    • 修改
  • 商品模块
    • 商品的展示
    • 分类展示
  • 购物车模块
  • 订单模块
    • 在线支付
  • 后台管理模块

今日任务

  • 完成用户模块
  • 注册
  • 登录
  • 退出登录

前后端分离

所有用到的展现数据都是后端通过异步接口(AJAX/JSON)的方式提供的,前端只负责展现内容

前端: 前端开发人员复制页面的显示效果,AJAX从服务器端获取数据,如何展示数据由前端开发人员决定

后端:Web服务器开发人员负责将JSON数据回传客户端,无需在对客户端显示内内容控制

前后端开发人员通过接口文档进行约定接口信息

在这里插入图片描述

开发环境搭建

  • Maven骨架创建Web应用程序
  • 前端开发工具编写网页(有关前端开发工具hbuilder的环境搭建

AJAX跨域访问

跨域问题来源于JavaScript的同源保护策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。
在这里插入图片描述

解决此问题分为前后端两部分:

  1. 前端部分:
   //使用jquery发送ajax请求的时候 额外设置属性
   $.ajax({
       url:url,
       dataType:"json",
       data:parameter,
       xhrFields: {
       //允许接受从服务器端返回的cookie信息 ,默认值为false 也就是说如果必须设置为true的时候 才可以接受cookie 并且请求带上
           withCredentials: true
       },
       success:function (data,status,xhr) {
           //处理登录的filter
           if(true){
               fn(data,status,xhr);
           }
       }
   })
  1. 后端部分:
//解决跨域访问数据问题
response.setHeader("Access-Control-Allow-Origin", "http://www.itheima326.com:8020");
//AJAX访问允许客户端保存cookie
response.setHeader("Access-Control-Allow-Credentials","true");

另一种方式

	//获取请求的来源网站
	String origin = request.getHeader("Origin");
	//允许你访问我 但是不允许设置cookie
	response.setHeader("Access-Control-Allow-Origin",origin);
	//允许浏览器发送cookie
	response.setHeader("Access-Control-Allow-Credentials","true");

域名解析服务器

在这里插入图片描述
输入域名后先找DNS服务器解析成ip地址,然后才访问

BaseServlet抽取

public class BaseServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //获取方法调用的参数
            String method = request.getParameter("method");
            Method m = this.getClass().getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class);
            m.invoke(this, request, response);
        }catch (Exception ex){ex.printStackTrace();}
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

成功响应和失败响应抽取

    public void success(Object data) throws IOException {
        ResultVo vo = new ResultVo(ResultVo.CODE_SUCCESS,data,"");
        String s = new ObjectMapper().writeValueAsString(vo);
        RRHolder.getResponse().getWriter().print(s);
    }

    public void fail(Object data) throws IOException {
        ResultVo vo = new ResultVo(ResultVo.CODE_FAILED,data,"");
        String s = new ObjectMapper().writeValueAsString(vo);
        RRHolder.getResponse().getWriter().print(s);
    }

用户注册实现

注册实现步骤:

  • 客户端发起AJAX请求,表单数据提交到服务器Servlet
  • Servlet接收客户端请求数据并封装JavaBean
  • 调用业务层方法
  • 业务层调用持久层方法
  • Servlet将注册结果封装对象,向客户端回写JSON数据
  • 客户端判断JSON数据,跳转页面

注册页面

ajax

	<script>
		$(function(){
			$("#registBtn").click(function(){
				//把form里的表单数据以键值对的形式取出来
				var params = $("form").serialize();
				//1.访问的servlet 2.访问时带的参数 3.成功回调函数
				HM.ajax("/user?md=regist",params,function(vo){
					if(vo.code==1){
						location.href="login.html";
					}else{
						var errorString = vo.data;
						$("#username_error").html(errorString).css("color","red");
					}
				})
			})
		})
	</script>

servlet

 protected void regist(HttpServletRequest request,HttpServletResponse response) throws Exception {
        String username = request.getParameter("username");
        if(username==null||username.trim().length()>6||username.trim().length()<2){
            fail("username的长度在2-6之间");
            return;
        }
        Map<String, String[]> parameterMap = request.getParameterMap();
        User user = new User();
        try {
            BeanUtils.populate(user,parameterMap);
            user.setUid(UUIDUtil.getId());
            new UserService().save(user);
            success(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

dao

 public void save(User user) {
        QueryRunner queryRunner = new QueryRunner(DataSourceUtil.getDataSource());
        String sql = "insert into user(uid,username,password,name,email,birthday,gender,remark)values(?,?,?,?,?,?,?,?)";
        Object[] params = {user.getUid(),user.getUsername(),user.getPassword(),user.getName(),user.getEmail(),user.getBirthday(),user.getGender(),user.getRemark()};
        try {
            queryRunner.update(sql,params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

用户登录实现

登录实现步骤:

  • 客户端发起AJAX请求,表单数据提交到服务器Servlet
  • Servlet接收客户端请求数据并传递到业务层
  • 调用业务层方法获取返回值
  • 业务层调用持久层方法
  • Servlet将登录结果封装成对象,返回JSON数据
  • 登录成功保存session
  • 用户名姓名保存在cookie中,回写浏览器
  • 客户端判断JSON数据,跳转页面
  • 客户端在页面顶部显示登录的用户名

登录功能页面

ajax

<script  type="text/javascript">
	$(function () {
	   $("#loginBtn").click(function(){
	   	var params = $("#loginForm").serialize();
	   	HM.ajax("/user?md=login",params,function(vo){
	   		if(vo.code==1){
	   			location.href="index.html";
	   		}else{
	   			$("#error").html(vo.data).css("color","red");
	   		}
	   	})
	   })
          })			
</script>

servlet

    protected void login(HttpServletRequest request,HttpServletResponse response) throws Exception {

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        User user = new UserService().findUserByUAP(username,password);

        if(user!=null){

            request.getSession().setAttribute("user",user);

           success(null);
        }else{
           fail("用户名或者密码不正确");
        }
    }

dao

public User findUserByUAP(String username, String password) {
        QueryRunner queryRunner = new QueryRunner(DataSourceUtil.getDataSource());
        String sql = "select * from user where username = ? and password = ?";
        Object[] params = {username,password};
        try {
            User user = queryRunner.query(sql, new BeanHandler<User>(User.class), params);
            return user;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

Header页面的用户名显示

ajax

		HM.ajax("/user?md=currentname","",function(vo){
			if(vo.code==1){
				var nickname = vo.data;
				
				var li = "<li>"+nickname+":欢迎你</li>";
				li+="<li><a href='javascript:;' οnclick='logout()'>注销登录</a></li>"
				li+="<li><a href='http://www.bai.com:8020/store/view/cart/list.html'>购物车</a></li>"
				li+="<li><a href='http://www.bai.com:8020/store/view/order/list.html'>我的订单</a></li>"
				$("#login-menu").html(li)
			}else{
				
			}
		})
		
		HM.ajax("/category?md=list","",function(vo){
			
		})
	})

servlet

 protected void currentname(HttpServletRequest request,HttpServletResponse response) throws IOException {
        User user = (User) request.getSession().getAttribute("user");
        if(user!=null){
            String name = user.getUsername();
            success(name);
        }else{
            fail(null);
        }
    }

退出登录

实现步骤

  • 点击退出登录按钮
  • 服务器端销毁session对象
  • 客户端跳转到首页

ajax

HM.ajax("/category?md=list","",function(vo){
			
		})

servlet

 protected void logout(HttpServletRequest request,HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        session.invalidate();
        success(null);
    }
}

本地线程封装

谁放的谁取,封装request和response,方便获取使用
RRHolder

public class RRHolder {

    private static final ThreadLocal<HttpServletRequest> requestThreadLocal = new ThreadLocal<>();
    private static final ThreadLocal<HttpServletResponse> responseThreadLocal = new ThreadLocal<>();


    public static void setRequest(HttpServletRequest request){
        requestThreadLocal.set(request);
    }

    public static void setResponse(HttpServletResponse response){
        responseThreadLocal.set(response);
    }

    public static HttpServletRequest geRequest(){
        return requestThreadLocal.get();
    }

    public static HttpServletResponse getResponse(){
        return  responseThreadLocal.get();
    }
}

RRFilter

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest)req;
        HttpServletResponse response = (HttpServletResponse)resp;
        RRHolder.setRequest(request);
        RRHolder.setResponse(response);
        chain.doFilter(req, resp);
    }

测试两端是否畅通

前端页面

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript" src="resources/js/jquery-1.11.3.min.js" ></script>
		<script>
			function req(){
				$.ajax({
					type:"get",
					url:"http://api.itheima349.com:80/test",
					data:"username=xiaoming",
					success:function(data){
						alert(data);
						
					},
					error:function(){
						//.....
					}
				});
			}
		</script>
	</head>
	<body>
		<div>
			<input type="button" value="点我试试后端行不行" onclick="req()" />
		</div>
	</body>
</html>

后端页面

@WebServlet("/test")
public class TestServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");

        String username = request.getParameter("username");
        System.out.println("前端传来参数:"+username);

        //response.setHeader("Access-Control-Allow-Origin","http://www.itheima349.com:8020");


        response.getWriter().print("后端启动");
    }
}

测试两端cookie问题

前端

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript" src="resources/js/jquery-1.11.3.min.js" ></script><br />
		<script type="text/javascript" src="resources/js/jquery-heima-0.0.1.js" ></script>
		<script>
			function req(){
				/*$.ajax({
					type:"get",
					url:"http://api.itheima349.com:80/testcookie",
					data:"username=xiaoming",
					success:function(data){
						alert(data);
						
					},
					error:function(){
						//.....
					},
					xhrFields:{
						//允许服务器端给发送cookie  我会保存 并且允许客户端往回带cookie
						withCredentials:true
					}
				});
				*/
				HM.ajax("/testcookie","username=xiaoming",function(data){
					alert(data)
					
				})
			}
		</script>
	</head>
	<body>
		<div>
			<input type="button" value="点我试试后端行不行" onclick="req()" />
		</div>
	</body>
</html>

后端

public class CookieServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");

        String username = request.getParameter("username");
        System.out.println("前端传来参数:"+username);

        //尝试获取
        Cookie[] cookies = request.getCookies();
        if(cookies!=null&&cookies.length>0){
            for (Cookie cookie : cookies) {
                System.out.println("cookie的名字:"+cookie.getName()+"-----cookie的值:"+cookie.getValue());
            }
        }

        //设置一个cookie
        Cookie cookie = new Cookie("name", "xyz");
        cookie.setMaxAge(60*60);
 	    cookie.setPath("/");
        response.addCookie(cookie);
        response.getWriter().print("测试cookie");
    }
}

测试两端交互数据json格式

在这里插入图片描述
前端

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript" src="resources/js/jquery-1.11.3.min.js" ></script><br />
		<script type="text/javascript" src="resources/js/jquery-heima-0.0.1.js" ></script>
		<script>
			function req(){
				
				HM.ajax("/testjson","username=xiaoming",function(vo){
					alert(vo.data[1])
					
				})
			}		
		</script>
	</head>
	<body>
		<div>
			<input type="button" value="点我试试后端行不行" onclick="req()" />
		</div>
	</body>
</html>

后端

public class JsonServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //后端返回的是一个json格式数据

        //希望返回一个 成功与否

        //这次业务返回 你好
        /*ResultVO resultVO = new ResultVO();
        resultVO.setData("你好");
        resultVO.setCode(1);
        resultVO.setDesc("正常返回的描述信息");*/
        //这次项返回 的是个数组
        ResultVo resultVO = new ResultVo();
        String[] ss=new String[]{"夏明","夏红","夏雨"};
        resultVO.setData(ss);
        resultVO.setCode(ResultVo.CODE_SUCCESS);
        resultVO.setMessage("正常返回的描述信息");

        String s = new ObjectMapper().writeValueAsString(resultVO);

        response.getWriter().print(s);

    }
}

JavaScript特性

		<script>
			var  HM={
				xxxx:"你好",
				sayhello:function(){
					alert("我是一个函数")
				}
			}
			//alert(HM.xxxx)
			HM.sayhello()
			
		</script>

hosts文件修改

进入该目录
C:\Windows\System32\drivers\etc

打开hosts文件
新增记录
127.0.0.1 www.itheima.com
127.0.0.1 api.itheima.com

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值