目录

一:概述

二:设计框架

三:实现步骤

第一阶段:表单验证

 第二阶段:注册和登陆功能的实现

1、先创建书城需要的数据库和表(使用sqlyog)

2、编写数据库表中对应的javaBean对象——User类

3、编写工具类JDBCUtils并测试

4、编写 BaseDao和与负责数据库交互的Dao

5、编写Service层

6、编写web层(servlet)

第三阶段:编写jsp页面


一:概述

这是尚硅谷javaweb的开源实战项目

主界面:

java 网上书店项目下载 javaweb网上书城项目_User

登录界面:

java 网上书店项目下载 javaweb网上书城项目_User_02

注册界面:

java 网上书店项目下载 javaweb网上书城项目_sql_03

 

购物车界面:

java 网上书店项目下载 javaweb网上书城项目_java-ee_04

 

 

二:设计框架

该项目采用MVC三层架构,示意图如下:

java 网上书店项目下载 javaweb网上书城项目_java-ee_05

① 视图展现层:接收用户请求,负责调用业务层。

②业务层:处理具体的事务逻辑,以及调用持久层的操作。

③持久层:负责与数据库交互,实现数据的增删改查操作。

代码布局如下:

javaweb工程的创建和tomcat服务器的部署详见我的另一篇博客


java 网上书店项目下载 javaweb网上书城项目_User_06

 

三:实现步骤

第一阶段:表单验证

java 网上书店项目下载 javaweb网上书城项目_java-ee_07

验证用户名是否合法:5-12位,由数字,字母或下划线组成

验证密码是否合法:5-12位,由数字,字母或下划线组成

验证确认密码密码是否相同

验证电子邮件是否合法:

验证验证码是否非空:该阶段暂不用实现验证码的正确性判断

//给注册按钮绑定单击事件
				$("#sub_btn").click(function (){
					//1.获取输入框用户名
					var usernameText=$("#username").val()
					var patt=/^\w{5,12}$/
					if (!patt.test(usernameText)){
						$("span.errorMsg").text("用户名不合法!")
						return false
					}

					//2.获取输入框密码
					var passwordText=$("#password").val()
					var passwordReText=$("#repwd").val()
					if (!patt.test(passwordText)){
						$("span.errorMsg").text("密码不合法!")
						return false
					}
					if(passwordReText!==passwordText){
						$("span.errorMsg").text("密码不一致!")
						return false
					}
					//3.确认邮箱
					var emailpatt=/^\w+@\w+.com$/
					var email=$("#email").val()
					if(!emailpatt.test(email)){
						$("span.errorMsg").text("邮箱不合法!")
						return false
					}
					//4.验证码
					var codetext=$("#code").val()
					if (codetext==null||codetext==""){
						$("span.errorMsg").text("验证码不能为空!")
						return false
					}
					//去除错误信息
					$("span.errorMsg").text()
				})

 

 第二阶段:注册和登陆功能的实现

1、先创建书城需要的数据库和表(使用sqlyog)

java 网上书店项目下载 javaweb网上书城项目_前端_08

2、编写数据库表中对应的javaBean对象——User类

package com.atguigu.pojo;

public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                '}';
    }

    public User() {
    }

    public User(Integer id, String username, String password, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
    }
}

3、编写工具类JDBCUtils并测试

