基于三层架构+java+jsp+servlet+jQuery+bootstrap——web资源库项目(注册功能demo)

Posted stormzhuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于三层架构+java+jsp+servlet+jQuery+bootstrap——web资源库项目(注册功能demo)相关的知识,希望对你有一定的参考价值。

项目需求分析

(1)用户注册与登录模块:未注册用户可以通过注册用户信息,登录到资源交流平台,达到相互交流学习的目的。已有账号密码的学生或老师可以直接登录课程资源库系统,进行资源浏览。

  • 学生用户成功登陆Web资源库后可以上传学生资源,收藏和下载系统内所有资源,发布学生帖子和评论所有帖子,关注其他用户。
  • 教师用户成功登陆Web资源库后可以上传教师资源,收藏和下载系统内所有资源,发布教师帖子和评论所有帖子,关注其他用户。
  • 管理员用户具有用户信息管理、学生信息批量导入、资源管理、交流区管理的权限。

(2)资源浏览与下载模块:用户可以直接在web资源的首页查看到所有发布的文件和图片,对于共享的资源文件可以直接下载保存。
(3)资源上传模块:用户可以直接上传资源文件,上传文件时需要录入资源的名字,类别,等级和描述。
(4)学习推荐模块:随着Web资源库的内容增加,用户需要从大量资源文件中获取自己想要的资源。学习推荐模块,是对用户实施的一个推荐功能。用户在推荐的目录文件中也可以选择关注自己感兴趣的用户,一起参与讨论。
(5)用户交流区模块:在论坛中,学生用户可以直接发贴提问,回复和评论所有帖子,教师用户可以发帖回答问题,回复和评论所有帖子,帮助学生解决学习上的疑惑。
(6)后台管理模块:管理员进行Web资源库的后台管理。管理员可以在此模块管理用户账号,进行增删查改的操作,并且批量导入学生信息。同时也要讲系统内的资源构件分门别类,删除出错的构件,将优质资源标“优”,将优质的资源摘录到Web资源库首页并且置顶,将交流区的优质回复摘录到Web资源库首页置顶的用户评论区,对交流区内违规操作的用户进行禁言处理。

概要设计

经过需求分析后,按照系统实现的功能进行模块划分,将相关功能的实现划分到同一模块中。
(1)按照管理系统的要求将模块划分为六大部分,用户注册与登录模块,资源浏览与下载模块,资源上传模块和推荐学习模块,用户交流区模块,后台管理模块。

(2)将六个模块细化

用户注册与登录-注册注册成为资源库的一个用户,可以共享web资源内容
用户注册与登录-登录学生用户、教师用户和管理员用户登录账号,分别拥有不同的权限
后台管理-用户管理对用户信息进行管理,批量导入学生,增删查改
后台管理-资源管理对资源信息进行管理,删除出错的构件,将优质资源标“优”
后台管理-论坛管理对发布的帖子进行管理,对交流区内违规操作的用户进行禁言处理
资源浏览与下载-资源中心包含所有用户已经上传的资源信息,可以让用户浏览
资源浏览与下载-资源下载将感兴趣的内容进行资源下载保存到本地
资源上传-上传教师可以上传教师资源文件,学生可以上传个人文件
推荐学习-资源置顶推荐系统将推荐的资源置顶,让用户方便搜索到想要的内容
用户交流区-论坛帖子汇总了所有学生和教师的帖子,方便大家在论坛内展开讨论
用户交流区-我要发帖学生和教师可以发布个人的帖子,评论他人的帖子,关注其他用户

三层架构搭建项目结构

三层架构简介

首先来说,三层架构与MVC的目标一致:都是为了解耦和、提高代码复用。MVC是一种设计模式,而三层架构是一种软件架构。

三层架构分为:控制层(controller层即servlet)、业务逻辑层(service层)、数据访问层(dao层) ,再加上实体类(Model)和表现层(web层即jsp)

实体类(Model)

在Java中,往往将其称为Entity实体类。数据库中用于存放数据,而我们通常选择会用一个专门的类来抽象出数据表的结构,类的属性就一对一的对应这表的属性。

Model实体类需要被dao层,service层和web层引用。

数据访问层(dao)

主要是存放对数据类的访问,即对数据库的添加、删除、修改、更新等基本操作

dao就是根据业务需求,构造SQL语句,构造参数,调用帮助类,获取结果,dao层被service层调用

业务逻辑层(service)

service层好比是桥梁,将web表示层与dao数据访问层之间联系起来。所要负责的,就是处理涉及业务逻辑相关的问题,比如在调用访问数据库之前,先处理数据、判断数据。

后端注册功能实现

eclipse配置

双击eclipse,选择自己的工作空间

设置工作空间的字符编码


设置JSP的字符编码

配置tomcat服务器


创建web项目

按Ctrl+N输入dynamic web project

用户表设计与创建数据库和表

用户表设计

学生,教师都有个人信息(姓名,性别,年龄,生日),但教师不包含班级字段,但它们都有账号信息以及身份标识。管理员只有账号信息,身份标识。

