当前位置:首页>笔记分享>Java笔记>JavaWeb>JavaWeb-SMBMS实战项目

JavaWeb-SMBMS实战项目

SMBMS项目

Servlet层负责接收用户数据,调用业务层,以及转发视图

service层就负责处理业务(从数据库调取信息)

持久层(Dao):连接查询数据库

前端:负责页面展示

数据库:SMBMS

做一个项目首先要看数据库查看表的结构

  • 借用sqlyog等工具查看表的结构

1、项目搭建准备

1.1、Maven

1.2、配置tomcat

1.3、导依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gong</groupId>
  <artifactId>smbms</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <dependencies>
    <!--测试用的-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <!--servlet-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
    <dependency>
      <!--jsp-->
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
    </dependency>
  <!--连接数据库-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.13</version>
    </dependency>
    <!--jstl标签-->
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>
    <!--jstl依赖的-->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
  </dependencies>
</project>

这些只是目前要用到的

1.4、创建项目包结构

-main
  - java
        - com.kuang      
        - dao 持久化层      
    - filter 过滤层      
    - pojo 实体层      
    - service 业务层      
    - servlet 调用业务层
    - resources
        - db.properties 数据库配置文件
    - webapp

1.5、编写实体类

  • ORM映射: 表 - 类(将数据库的字段映射成类 get、set),放到pojo中

image-20211222123101156

1.6、编写基础公共类

  1. 数据库配置文件
  2. 编写数据库的公共类
  3. 编写字符编码过滤器
  • 数据库配置文件

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=12345678
  • 编写数据库的公共类