package com.atguigu.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtils {
    private static DruidDataSource dataSource;
    private static ThreadLocal<Connection> conns=new ThreadLocal<>();
    static {
        try {
            Properties properties=new Properties();
            //读取jdbc.properties属性配置文件
            InputStream resourceAsStream = JdbcUtils.class.getClassLoader().
                                            getResourceAsStream("jdbc.properties");
            //从流中加载数据
            properties.load(resourceAsStream);
            //创建数据库连接池
            dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    获取数据库连接池中的连接
    返回null说明获取失败
     */
    public static Connection getConnection(){
        Connection conn=conns.get();
        if(conn==null){
            try {
                conn= dataSource.getConnection();
                conns.set(conn);//保存到threadLocal对象中,供后面JDBC操作使用
                conn.setAutoCommit(false);//手动提交
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        return conn;
    }
//        Connection conn=null;
//        try {
//            conn=dataSource.getConnection();
//        } catch (SQLException throwables) {
//            throwables.printStackTrace();
//        }
//        return conn;
//    }
    /*
    关闭数据库连接,放回数据库连接池
     */
//    public static void close(Connection conn){
//        if(conn!=null){
//            try {
//                conn.close();
//            } catch (SQLException throwables) {
//                throwables.printStackTrace();
//            }
//        }
//    }
    /*
    提交事务并关闭
     */
    public static void commmitAndClose(){
        Connection conn=conns.get();
        if(conn!=null){
            try {
                conn.commit();

            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }finally {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        //一定要执行remove操作,否则就会出错,因为tomcat服务器底层用了线程池技术
        conns.remove();
    }
    
    /*
    回滚事务并关闭
     */
    public static void rollbackAndClose(){
        Connection conn=conns.get();
        if(conn!=null){
            try {
                conn.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }finally {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        //一定要执行remove操作,否则就会出错,因为tomcat服务器底层用了线程池技术
        conns.remove();
    }
}

4、编写 BaseDao和与负责数据库交互的Dao

BaseDao类

package com.atguigu.dao.impl;

import com.atguigu.utils.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public abstract class BaseDao {
    //使用DbUtils操作数据库
    private QueryRunner queryRunner=new QueryRunner();
    /*
    update()用来执行Insert/update/delete语句
    返回-1说明执行失败
    返回其他表示影响的行数
     */
    public int update(String sql,Object ...args){
        Connection conn= JdbcUtils.getConnection();
        try {
            return queryRunner.update(conn,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    /*
    查询返回一个javabean的sql语句
    */
    public <T> T queryForOne(Class<T> type,String sql,Object ...args){
        Connection conn=JdbcUtils.getConnection();
        try {
            return queryRunner.query(conn,sql,new BeanHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
    /*
    查询返回多个javabean的sql语句
     */
    public <T>List<T> queryForList(Class<T> type,String sql,Object ...args){
        Connection conn=JdbcUtils.getConnection();
        try {
            //只有此处不同
            return queryRunner.query(conn,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
    /*
    单个查询
     */
    public Object queryForSingleValue(String sql,Object...args){
        Connection conn=JdbcUtils.getConnection();
        try {
            return queryRunner.query(conn,sql,new ScalarHandler(),args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
}

 UserDaoImpl类,继承了BaseDao实现了UserDao类

package com.atguigu.dao.impl;

import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;

public class UserDaoImpl extends BaseDao implements UserDao {
    @Override
    public User queryUserByUsername(String username) {
        String sql="select `id`,`username`,`password`,`email` from t_user where username=?";
        return queryForOne(User.class,sql,username);

    }
    @Override
    public User queryUserByUsernameAndPassword(String username, String password) {
        String sql="select `id`,`username`,`password`,`email` from t_user where username=? and password=?";
        return queryForOne(User.class,sql,username,password);
    }

    @Override
    public int saveUser(User user) {
        String sql="insert into t_user(`username`,`password`,`email`) values(?,?,?)";
        return update(sql,user.getUsername(),user.getPassword(),user.getEmail());
    }
}

5、编写Service层

package com.atguigu.service;

import com.atguigu.pojo.User;

public interface UserService {
    /*
    注册用户
     */
    public void registUser(User user);
    /*
    用户登陆
     */
    public User login(User user);
    /*
    检查用户名是否可用
    返回false--用户名不存在说明可用
        true--用户名存在说明该用户名不可用
     */
    public boolean existsUsername(String username);
}

具体实现类UserServiceImpl

package com.atguigu.dao.impl;

import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;

public class UserDaoImpl extends BaseDao implements UserDao {
    @Override
    public User queryUserByUsername(String username) {
        String sql="select `id`,`username`,`password`,`email` from t_user where username=?";
        return queryForOne(User.class,sql,username);

    }
    @Override
    public User queryUserByUsernameAndPassword(String username, String password) {
        String sql="select `id`,`username`,`password`,`email` from t_user where username=? and password=?";
        return queryForOne(User.class,sql,username,password);
    }

    @Override
    public int saveUser(User user) {
        String sql="insert into t_user(`username`,`password`,`email`) values(?,?,?)";
        return update(sql,user.getUsername(),user.getPassword(),user.getEmail());
    }
}

6、编写web层(servlet)

package com.atguigu.web;

import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public abstract class BaseServlet extends HttpServlet {
    private UserService userService=new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决相应的中文问题
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=UTF-8");
        String action = req.getParameter("action");
        try {
            Method method = this.getClass().getDeclaredMethod(action,
                    HttpServletRequest.class,HttpServletResponse.class);
            method.invoke(this,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();//吧异常抛给Filter过滤器
        }
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
}

UserServet类:用于实现用户登录,用户注册等功能

package com.atguigu.web;

import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;
import com.atguigu.utils.WebUtils;
import com.google.gson.Gson;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY;

public class UserServlet extends BaseServlet {
    private UserService userService=new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action = req.getParameter("action");
        try {
            Method method = this.getClass().getDeclaredMethod(action,
                    HttpServletRequest.class,HttpServletResponse.class);
            method.invoke(this,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        User login = userService.login(new User(null, username, password, null));
        if(login!=null){
            //System.out.println("登陆成功!");
            req.getSession().setAttribute("user",login);
            req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp);
        }else{
            //System.out.println("用户名或密码错误!");
            //把错误信息,和回显的表单项信息,保存到Request域中
            req.setAttribute("msg","用户名或密码错误!");
            req.setAttribute("username",username);
            req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);
        }
    }
    protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Session中的验证码
        String token =(String)req.getSession().getAttribute(KAPTCHA_SESSION_KEY);
        //删除Session中的验证码
        req.getSession().removeAttribute(KAPTCHA_SESSION_KEY);
        //1.获取请求的参数。比如用户名密码邮箱验证码等
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
        String code = req.getParameter("code");
        User user= WebUtils.copyParamToBean(req.getParameterMap(),new User());

        //2.检查验证码是否正确
        if(token!=null&&token.equalsIgnoreCase(code)){
            //  正确 3检查用户名是否可用
            if(userService.existsUsername(username)){
                //不可用 跳转到注册页面
                //System.out.println("用户名"+username+"已存在!");
                req.setAttribute("msg","用户名已存在");
                req.setAttribute("username",username);
                req.setAttribute("email",email);
                req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
            }else{
                //可用  调用Service保存到数据库,跳转到登陆成功页面
                userService.registUser(user);
                req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp);
            }
        }else{
            //  不正确  跳回注册页面
            req.setAttribute("msg","验证码错误!");
            req.setAttribute("username",username);
            req.setAttribute("email",email);
            //System.out.println("验证码["+code+"]错误");
            req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
        }
    }
    /*
    注销用户
     */
    protected void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.销毁Session中的用户登陆信息
        //2.重定向到首页
        req.getSession().invalidate();
        resp.sendRedirect(req.getContextPath());
    }

    /*
     */
    protected void ajaxExistsUsername(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数username
        String username = req.getParameter("username");
        //调用userservice.existsUsername();
        boolean existsUsername = userService.existsUsername(username);
        //把返回的结果封装成map对象
        Map<String,Object> resultMap=new HashMap<>();
        resultMap.put("existsUsername",existsUsername);
        Gson gson = new Gson();
        String json = gson.toJson(resultMap);
        resp.getWriter().write(json);
    }
}

第三阶段:编写jsp页面

1.将网页中公共的部分,如页脚,log,css等公共部分进行提取为head.jsp。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String basepath=request.getScheme()+"://"+
                    request.getServerName()+":"+
                    request.getServerPort()+
                    request.getContextPath()+"/";
    pageContext.setAttribute("basepath",basepath);
%>
<!--写base标签固定跳转路径-->
<base href="<%=basepath%>">
<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>

2.将每个.jsp都静态包含head.jsp

<%--静态包含base标签,css样式,jquery文件--%>
	<%@include file="/pages/common/head.jsp"%>

3.将项目中所有的html改写为jsp文件

java 网上书店项目下载 javaweb网上书城项目_java-ee_09