smbsm项目
1.准备工作
1.1.环境搭建
1.搭建一个Maven项目(使用idea搭建一个空白的Maven环境)
2.配置Tomcat
3.测试项目是否能跑起来
4.导入项目中会遇到的jar包
在pom.xml文件中导入依赖:servlet、jsp、mysql…
<dependencies>
<!--servlet的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!--jsp的依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!--mysql的驱动-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!-- <!–JSTL表达式依赖–>-->
<!-- <dependency>-->
<!-- <groupId>javax.servlet.jsp.jstl</groupId>-->
<!-- <artifactId>jstl</artifactId>-->
<!-- <version>1.2</version>-->
<!-- </dependency>-->
<!--standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
5.创建项目包结构
entity-------实体类(对应数据库中的各个表)
Dao------与数据库交互,进行持久化操作
service-------业务逻辑处理
servet--------服务器
filter--------过滤器
util----------工具
1.2.编写实体类
分析项目中需要的几个实体
ORM映射----表关系映射
1.3.编写基础公共类
1.数据库配置文件
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username = root
password = 123456
2.编写数据库的公共类
//数据库操作公共类(包括通过配置文件连接数据库、查询数据库、增删改数据库)
public class Base {
//连接数据库的四个数据
private static String driver;
private static String url;
private static String username;
private static String password;
//静态代码块,在类加载时进行初始化
static {
//创建配置文件的对象实例
Properties properties = new Properties();
//通过类的反射加载类加载器,把从配置文件中信息转换为输入流
InputStream io = Base.class.getClassLoader().getResourceAsStream("db.properties");
//从输入流中读取属性列表
try {
properties.load(io);
} catch (IOException e) {
e.printStackTrace();
}
//对四个属性,通过properties读取的属性进行赋值
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
}
//创建数据库的连接类
public static Connection getConnection() throws SQLException, ClassNotFoundException {
//加载类驱动
Class.forName(driver);
//通过驱动器管理连接数据库(数据库的url以及用户名和密码)
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
}
//编写数据库查询公共类
public static ResultSet execute(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet,String sql,Object[] params) throws Exception {
//通过预编译
preparedStatement = connection.prepareStatement(sql);
//预编译需要向里面赋值,所以需要一个参数的数组params
for (int i = 0; i < params.length; i++) {
//由于setObject从1开始,但是我们的数据是从0开始
preparedStatement.setObject(i+1,params[i]);
}
//查询执行用executQuery
resultSet = preparedStatement.executeQuery();
return resultSet;
}
//编写数据库增删改公共类
public static int execute(Connection connection,PreparedStatement preparedStatement,String sql,Object[] params) throws Exception {
//通过预编译
preparedStatement = connection.prepareStatement(sql);
//预编译需要向里面赋值,所以需要一个参数的数组params
for (int i = 0; i < params.length; i++) {
//由于setObject从1开始,但是我们的数据是从0开始
preparedStatement.setObject(i+1,params[i]);
}
//查询执行用executQuery
int i = preparedStatement.executeUpdate();
return i;
}
//释放资源类
public static boolean close(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
boolean flag = true;
if(resultSet != null){
try {
resultSet.close();
resultSet = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if(preparedStatement != null){
try {
preparedStatement.close();
preparedStatement = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if(connection != null){
try {
connection.close();
connection = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
return flag;
}
}
1.4.编写字符过滤器
//Filter:过滤器 ,用来过滤网站的数据;
//处理中文乱码
//登录验证….
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
}
别忘了到web.xml中进行注册。
<!--注册字符编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.wang.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是servlet的任何请求,会经过这个过滤器-->
<url-pattern>/*</url-pattern>
</filter-mapping>
2.登录功能的实现
2.1.编写前端界面
2.2设置首页
在web.xml中设置:
<!--设置首页-->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
2.3编写DAO层登录用户登录界面
//得到要登陆的用户
public User getLoginUser(Connection connection,String userCode) throws Exception;
2.4编写DAO层接口的实现类
public class UseDAO implements UserDAOImpl{
@Override
public User getLoginUser(Connection connection, String userCode) throws Exception {
User user = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
//先进行判断connection是否为空
if (connection != null){
String sql = "select * from smbms_user where userCode=?";
Object[] params ={userCode};
resultSet = Base.execute(connection, preparedStatement,resultSet,sql,params);
if (resultSet.next()){
user = new User();
user.setId(resultSet.getInt("id"));
user.setUserCode(resultSet.getInt("userCode"));
user.setUserName(resultSet.getString("userName"));
user.setUserPassword(resultSet.getString("userPassword"));
user.setGender(resultSet.getInt("gender"));
user.setBirthday(resultSet.getDate("birthday"));
user.setPhone(resultSet.getString("phone"));
user.setAddress(resultSet.getString("address"));
user.setUserRole(resultSet.getInt("userRole"));
user.setCreatedBy(resultSet.getInt("createBy"));
user.setCreationDate(resultSet.getDate("creationDate"));
user.setModifyBy(resultSet.getInt("modifyBy"));
user.setModifyDate(resultSet.getDate("modifyDate"));
}
Base.close(null,preparedStatement,resultSet);
}
return user;
}
}
2.5编写业务层接口
//用户登录
public User login(String userCode,String password) throws Exception;
2.6编写业务层实现类
public class UserServiceImpl implements UserService {
//业务层都会调用DAO层,所以我们要引入DAO层
private UserDAO userDAO;
public UserServiceImpl(){
userDAO = new UseDAOImpl();
}
@Override
public User login(String userCode, String password){
Connection connection = null;
User user = null;
try {
connection = Base.getConnection();
user = userDAO.getLoginUser(connection,userCode);
} catch (Exception e) {
e.printStackTrace();
}finally {
Base.close(connection,null,null);
}
return user;
}
}
2.7编写LoginServlet
//servlet:控制层,调用业务层代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户名和密码
String userCode = req.getParameter("userCode");
String userPassword = req.getParameter("userPassword");
//和数据库中的用户名和密码进行对比
UserService userService = new UserServiceImpl();
User user = null;//这里已经把登录的人查出来了
try {
user = userService.login(userCode, userPassword);
} catch (Exception e) {
e.printStackTrace();
}
if (user != null){//查到此人时
//将用户的信息放到session中
req.getSession().setAttribute(Constans.USER_SESSION,user);
//成功过之后跳转到登陆成功的界面
resp.sendRedirect("./jsp/frame.jsp");
}else {//查无此人,无法登录
//转发会登陆界面,顺带提示
req.setAttribute("error","用户名或者密码错误");
req.getRequestDispatcher("./login.jsp").forward(req,resp);
}
}
用户信息Session可以写成常量,之后直接调用
public class Constans {
public final static String USER_SESSION = "userSession";
}
2.8注册servlet
<!--注册Servlet-->
<servlet>
<servlet-name>LoginServlet</servlet-name><!--Servlet名-->
<servlet-class>com.wang.servlet.LoginServlet</servlet-class><!--Servlet所属的包-->
</servlet>
<!--一个Servlet对应一个Mapping:映射-->
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login.do</url-pattern><!--请求路径-->
</servlet-mapping>
3.登录功能优化
3.1注销功能
思路:注销Session,返回登录页面
public class LoginOutServlet extends HttpServlet {
//servlet:控制层,调用业务层代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//移除Session
req.getSession().removeAttribute(Constans.USER_SESSION);
resp.sendRedirect(req.getContextPath()+"/login.jsp");//返回登陆界面
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
注册servlet
<!--注销servlet-->
<servlet>
<servlet-name>LoginOutServlet</servlet-name><!--Servlet名-->
<servlet-class>com.wang.servlet.LoginOutServlet</servlet-class><!--Servlet所属的包-->
</servlet>
<!--一个Servlet对应一个Mapping:映射-->
<servlet-mapping>
<servlet-name>LoginOutServlet</servlet-name>
<url-pattern>/logout.do</url-pattern><!--请求路径-->
</servlet-mapping>
3.2登录拦截器
public class SysFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// HttpServletRequest是继承自servletRequest,但是父类无法使用子类的方法,故使用强转类型
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (request.getSession().getAttribute(Constans.USER_SESSION) == null){
response.sendRedirect("/error.jsp");
}else {
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
注册过滤器
<!--注册用户登录过滤器-->
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.wang.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<!--只要是servlet的任何请求,会经过这个过滤器-->
<url-pattern>/jsp/*</url-pattern>
</filter-mapping>