商城项目第一天
baidu IP 写不对 百度就上不去
黑马商城项目功能演示
功能模块
-
用户模块
-
登录
-
注册
-
退出
-
修改
-
-
商品模块
-
商品的展示
-
分类展示
-
-
购物车模块
-
订单模块
-
在线支付
-
-
后台管理模块
今日任务
- 完成用户模块
- 注册
- 登录
- 退出登录
前后端分离
所有用到的展现数据都是后端通过异步接口(AJAX/JSON)的方式提供的,前端只管展现
前端: 前端开发人员复制页面的显示效果,AJAX从服务器端获取数据,如何展示数据由前端开发人员决定
后端:Web服务器开发人员负责将JSON数据回传客户端,无需在对客户端显示内内容控制
放两个tomcat中,两个tomcat端口号不能一样,浏览器只能访问8020的。
前后端分离解决耦合性。
开发环境搭建
- Maven骨架创建Web应用程序
- 前端开发工具编写网页
AJAX跨域访问
跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。
解决不能跨域访问的问题
//允许AJAX跨域访问
response.setHeader("Access-Control-Allow-Origin", "http://www.itheima326.com:8020");
//AJAX访问允许客户端保存cookie
response.setHeader("Access-Control-Allow-Credentials","true");
表单提交数据
表单提交的数据和数据处理的方式序列化后传到后端。
效果:
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);
}
}
json传递数据不统一
通过结果集对象转为json传递:
package com.itheima.web;
/**
* 响应的结果对象
* 封装3个成员
* 状态码 int
* 状态码信息 String
* 响应数据 Object
*/
public class Result {
//定义状态码
public static final int SUCCESS = 1;
public static final int FAILS = 0;
public static final int NOLOGIN= 2; // 未登陆
private int code;
private String message;
private Object obj;
public Result(int code,String message){
this.code = code;
this.message = message;
}
public Result(int code, String message, Object obj) {
this.code = code;
this.message = message;
this.obj = obj;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
传递过程:
用户登录实现
登录实现步骤:
- 客户端发起AJAX请求,表单数据提交到服务器Servlet
- Servlet接收客户端请求数据并传递到业务层
- 调用业务层方法获取返回值
- 业务层调用持久层方法
- Servlet将登录结果封装成对象,返回JSON数据
- 登录成功保存session(不然打开一个页面登陆一次)
- 用户名姓名保存在cookie中,回写浏览器
- 客户端判断JSON数据,跳转页面
- 客户端在页面顶部显示登录的用户名
登陆页面
<script type="text/javascript">
$(function(){
//登录按钮,绑定点击事件
$("#submit").click(function(){
//获取表单数据,用户名和密码
var param = $("#loginForm").serialize(); // 往后端提交的数据
//数据提交服务器端
HM.ajax("/user",param,function(data){
//data是响应回来的json
if(data.code==1){
//登录成功,跳转到首页
location.href="http://www.itheima331.com:8020/web/index.html";
}else if(data.code==0){
//登录失败,json的键message取出数据
$("#loginMsg").html(data.message).css("color","red");
}
});
});
});
</script>
UserServlet
响应到客户端的json数据
cookie
UserDao
private QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
@Override
public User login(String username, String password) throws SQLException {
String sql = "select * from user where username = ? and password = ?";
return qr.query(sql, new BeanHandler<User>(User.class),username, password);
}
UserService
// bean 工厂 ,获得dao接口的实现类对象 //传递接口 返回实现类对象
private UserDao dao = BeanFactory.newInstance(UserDao.class);
// 用户登陆方法
@Override
public User login(String username, String password){
User user = null;
try {
user = dao.login(username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
Header页面的用户名显示
<script type="text/javascript">
$(function(){
//取出cookie中的用户名,填充到菜单中
//工具方法 cookieValue函数,传递cookie键,返回值
var cookieValue = HM.cookieValue("username"); // 取出cookie中的姓名 显示在原来写登陆注册的地方
//判断取出的cookie值
if(cookieValue==null || cookieValue==""){
//没有cookie,没有登录,显示 登录,注册,购物车,订单
var s = "<li><a href=\"http://www.itheima331.com:8020/web/login.html\">登录</a></li>\n" +
"\t\t\t<li><a href=\"http://www.itheima331.com:8020/web/register.html\">注册</a></li>\n" +
"\t\t\t<li><a href=\"http://www.itheima331.com:8020/web/view/cart/list.html\">购物车</a></li>\n" +
"\t\t\t<li><a href=\"http://www.itheima331.com:8020/web/view/cart/list.html\">我的订单</a></li>";
$("#login-menu").html(s); //没有登陆显示 “注册” “登陆”
}else{
//有cookie, 显示你好 用户名,购物车,订单
var s = "<li>欢迎您 "+cookieValue+"</li>\n" +
"\t\t\t<li><a href=\"#\" onclick='loginOut()'>退出登录</a></li>\n" +
"\t\t\t<li><a href=\"http://www.itheima331.com:8020/web/view/cart/list.html\">购物车</a></li>\n" +
"\t\t\t<li><a href=\"http://www.itheima331.com:8020/web/view/cart/list.html\">我的订单</a></li>";
$("#login-menu").html(s); // 登陆成功在原地方显示 用户名
// 在login-menu 中加入这些内容
// 双引带转义
}
});
var cookieValue = HM.cookieValue("username"); 有值的话说明登陆成功,将原来现实登陆和注册的地方显示姓名。
没有登陆成功则显示“登陆”,“注册”
退出登录
实现步骤
- 点击退出登录按钮
- 服务器端销毁session对象
- 客户端跳转到首页
- 页面头部不在显示登录的用户名
/**
* 客户端的退出登录
* 销毁session对象
* 销毁客户端cookie
*/
public void loginOut(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//销毁session对象
request.getSession().invalidate();
//销毁客户端cookie
//创建cookie对象,保存用户名
Cookie cookie = new Cookie("username",null); //前端回到location到首页时, 不再显示用户名
//设置cookie参数
cookie.setMaxAge(0);
cookie.setPath(request.getContextPath()); //路径一致
//设置cookie携带的域名
cookie.setDomain("itheima331.com"); //跨站请求服务端和客户端不在同一个应用,需要此项
response.addCookie(cookie);
Result result = new Result(Result.SUCCESS,"退出成功");
response.getWriter().print(JSONObject.fromObject(result));
}