package com.gong.dao;
import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class BaseDao {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
    static {
        InputStream resourceAsStream = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
        Properties properties = new Properties();
        try {
            properties.load(resourceAsStream);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //连接数据库
    public static Connection getConnection(){
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }
    //便携查询公共方法
    public static ResultSet execute(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet,String sql,Object[] params) throws Exception{
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            preparedStatement.setObject(i+1,params[i]);
        }
        resultSet = preparedStatement.executeQuery();
        return resultSet;
    }
    //编写增删改公共类
    public static int execute(Connection connection,String sql,Object[] params) throws Exception{
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            preparedStatement.setObject(i+1,params[i]);
        }
       int updateRows = preparedStatement.executeUpdate();
        return updateRows;
    }
    //释放资源
    public static boolean closeResource(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
        boolean flag = true;
        if (resultSet!=null){
            try {
                resultSet.close();
                resultSet=null;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        if (connection!=null){
            try {
                connection.close();
                connection = null;//gc回收
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        if (preparedStatement!=null){
            try {
                preparedStatement.close();
                preparedStatement = null;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        return flag;
    }
}

连接数据库,增删改查方法实现

  • 编写字符编码过滤器

package com.gong.filter;

import javax.servlet.*;
import java.io.IOException;

public class CharaterEncodingFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }
    public void destroy() {
    }
}

要配置过滤器在web.xml中后面就不提醒了

<filter>
  <filter-name>CharaterEncodingFilter</filter-name>
  <filter-class>com.gong.filter.CharaterEncodingFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CharaterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

1.7、导入静态资源

  • webapp

以上都是准备阶段,下面才正式进入项目

2、登录

登录思想:根据用户输入的用户名(用户编码)调用查询查询有没有这个用户,并且对比密码是否正确

img

2.1、编写前端页面

2.2、设置首页

<!--设置欢迎页面-->
<welcome-file-list>
  <welcome-file>login.jsp</welcome-file>
</welcome-file-list>

2.3、编写dao层登录用户登录接口

package com.gong.dao.user;
import com.gong.pojo.User;
import java.sql.Connection;
//获取用户信息接口
public interface UserDao {
    public User getLoginUser(Connection connection,String userCode) throws Exception;
}

2.4、编写dao接口的实现类

package com.gong.dao.user;
import com.gong.dao.BaseDao;
import com.gong.pojo.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/**
 * 提供获得用户信息的方法
 */
public class UserDaoImpl implements UserDao {

    public User getLoginUser(Connection connection, String userCode) throws Exception {
        ResultSet rs = null;
        PreparedStatement preparedStatement = null;
        User user = null;
        String sql = "select * from smbms_user where userCode =?";
        Object[] params = {userCode};
        rs = BaseDao.execute(connection,preparedStatement,rs, sql, params);
        if (rs.next()){
            user = new User();
            user.setId(rs.getInt("id"));
            user.setUserCode(rs.getString("userCode"));
            user.setUserName(rs.getString("userName"));
            user.setUserPassword(rs.getString("userPassword"));
            user.setGender(rs.getInt("gender"));
            user.setBirthday(rs.getDate("birthday"));
            user.setPhone(rs.getString("phone"));
            user.setAddress(rs.getString("address"));
            user.setUserRole(rs.getInt("userRole"));
            user.setCreatedBy(rs.getInt("createdBy"));
            user.setCreationDate(rs.getDate("creationDate"));
            user.setModifyBy(rs.getInt("modifyBy"));
            user.setModifyDate(rs.getDate("modifyDate"));
        }
        BaseDao.closeResource(null, preparedStatement, rs);
        return user;
    }
}

2.5、业务层接口

package com.gong.service.user;
import com.gong.pojo.User;

public interface UserLoginService {
    User Login(String userCode,String password) throws Exception;
}

2.6、业务层接口的实现类

调用Dao的方法获取欲登录用户的信息

package com.gong.service.user;
import com.gong.dao.BaseDao;
import com.gong.dao.user.UserDaoImpl;
import com.gong.pojo.User;
import org.junit.Test;
import java.sql.Connection;
/**
 * 调用UserDaoImpl获取用户数据库信息
 * 方便在servlet中对比
 */
public class UserLoginServiceImpl implements UserLoginService {
    private UserDaoImpl UserDaoImpl;
    public UserLoginServiceImpl() {
        UserDaoImpl = new UserDaoImpl();
    }
    public User Login(String userCode, String password)  {
        Connection connection = null;
        User user = null;
        try {
            connection = BaseDao.getConnection();
            user = UserDaoImpl.getLoginUser(connection, userCode);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            BaseDao.closeResource(connection, null, null);
        }
        return user;
    }
}

2.7、编写Servlet

package com.gong.servlet.user;

import com.gong.pojo.User;
import com.gong.service.user.UserLoginServiceImpl;
import com.gong.util.Constant;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserLoginServletImpl extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入UserLoginServletImpl");
        //前端传来获取用户的信息
        String userCode = (String)req.getParameter("userCode");
        String password = (String)req.getParameter("userPassword");
        //下面两行从数据库获取用户信息
        UserLoginServiceImpl userLoginService = new UserLoginServiceImpl();
        User user = userLoginService.login(userCode,password);
        //判断用户密码是否正确
        if (user != null && user.getUserPassword().equals(password)){
            req.getSession().setAttribute(Constant.USER_SESSION,user);
            resp.sendRedirect("jsp/frame.jsp");
        }else {
            req.getSession().setAttribute("error", "用户名或者密码错误");
            resp.sendRedirect("login.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

2.8、注册Servlet

    <servlet>
        <servlet-name>UserLoginServletImpl</servlet-name>
        <servlet-class>com.gong.servlet.user.UserLoginServletImpl</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserLoginServletImpl</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>

2.9、测试访问,确保以上功能成功

3、登录功能优化

3.1、注销功能

  • 思路:移除Session,返回登录页面(因为有过滤层session没了就不能进入其他页面)
package com.gong.servlet.user;

import com.gong.util.Constant;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserLogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //移除session中用户信息
        req.getSession().removeAttribute(Constant.USER_SESSION);
        req.getSession().removeAttribute("error");
        resp.sendRedirect("../login.jsp");
        //System.out.println(req.getContextPath());
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3.2、登录拦截优化

package com.gong.filter;

import com.gong.util.Constant;
import com.sun.deploy.net.HttpRequest;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class sysFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //强转成HttpServletRequest才能获取session
        HttpServletRequest req = (HttpServletRequest)servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        //session中的USER_SESSION空则说明注销了或者没登录,禁止访问某些页面
        if (req.getSession().getAttribute(Constant.USER_SESSION)==null){
            resp.sendRedirect("/smbms/error.jsp");
        }else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
    public void destroy() {
    }
}

4、修改密码

导入前端页面,写项目,建议从底层往上写

思想:首先判断旧密码是否正确,用户登录后session中存放着旧密码对比一下就可以判断是否正确,所有判断都满足后根据用户id(session中有)改密码就行(update)

4.1、编写Dao接口

//修改密码
public int updatePwd(Connection connection,int id,String password)throws Exception;

4.2、Dao层实现类

    public int updatePwd(Connection connection, int id, String password) throws Exception {
        int execute = 0;
        if (connection!=null){
            String sql = "update smbms_user set userPassword = ? where id = ?";
            connection.prepareStatement(sql);
            Object[] params = {password,id};
            execute = BaseDao.execute(connection, sql, params);
        }
        return execute;
    }

4.3、Service层接口

//修改密码
boolean updatePwd(int id,String password);

4.4、Service接口实现类

    //修改密码
    public boolean updatePwd(int id, String password) {
        boolean flag = false;
        Connection connection =null;
        try {
            connection = BaseDao.getConnection();
            //将数据给Dao层进行修改密码
            int i = UserDaoImpl.updatePwd(connection, id, password);
            if (i>0){
                flag = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放资源
            BaseDao.closeResource(connection, null, null);
        }
        return flag;
    }

4.5、编写Servlet

实现Servlet复用,将方法提出来

package com.gong.servlet.user;

import com.gong.pojo.User;
import com.gong.service.user.UserLoginServiceImpl;
import com.gong.util.Constant;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UpdatePwdServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //复用
        String method = req.getParameter("method");
        if (method.equals("savepwd")){
            this.updatePwd(req, resp);
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
    //提成方法实现Servlet复用
    public void updatePwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String newpassword = req.getParameter("newpassword");
        boolean flag = false;
        //获取到用户
        Object o = req.getSession().getAttribute(Constant.USER_SESSION);
        if (o!=null && newpassword!=null && newpassword.length()!=0){
            flag = new UserLoginServiceImpl().updatePwd(((User)o).getId(), newpassword);
            if (flag){
                req.setAttribute("message", "密码修改成功,请重新登录");
                req.getSession().removeAttribute(Constant.USER_SESSION);
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else {
                req.setAttribute("message", "密码修改失败");
            }
        }else{
            req.setAttribute("message", "新密码有问题");
        }
        req.getRequestDispatcher("pwdmodify.jsp").forward(req, resp);
    }
}

4.6、注册Servlet

<servlet>
    <servlet-name>UpdatePwd</servlet-name>
    <servlet-class>com.gong.servlet.user.UpdatePwdServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>UpdatePwd</servlet-name>
    <url-pattern>/jsp/user.do</url-pattern>
</servlet-mapping>

4.7、优化密码修改使用Ajax

之前我们只实现了密码修改但是没有验证旧密码是否正确

  • 验证旧密码方法有很多,下面的方法是最推荐的,企业常用
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<!--    其他类型转json工具阿里的-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.47</version>
    </dependency>

fastjson maven 阿里巴巴的:作用是将其他类型转换为json格式

//验证旧密码是否正确
    public void pwdModify(HttpServletRequest req, HttpServletResponse resp){
        //oldpassword是json传递过来的不是 当失去焦点就传过来了
        String oldpassword = req.getParameter("oldpassword");
        //session中有我们之前的密码信息
        Object o = req.getSession().getAttribute(Constant.USER_SESSION);
        Map<String, String> resultMap = new HashMap<String, String>();
        if (o==null){//session过期
            resultMap.put("result", "sessionerror");
        }else if (StringUtils.isNullOrEmpty(oldpassword)){//输入的旧密码为空
            resultMap.put("result", "error");
        }else {
            String userPassword = ((User)o).getUserPassword();
            if (userPassword.equals(oldpassword)){//旧密码正确
                resultMap.put("result", "true");
            }else {//旧密码错误
                resultMap.put("result", "false");
            }
        }
        try {
            PrintWriter writer = resp.getWriter();
            //写出格式为json 类似与我们之前写出的"text/html"
            resp.setContentType("application/json");
            //JSONArray是导入包的方法将其他类型转换成json,
            // 我们自己可以利用字符串拼接形式将map转为json
            String s = JSONArray.toJSONString(resultMap);
            writer.write(s);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

5、用户管理

思路:
img

5.1、导入分页的工具类

5.2、用户列表页面导入

  • userlist.jsp
  • rollpage.jsp

5.3、获取用户数量

根据用户名或者身份编号查询用户个数

①UserDao

//根据用户名或者身份编号查询用户个数
int getUserCount(Connection connection,String userName,int id) throws Exception;

②UserDaoImpl

    //根据用户名或者身份编号查询用户个数
    public int getUserCount(Connection connection, String userName, int id) throws Exception {
        PreparedStatement pstm = null;
        ResultSet rs = null;
        int count = 0;
        StringBuffer sql = new StringBuffer();
        ArrayList<Object> list = new ArrayList<Object>();
        if (connection !=null){
            sql.append("select count(1) as count from smbms_user u,smbms_role r where u.userRole=r.id");
            if (!StringUtils.isNullOrEmpty(userName)){
                sql.append(" and u.userName like ?");//拼接sql
                list.add("%"+userName+"%");
            }
            if (id>0){
                sql.append(" and r.id = ?");
                list.add(id);
            }
        }
        System.out.println(sql.toString());//查看sql语句
        Object[] params = list.toArray();
        rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
        if (rs.next()){
            count = rs.getInt("count");//count是上面sql我们重命名的
        }
        BaseDao.closeResource(null, pstm, rs);
        return count;
    }

③UserService

int getUserCount(String userName,int id) throws Exception;

④UserServiceImpl

    //根据用户名或者身份编号查询用户个数
    public int getUserCount(String userName, int id) throws Exception {
        Connection connection = BaseDao.getConnection();
        int userCount = UserDaoImpl.getUserCount(connection, userName, id);
        BaseDao.closeResource(connection, null, null);
        return userCount;
    }

5.4、获取用户列表

获取用户列表并实现分页查询

①UserDao

//根据用户名或者身份id查询用户列表
    List<User> getUserList(Connection connection,String userName,int id,int currentPageNo,int pageSize)throws Exception;

②UserDaoImpl

public List<User> getUserList(Connection connection, String userName, int id,int currentPageNo,int pageSize) throws Exception {
        ArrayList<User> userList = new ArrayList<User>();//用户列表
        ArrayList<Object> list = new ArrayList<Object>();//sql参数
        User user = new User();
        PreparedStatement pstm = null;
        ResultSet rs = null;
        StringBuffer sql = new StringBuffer();
        if (connection!=null){
            sql.append("select u.*,r.roleName roleName from smbms_role r,smbms_user u where u.userRole =r.id");
            if (!StringUtils.isNullOrEmpty(userName)){//名字不为空
                sql.append(" and u.userName like ?");
                list.add("%"+userName+"%");
            }
            if (id>0){//角色身份id存在
                sql.append( "and r.id = ?");
                list.add(id);
            }
            //分页查询
            sql.append(" order by u.id ASC limit ?,?");
            /*
          1  0  5
          2  5  5
          3  10  5   可以看出下面这个计算公式由来
             */
            currentPageNo = (currentPageNo-1)*pageSize;//当前第几个数据
            list.add(currentPageNo);
            list.add(pageSize);//页面显示信息个数
            Object[] params = list.toArray();
            System.out.println("UserDaoImpl->getUserList:sql:"+sql.toString());
            rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
            while (rs.next()){
                user.setId(rs.getInt("id"));
                user.setUserCode(rs.getString("userCode"));
                user.setUserName(rs.getString("userName"));
                user.setUserPassword(rs.getString("userPassword"));
                user.setGender(rs.getInt("gender"));
                user.setBirthday(rs.getDate("birthday"));
                user.setPhone(rs.getString("phone"));
                user.setAddress(rs.getString("address"));
                user.setUserRole(rs.getInt("userRole"));
                user.setCreatedBy(rs.getInt("createdBy"));
                user.setCreationDate(rs.getDate("creationDate"));
                user.setModifyBy(rs.getInt("modifyBy"));
                user.setModifyDate(rs.getDate("modifyDate"));
                user.getUserRoleName(rs.getString("roleName"));
                userList.add(user);
            }
            BaseDao.closeResource(null, pstm, rs);
        }
        return userList;
    }

③UserService

 //获取用户列表
List<User> getUserList(String userName, int id, int currentPageNo, int pageSize)throws Exception;

④UserServiceImpl

    //根据用户名或者身份编号获取用户列表
    public List<User> getUserList(String userName, int id, int currentPageNo, int pageSize) throws Exception {
        List<User> users = new ArrayList<User>();
        Connection connection = BaseDao.getConnection();
        //执行Dao持久层方法根据用户名或者id查询信息
        List<User> userList = UserDaoImpl.getUserList(connection, userName, id, currentPageNo, pageSize);
        //释放资源
        BaseDao.closeResource(connection, null, null);
        return userList;
    }

5.5、获取角色操作

为了职责统一,可以把角色的操作单独放在一个包中,并和POJO类进行对应。

①RoleDao

package com.gong.dao.role;
import com.gong.pojo.Role;
import java.sql.Connection;
import java.util.List;
public interface RoleDao {
    List<Role> getRoleList(Connection connection);
}

②RoleDaoImpl

package com.gong.dao.role;

import com.gong.dao.BaseDao;
import com.gong.pojo.Role;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class RoleDaoImpl implements RoleDao {
    //获取role角色职位列表
    public List<Role> getRoleList(Connection connection) {
        //查询role职位信息
        String sql = "select * from smbms_role";
        Object[] params = {};
        ResultSet rs = null;
        PreparedStatement pstm = null;
        List<Role> roleList = new ArrayList<Role>();
        if (connection!=null){
            try {
                rs = BaseDao.execute(connection, pstm, rs, sql, params);
                while (rs.next()){
                    Role role = new Role();
                    role.setId(rs.getInt("id"));
                    role.setRoleName("roleName");
                    role.setRoleCode("roleCode");
                    roleList.add(role);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                BaseDao.closeResource(null, pstm, rs);
            }
        }
        return roleList;
    }
}

③RoleService

package com.gong.service.role;
import com.gong.pojo.Role;
import java.util.List;

public interface RoleService {
  //获取角色列表
    List<Role> getRoleList();
}

④RoleServiceImpl

package com.gong.service.role;

import com.gong.dao.BaseDao;
import com.gong.dao.role.RoleDao;
import com.gong.dao.role.RoleDaoImpl;
import com.gong.pojo.Role;
import java.sql.Connection;
import java.util.List;

public class RoleServiceImpl implements RoleService {
    private RoleDao roleDao;

    public RoleServiceImpl() {
        roleDao = new RoleDaoImpl();
    }
    public List<Role> getRoleList() {
        Connection connection = BaseDao.getConnection();
        List<Role> roleList = roleDao.getRoleList(connection);
        return roleList;
    }
    //获取角色正常
//    @Test
//    public void test(){
//        List<Role> roleList = this.getRoleList();
//        System.out.println(roleList.toString());
//    }
}

5.6、用户显示的Servlet

  • 获取用户前端的数据(查询)
  • 判断请求是否需要执行,看参数的值判断
  • 为了实现分页,需要计算出当前页面和总页面,页面大小…
  • 用户列表展示
  • 返回前端

小黄鸭调试法:

  • 程序员修炼之道
  • 和小黄鸭边说边分析(物体)
   //展示查询用户页信息(全局最难处)
    public void query(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        //1.从前端获取用户信息
        String queryname = req.getParameter("queryname");
        String temp = req.getParameter("queryUserRole");//角色id
        String pageIndex = req.getParameter("pageIndex");
        int queryUserRole = 0;//给一个初始化方便首次登录显示全部
        //2.获取用户
        UserLoginServiceImpl userService = new UserLoginServiceImpl();
        //首次进入页面显示多少个固定死
        int pageSize = 5;//可以写在配置文件方便后期修改
        int currentPageNo = 1;
        //null和空不一样的""的长度是0
        if (queryname==null){
            queryname = "";
        }
        //给角色id赋值 0,1,2,3
        if (temp!=null && !temp.equals("")){
            queryUserRole = Integer.parseInt(temp);
        }
        //默认第一页,用pageIndex获取当前页
        if (pageIndex!=null){
            currentPageNo = Integer.parseInt(pageIndex);
        }
        //获取用户总数(分页问题)
        int totalCount = userService.getUserCount(queryname, queryUserRole);
        //总页数等支持
        PageSupport pageSupport = new PageSupport();
        pageSupport.setPageSize(pageSize);
        pageSupport.setTotalCount(totalCount);
        pageSupport.setCurrentPageNo(currentPageNo);
        //显示页数
        int totalPageCount = (int)(totalCount/pageSize)+1;
        //控制首页和尾页,页面小于1就显示第一页内容
        if (currentPageNo<1){
            currentPageNo = 1;
        }else if (currentPageNo>totalPageCount){
            currentPageNo = totalPageCount;
        }
        //3.给前端传递数据
        List<User> userList = userService.getUserList(queryname, queryUserRole, currentPageNo, pageSize);
        req.setAttribute("userList",userList);//用户列表
        RoleServiceImpl roleService = new RoleServiceImpl();
        List<Role> roleList = roleService.getRoleList();
        //前端要用到什么数据就传递什么数据
        req.setAttribute("roleList",roleList);//角色列表
        req.setAttribute("totalCount",totalCount);//用户总数
        req.setAttribute("currentPageNo",currentPageNo);//当前页
        req.setAttribute("totalPageCount",totalPageCount);//总页数
        //请求转发
        req.getRequestDispatcher("userlist.jsp").forward(req,resp);
    }

5.7、增加用户

思想:很简单三层架构按顺序来就行

img

    - 一切的增删改操作都需要处理事务    - ACID原则

增加用户:

  • 前端(表单提交)/jsp/user.do?method=add
  • servlet userService.addUser(user)
  • service userDao.add(connection,user)
  • Dao BaseDao.execute(connection,pstm,sql,params)

其他方法大概都是增加用户这个流程都差不多(就写一个增加用户演示一下)

img

①UserDao

 //增加用户信息
    int addUser(Connection connection,User user)throws Exception;

②UserDaoImpl

    //增加用户
    public int addUser(Connection connection, User user) throws Exception {
        PreparedStatement pstm = null;
        ResultSet rs = null;
        int count=0;
        if (connection!=null){
            String sql = "insert into smbms_user(userCode,userName,userPassword," +
                    " gender,birthday,phone,address,userRole" +
                    ",createdBy,creationDate)" +
                    "values (?,?,?,?,?,?,?,?,?,?)";
            Object[] params = {user.getUserCode(),user.getUserName(),user.getUserPassword()
                               ,user.getGender(),user.getBirthday(),user.getPhone(),user.getAddress()
                                ,user.getUserRole(),user.getCreatedBy(),user.getCreationDate()
                                };
            count = BaseDao.execute(connection, sql, params);
            BaseDao.closeResource(null, pstm, rs);
        }
        return count;
    }

③UserService

    //增加用户
    boolean addUser(User user) throws SQLException;

④UserServiceImpl

    //增加用户
    public boolean addUser(User user) throws SQLException {
        boolean flag = false;
        int count = 0;
        if (!StringUtils.isNullOrEmpty(user.getUserPassword())){
            Connection connection = BaseDao.getConnection();
            //要开启事务回滚
            try {
                connection.setAutoCommit(false);
                count = UserDaoImpl.addUser(connection, user);
                connection.commit();
                if (count>0){
                    flag = true;
                    System.out.println("添加用户成功");
                }else {
                    System.out.println("用户添加失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("用户添加失败");
                connection.rollback();//失败回滚
            }finally {
                BaseDao.closeResource(connection, null, null);
            }
        }
        return flag;
    }

⑤servlet

public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, SQLException {
    System.out.println("当前正在执行增加用户操作");
    //从前端得到页面的请求的参数即用户输入的值
    String userCode = req.getParameter("userCode");
    String userName = req.getParameter("userName");
    String userPassword = req.getParameter("userPassword");
    //String ruserPassword = req.getParameter("ruserPassword");
    String gender = req.getParameter("gender");
    String birthday = req.getParameter("birthday");
    String phone = req.getParameter("phone");
    String address = req.getParameter("address");
    String userRole = req.getParameter("userRole");
    //把这些值塞进一个用户属性中
    User user = new User();
    user.setUserCode(userCode);
    user.setUserName(userName);
    user.setUserPassword(userPassword);
    user.setAddress(address);
    user.setGender(Integer.valueOf(gender));
    user.setPhone(phone);
    try {
        user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
    } catch (ParseException e) {
        e.printStackTrace();
    }
    user.setUserRole(Integer.valueOf(userRole));
    user.setCreationDate(new Date());
    //查找当前正在登陆的用户的id
    user.setCreatedBy(((User)req.getSession().getAttribute(Constant.USER_SESSION)).getId());
    UserLoginServiceImpl userService = new UserLoginServiceImpl();
    Boolean flag = userService.addUser(user);
    //如果添加成功,则页面转发,否则重新刷新,再次跳转到当前页面
    if(flag){
        resp.sendRedirect(req.getContextPath()+"/jsp/user.do?method=query");
    }else{
        req.getRequestDispatcher("useradd.jsp").forward(req,resp);
    }
}

删除用户

一样的很简单,根据id删就行

①UserDao

int deleteUser(Connection connection,int id) throws Exception;

②UserDaoImpl

//删除用户
public int deleteUser(Connection connection, int id) throws Exception {
    PreparedStatement pstm = null;
    ResultSet rs = null;
    int delResult = 0;
    Object[] params = {id};
    String sql = "delete from smbms_user where id = ?";
    if (connection!=null){
        delResult  = BaseDao.execute(connection, sql, params);
    }
    BaseDao.closeResource(null, pstm, rs);
    return delResult;
}

③UserService

//删除用户
boolean delUser(int id) throws Exception;

④UserServiceImpl

public boolean delUser(int id) throws SQLException {
    boolean flag = false;
    Connection connection = BaseDao.getConnection();
    //开启事务
    try {
        connection.setAutoCommit(false);
        int i = UserDaoImpl.deleteUser(connection, id);
        connection.commit();
        if (i>0){
            System.out.println("删除用户成功");
            flag = true;
        }
    } catch (Exception e) {
        connection.rollback();
        e.printStackTrace();
    }finally {
        BaseDao.closeResource(connection, null, null);
    }
    return flag;
}

⑤Servlet

private void deluser(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    boolean flag = false;
    String userid = req.getParameter("uid");
    System.out.println("Servlet--deluser"+userid);
    Map<String, String> map = new HashMap<String, String>();//返回给json键值对
    if (StringUtils.isNullOrEmpty(userid)){
        map.put("delResult", "notexist");
    }else {
        UserLoginServiceImpl userService = new UserLoginServiceImpl();
        Integer uid = Integer.valueOf(userid);
        try {
            flag = userService.delUser(uid);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        if (flag){
            map.put("delResult", "true");
        }else {
            map.put("delResult", "false");
        }
    }
    //写出json
    PrintWriter writer = resp.getWriter();
    resp.setContentType("application/json");
    String s = JSONArray.toJSONString(map);
    writer.write(s);
    writer.flush();
    writer.close();
}

项目搭建

Empty Project
Project
File - Module

文件上传和下载

在web应用中,文件上传和下载功能是非常常用的功能。

准备工作

  1. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的。
  2. 一般选择采用apache的开源工具common-fileupload这个文件上传组件;
  3. common-fileupload是依赖于common-io这个包的,所以还需要下载这个包

使用类介绍

文件上传注意事项(上传文件调优方法)

  1. 为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放在WEB-INF目录下。
  2. 为防止文件覆盖的现象发生,要为上传文件产生一个 唯一的文件名。(时间戳+uuid(生成随机且不会重复的数字)、md5、位运算算法)
  3. 要限制上传文件的最大值。(服务器要钱)
  4. 可以限制上传文件的类型 ,在收到上传文件名时,判断后缀名是否合法。

需要用到的类详解

  1. ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象,在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象。所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象,通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性。

  2. ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中,使用其parseRequest(HttpServletRequest)方法可以将通过表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回。使用该方法处理上传文件简单易用。

  3. FileItem类

    在HTML页面input必须有name <input type="file" name="filename">

    表单如果包含一个文件上传输入项的话,这个表单的enctype属性就必须设置为multipart/form-data

<!--浏览器表单的类型如果为multipart/form-data,在服务器端想获取数据就要通过流。--><form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post">    上传用户:<input type="text" name="username"><br/>    上传文件1:<input type="file" name="file1"><br/>    上传文件2:<input type="file" name="file2"><br/>    <input type="submit" value="提交"></form>

常用方法

isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单,还是一个文件表单;如果是普通表单字段则返回true,否则返回falseboolean isFormField();getFieldName方法用于返回表单标签name属性的值String getFieldName();getString方法用于将FileItem对象中保存的数据流内容以一个字符串返回String getString();getName方法用于获得文件上传字段中的文件名String getName();以流的形式返回上传文件的数据内容InputStream getInputStream()delete方法用于清空FileItem类对象中存放的主体内容;如果主体内容被保存在临时文件中,delete方法将删除该临时文件void delete();

img

img

img

img

img

判断上传的文件是普通表单还是文件表单

邮件发送

  1. 要在网络上实现邮件功能,必须要有专门的邮件服务器。
  2. 这些邮件服务器类似于显示生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
  3. SMTP服务器地址:一般是smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com。
  4. 电子邮箱(E-Mail地址)的获得需要在邮件服务器上进行申请。比如我们要使用QQ邮箱,就需要开通邮箱功能;

img

传输协议

SMTP协议
发送邮件:
我们通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。

POP3协议
接收邮件:
我们通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。

使用java发送E-mail十分简单,但是首先你应该准备JavaMail API和Java Activation Framework。
得到两个jar包
mail.jar
activation.jar

MIME:多用途互联网邮件扩展类型
它是一个互联网标准,扩展了电子邮件标准,使其能够支持:

- 声音、图像、视频、- 附件

MimeBodyPart类
javax.mail.internet.MimeBodyPart类表示的是一个MIME消息,它和MimeMessage类一样都是从Part接口继承过来。
MimeMultipart类
javax.mail.internet.MimeMultipart是抽象类Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象。

微服务项目

File - new Project - Spring Initializr - next - next

给TA打赏
共{{data.count}}人
人已打赏
JavaWebJava笔记

JavaWeb之邮件发送

2021-12-29 18:05:08

Java笔记笔记分享

Mybatis

2022-1-4 20:14:15

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
购物车
优惠劵
有新私信 私信列表
搜索