注册时一般只需提供账号,密码,身份标识,如果是学生还需要提供班级,而个人信息是通过登录后通过个人信息修改的。

为了简单起见,可以把学生,教师,管理员放在一张表中,共有的字段设置为不可为空(账号,密码,身份标识),不共有的设置可以为空,表如下

user表

字段名称类型约束描述
user_idvarchar(20)NOT NULL PRIMARY KEY用户ID
user_passwordvarchar(20)NOT NULL用户密码
user_namevarchar(20)NULL用户姓名(默认为空)
user_sexvarchar(10)NULL用户性别(默认为空)
user_birthdaydate()NULL用户生日(默认为空)
user_classvarchar(20)NULL班级
user_levelvarchar(20)NOT NULL用户标识

使用mysql命令行创建数据库和表

CREATE DATABASE web_resource;
CREATE TABLE `user` (
  `user_id` varchar(20) NOT NULL,
  `user_password` varchar(20) NOT NULL,
   `user_name` varchar(20)  NULL,
  `user_sex` varchar(10) DEFAULT NULL,
  `user_birthday` date DEFAULT NULL,
  `user_class` varchar(20) DEFAULT NULL,
  `user_level` varchar(20) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建用户实体类

鼠标左键java文件夹按Ctrl+N输入class

输入存放实体类的包名和类名后finish

User.java代码如下

public class User {
    private String userId;
    private String userPassword;
    private String userName;
    private String userSex;
    private String userBirthday;
    private String userClass;
    private String userLevel;
	public User() {
		super();
	}
	public User(String userId, String userPassword, String userName, String userSex, String userBirthday,
			String userClass, String userLevel) {
		super();
		this.userId = userId;
		this.userPassword = userPassword;
		this.userName = userName;
		this.userSex = userSex;
		this.userBirthday = userBirthday;
		this.userClass = userClass;
		this.userLevel = userLevel;
	}
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getUserPassword() {
		return userPassword;
	}
	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserSex() {
		return userSex;
	}
	public void setUserSex(String userSex) {
		this.userSex = userSex;
	}
	public String getUserBirthday() {
		return userBirthday;
	}
	public void setUserBirthday(String userBirthday) {
		this.userBirthday = userBirthday;
	}
	public String getUserClass() {
		return userClass;
	}
	public void setUserClass(String userClass) {
		this.userClass = userClass;
	}
	public String getUserLevel() {
		return userLevel;
	}
	public void setUserLevel(String userLevel) {
		this.userLevel = userLevel;
	}
	@Override
	public String toString() {
		return "User [userId=" + userId + ", userPassword=" + userPassword + ", userName=" + userName + ", userSex="
				+ userSex + ", userBirthday=" + userBirthday + ", userClass=" + userClass + ", userLevel=" + userLevel
				+ "]";
	}
}

控制层(controller)实现

鼠标左键java文件夹按Ctrl+N输入servlet

输入存放servlet的包名(com.zhuo.controller),由于注册是和用户相关的,还可以建一个子目录user,这样可以和后面各种类型的servlet进行区分,然后输入类名后next

修改URL映射,这样浏览器可以通过地址栏访问注册的servlet

RegisterServlet.java代码如下

public class RegisterServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/* 设置字符编码,解决中文乱码问题 */
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		/* 接收客户端信息 */
		String userId = request.getParameter("userId");
		String userPassword = request.getParameter("userPassword");
		String userName = request.getParameter("userName");
		String userLevel = request.getParameter("userLevel");
		String userClass = request.getParameter("userClass");
		/* 创建用户实体,并把请求参数设置为用户实体成员变量值 */
		User user = new User();
		user.setUserId(userId);
		user.setUserPassword(userPassword);
		user.setUserName(userName);
		user.setUserLevel(userLevel);
		user.setUserClass(userClass);
		// 创建用户service层接口的实现类对象
		UserServiceImpl userServiceImpl = new UserServiceImpl();
		/* 调用业务逻辑方法注册用户 */
		int i = 0;
		try {
			i = userServiceImpl.register(user);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		/* 若i>0,则重定向到login.jsp */
		if (i > 0) {
			response.sendRedirect("views/before/login.jsp");
		}
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doGet(req, resp);
	}
}

RegisterServlet的主要作用就是接受客户提交的表单(通过注册页面提交),然后把参数封装到实体类中,之后就可以以实体类作为参数调用service层业务逻辑处理方法,通过返回值判断是否注册成功

业务逻辑层(service)实现

service层分为接口和接口的实现类,为了要定义接口呢?直接用类不行吗?

我们知道接口是空实现,具体实现由子类继承。那么这样的好处就是当我们扩展业务功能时,只需在接口添加即可,具体的实现交给子类实现。由于接口只包含方法签名,而不包含复杂的逻辑代码,很容易就可以看出有什么业务功能

定义接口

鼠标左键java文件夹按Ctrl+N输入interface

输入存放service层的接口包名和接口名后finish

在UserService.java中添加一个注册的抽象方法

	// 注册用户
	public int register(User user) throws SQLException;

