一.系统需求
1.用户注册功能:包含了用户名、密码和邮箱等信息,注册完后跳转到登录页面
2.用户登录功能:用户可以通过注册的用户名和密码登录到管理系统
3.记住密码功能:由用户选择是否记住密码
4.新增生鲜功能:用户可以添加生鲜信息到数据库
二.准备工作
1.创建项目。创建如以下的项目,导入连接MySQL的mysql-connector-java-5.1.42-bin.jar(可自行下载)
2.创建数据库。user表存放用户名和密码;category表存放生鲜列表。
3.使用c3p0连接数据库。
4.jsp页面。注意:这里jsp页面form表单提交的name要与写的Java文件里的name一致。
ps我这里是我们老师提供
到这里准备工作就差不多了
三.个人分析
1.运行示意图
2.MVC模型分析
MVC是是模型(Model)、视图(View)和控制(Controller)这3个单词的第一个字母。它是一种目前广泛流行的应用模型,它的目的是实现Web系统的职能分工。模型层实现系统中的业务逻辑,通常可以用JavaBean或EJB来实现(也就是我们这里写的JavaBean封装数据);视图层则是用于与用户的交互,通常用JSP来实现;控制层则是模型与视图View之间沟通的桥梁。它可以把用户的请求分派并选择恰当的视图来显示它们,同时它也可以解释用户的输入并将其映射为模型层能够执行的操作(也就是我们这里写的service,用来获取数据、传输数据等操作)。
3.多态
多态是面向对象程序设计的一个重要特征,指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
在这里父类只有构造方法和成员变量,而子类把自己看成父类,使用父类的成员变量。多态的写法让我们不用考虑对象是什么类型的,只要考虑它使用什么方法。
如:(代码示例,子类继承了父类的方法并对该方法进行了重写,而且向上传值)
四、代码分析
执行顺序详解:
登录执行顺序为 LoginServlet类 ---> IUserService类 ---> UserServiceImpl类
---> IUserDao类 ---> UserDaoImpl类
注册执行顺序为 RegisterServlet类 ---> IUserService类 --->
UserServiceImpl类---> IUserDao类 ---> UserDaoImpl类
新增执行顺序为 CategoryService类 ---> ICategoryService类 --->
CategoryServiceImpl类---> ICategoryDao类 ---> CategoryDaolmpl类
“登录/注册/记住密码”功能代码
model层
User类 私有数据域:
private Integer userId;private String userName;private String password;private String email;
创建其get和set方法
web层
LoginServlet类 (登录的service)
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import com.kkk.model.User;
import com.kkk.service.IUserService;
import com.kkk.service.impl.UserServiceImpl;
/**
* 登录
* @author admin
*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
// Override检查当方法是不是重写
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置编码格式
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 获取用户名密码
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println(name + password);
// 调用用户登录业务service
IUserService userService = new UserServiceImpl();
try {
User user= userService.getUserByNameAndPassword(name,password);
if (user != null) {
// 登录成功将用户信息保存到Session中
HttpSession session = request.getSession();
session.setAttribute("user", user);
// 获取记住密码参数
String jizhu = request.getParameter("jizhu");
if( jizhu != null && jizhu.equals("yes")) {
// 将用户名和密码保存到cookie中
Cookie cookiename = new Cookie("name", name);
Cookie cookiepassword = new Cookie("password", password);
// 设置Cookie的有效期,一天:60*60*24
cookiename.setMaxAge(60*60*24);
cookiepassword.setMaxAge(60*60*24);
// 将Cookie放入到响应中
response.addCookie(cookiename);
response.addCookie(cookiepassword);
}
// 登录成功跳转
request.getRequestDispatcher("category-list.jsp").forward(request, response);
}else {
// 登录失败提示
response.getWriter().print("登录失败");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
RegisterServlet类 (注册的service)
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import com.kkk.model.User;
import com.kkk.service.IUserService;
import com.kkk.service.impl.UserServiceImpl;
/**
* Servlet implementation class RegisterServlet
*/
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public RegisterServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置编码格式
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 获取请求参数
String name = request.getParameter("name");
String password = request.getParameter("password");
String email = request.getParameter("email");
// 把数据封装到user对象
User user = new User();
user.setUserName(name);
user.setPassword(password);
user.setEmail(email);
IUserService userService = new UserServiceImpl();
try {
boolean flag = userService.regisyer(user);
if (flag) {
// 注册成功,重定向到login.jsp
response.sendRedirect(request.getContextPath()+"/login.jsp");
}else {
// 注册失败提示
response.getWriter().print("注册失败");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Service层
IUserService类
import java.sql.SQLException;
import com.kkk.model.User;
/**
* 用户业务接口
* @author 86188
*
*/
public interface IUserService {
/***
* 根据用户名和密码查询用户
*
* @param name
* @param password
* @return
* @throws SQLException
*/
// 根据用户名查询用户接口
User getUserByNameAndPassword(String name, String password) throws SQLException;
boolean regisyer(User user) throws SQLException;
boolean getUserByNameAndPassword(User user) throws SQLException;
}
UserServiceImpl类
import java.sql.SQLException;
import com.kkk.dao.IUserDao;
import com.kkk.dao.impl.UserDaoImpl;
import com.kkk.model.User;
import com.kkk.service.IUserService;
/**
* 用户业务实现
* @author 86188
*
*/
public class UserServiceImpl implements IUserService {
@Override
public boolean regisyer(User user) throws SQLException {
// 调用userdao
IUserDao userDao = new UserDaoImpl();
User user2 = userDao.getUserByUsername(user.getUserName());
if (user2 != null) {
// 当前用户名已经存在
return false;
}else {
int row = userDao.addUser(user);
return row > 0;
}
}
@Override
public User getUserByNameAndPassword(String name, String password) throws SQLException {
IUserDao userDao = new UserDaoImpl();
User user = userDao.getUserByNameAndPassword(name, password);
return user;
}
@Override
public boolean getUserByNameAndPassword(User user) throws SQLException {
// TODO Auto-generated method stub
return false;
}
}
dao层
IUserDao类
import java.sql.SQLException;
import com.kkk.model.User;
//与用户表操作数据库接口相关
public interface IUserDao {
/***
* 根据用户名和密码查询用户
*
* @param password
* @param password
* @return
* @throws SQLException
*/
// 根据用户名查询用户接口
User getUserByNameAndPassword(String name, String password) throws SQLException;
// 新增用户
int addUser(User user) throws SQLException;
// 根据用户名和密码查询用户
User getUserByUsername(String userName) throws SQLException;
}
UserDaoImpl类
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import com.kkk.dao.IUserDao;
import com.kkk.model.User;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class UserDaoImpl implements IUserDao {
@Override
public User getUserByUsername(String userName) throws SQLException {
// 使用c3p0链接数据库
DataSource dataSource = new ComboPooledDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
// 插入sql语句
String sql = "SELECT userId,userName,email FROM user WHERE userName = ?";
// 如果用户为空则没有注册过,返回true,否则返回false
User user = queryRunner.query(sql, new BeanHandler<User>(User.class), userName);
return user;
}
@Override
public int addUser(User user) throws SQLException {
DataSource dataSource = new ComboPooledDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
// 插入sql语句
String sql = "INSERT INTO USER VALUES(NULL,?,?,?)";
// 调用数据库操作类的更新方法并得到一个int值的结果,大于0表示数据添加成功,否则失败
int row = queryRunner.update(sql, user.getUserName(),user.getPassword(),user.getEmail());
return row;
}
@Override
public User getUserByNameAndPassword(String name, String password) throws SQLException {
// 使用c3p0链接数据库
DataSource dataSource = new ComboPooledDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
// 插入sql语句
String sql = "SELECT * FROM user WHERE userName=? AND password=?";
// 调用数据库操作类查找单个类信息的方法并返回查找结果,user或null
User user = queryRunner.query(sql, new BeanHandler<User>(User.class), name,password);
return user;
}
}
“新增数据”功能代码
model层
Category类 私有数据域:
private Integer categoryId;private String categoryName;private String place;private Date createtime;private String type;
创建其get和set方法
web层
CategoryService类
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import com.kkk.model.Category;
import com.kkk.service.ICategoryService;
import com.kkk.service.impl.CategoryServiceImpl;
import com.kkk.web.share.ShareServlet;
@WebServlet("/category")
public class CategoryService extends ShareServlet{ //我这里新建了一个共有类为父类
/**
* 序列化
*/
private static final long serialVersionUID = 1L;
/**
* 添加生鲜
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void addCategory(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
// 设置编码格式
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 获取数据
String categotyName = request.getParameter("categotyName");
String place = request.getParameter("place");
String type = request.getParameter("type");
System.out.println(categotyName+place+type);
// 封装数据
Category category = new Category();
category.setCategoryName(categotyName);
category.setPlace(place);
category.setType(type);
// 调用用户添加业务service
ICategoryService categoryService = new CategoryServiceImpl();
try {
boolean flag = categoryService.addCategory(category);
if (flag) {
response.setStatus(200);
request.getRequestDispatcher("/category-add.jsp").forward(request, response);
}else {
response.setStatus(600);
request.getRequestDispatcher("/category-add.jsp").forward(request, response);
}
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
service层
ICategoryService类
import java.sql.SQLException;
import com.kkk.model.Category;
public interface ICategoryService {
//新增生鲜
boolean addCategory(Category category) throws SQLException;
}
CategoryServiceImpl类
import java.sql.SQLException;
import com.kkk.dao.ICategoryDao;
import com.kkk.dao.impl.CategoryDaolmpl;
import com.kkk.model.Category;
import com.kkk.service.ICategoryService;
public class CategoryServiceImpl implements ICategoryService{
@Override
public boolean addCategory(Category category) throws SQLException {
// 调用ICategoryDao
ICategoryDao categoryDao = new CategoryDaolmpl();
int row = categoryDao.addCategory(category);
return row>0;
}
}
dao层
ICategoryDao类
import java.sql.SQLException;
import com.kkk.model.Category;
public interface ICategoryDao {
//添加
int addCategory(Category category) throws SQLException;
}
CategoryDaolmpl类
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import com.kkk.dao.ICategoryDao;
import com.kkk.model.Category;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class CategoryDaolmpl implements ICategoryDao {
// 添加生鲜品类
@Override
public int addCategory(Category category) throws SQLException {
// 使用c3p0链接数据库
DataSource dataSource = new ComboPooledDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
// 插入sql语句
String sql = "insert into category values(null,?,?,?,?)";
int row = queryRunner.update(sql, category.getCategoryName(),category.getPlace(),category.getCreatetime(),category.getType());
return row;
}
}
五、总结
1.简述后端执行过程
登录功能:
前端form表单的登录信息提交到LoginServlet类,LoginServlet类通过request.getParameter()方法获取到前端的注册信息,调用用户登录service,通过getUserByNameAndPassword()
接口调用dao层执行sql语句调用数据库操作类查找单个类信息的方法并返回查找结果,user或null,验证密码是否正确然后在转发到登录成功的页面。
注册功能:
同样通过request.getParameter()方法获取前端form表单提交的信息,之后把把数据封装到user对象,调用用户注册service,在regisyer()方法调用dao层查询数据库用户名,如果用户名为空则没有注册过,返回true,否则返回false。
如果返回true,接着调用addUser()方法执行sql语句往数据库里新增数据,并返回一个int值,这个int值大于0则表示添加成功,否则表示添加失败。
新增功能
同样通过request.getParameter()方法获取前端form表单提交的信息,后把把数据封装到category对象,调用用户添加业务service,在service层中调用addCategory()方法,接着调用dao层执行sql语句往数据库里添加数据,并返回一个布尔值,表示是否添加成功。
2.遇到的问题
往数据库里添加数据乱码,无奈强制utf-8
// String categotyName = request.getParameter("categotyName"); 乱码
String categotyName = new String(request.getParameter("categotyName").getBytes("ISO-8859-1"),"utf-8");
// String place = request.getParameter("place"); 也是乱码
String place = new String(request.getParameter("place").getBytes("ISO-8859-1"),"utf-8");