定义接口的实现类

鼠标左键java文件夹按Ctrl+N输入class

输入存放service层的接口实现类的包名和类名并继承UserService接口后finish

在UserServiceImpl实现类中重写接口的register方法

      
      /*
	  * 创建用户dao层接口的实现类,并赋给接口对象变量。
	  *  实现上转型,也就面向接口编程,而不关心它的 实现类是谁
	  */
		UserDao userDao = new UserDaoImpl();
		@Override
		public int register(User user) throws SQLException {
			//把用户插入到数据库中
			int i = userDao.insertUser(user);
			return i;
		}

实现类中重写的register方法,主要功能是封装了底层操作(即对数据库的增删改查),只提现业务功能(即注册)

数据访问层(dao)实现

dao层和service层类似,就不再重复阐述了

定义接口

鼠标左键java文件夹按Ctrl+N输入interface

输入存放dao层接口的包名(com.zhuo.dao)和类名后finish

在UserDao.java中添加一个插入用户到数据库抽象方法

	// 把用户插入到数据库中
	public int insertUser(User user) throws SQLException;

定义接口的实现类

输入存放dao层的接口实现类的包名和类名并继承UserDao接口后finish

在UserDaoImpl实现类中重写接口的insertUser方法

	   //存放查询数据库返回的结果集
		ResultSet resultSet;
		@Override
		public int insertUser(User user) throws SQLException {
			//sql插入语句
			String sql = "insert into user (user_id, user_password, user_name, "
					+ "user_sex, user_birthday,  user_class, user_level) "
					+ "values(?,?,?,?,?,?,?);";
			// 调用jdbc工具类执行sql语句,如果操作成功,i就是操作成功的条数(即i > 0)
			int i = JDBCUtil.executeUpdate(sql, user.getUserId(), 
					user.getUserPassword(), user.getUserName(),
					user.getUserSex(), user.getUserBirthday(), 
					user.getUserClass(), user.getUserLevel());
			return i;
		}

实现类UserDaoImpl重写了接口的insertUser方法,主要功能是调用jdbc工具执行sql插入语句添加用户

使用jdbc工具类和导入mysql驱动包

创建jdbc工具类

鼠标左键java文件夹按Ctrl+N输入class

输入存放工具类的包名和类名后finish

JDBCUtil.java代码如下

public class JDBCUtil {
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/web_resource?useUnicode=true&characterEncoding=utf-8";
    private static final String USER = "root";
    private static final String PASSWORD = "12345";
    private static Connection ct;
    private static PreparedStatement ps;
    private static ResultSet rs;
    static {
        // 1.加载驱动,只需要加载一次,所以放到静态代码块中
        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    /**
     * 描述:封装一个方法可以获得连接,目的可以在其他地方之接调用
     */
    public static Connection getConnection() {
        try {

            ct = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ct;
    }
    /**
     * 描述:封装一个方法可以完成查询操作
     *
     * @param sql 要查询的sql语句
     * @param obj 占位符的具体内容
     * @return ResultSet 将查询到的结果返回
     */
    public static ResultSet executeQuery(String sql, Object... obj) {
        // 1.得到连接
        ct = getConnection();
        // 2.创键发送对象
        try {
            ps = ct.prepareStatement(sql);
            // 处理占位符问题
            if (obj != null) {

                for (int i = 0; i < obj.length; i++) {
                    ps.setObject(i + 1, obj[i]);
                }
            }
            rs = ps.executeQuery();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return rs;
    }
    /**
     * 描述:封装一个方法可以完成DDL,DML操作
     *
     * @param sql 要操作的sql语句
     * @param obj 占位符
     * @return
     */
    public static int executeUpdate(String sql, Object... obj) {
        // 1.得到连接
        ct = getConnection();
        // 2.创键发送对象
        try {
            ps = ct.prepareStatement(sql);
            // 处理占位符问题
            if (obj != null) {
                for (int i = 0; i < obj.length; i++) {
                    ps.setObject(i + 1, obj[i]);
                }
            }
            int in = ps.executeUpdate();
            close(ct, ps, null);
            return in;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }
    /**
     * 描述:封装一个关闭资源的方法
     *
     * @param ct 连接对象
     * @param ps 发送sql语句对象
     * @param rs 返回值对象
     */
    public static void close(Connection ct, PreparedStatement ps, ResultSet rs) {

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ct != null) {
            try {
                ct.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    // 给外部一个访问ct,和ps的方法
    public static Connection getCt() {
        return ct;
    }
    public以上是关于基于三层架构+java+jsp+servlet+jQuery+bootstrap——web资源库项目(注册功能demo)的主要内容,如果未能解决你的问题,请参考以下文章

MVC开发模式和三层架构

java里分的三层到底是哪三层?

EL JSTL和简单MVC 还有三层架构(这次我先鸽了)的学习

Java项目:基于Jsp实现网上定餐系统

基于jsp+servlet的javaweb实现最基本的用户注册登陆注销功能

SpringMVC-01