基本ServletWEB專案

薩拉蒂亞發表於2021-09-12

專案搭建

  • 專案連結https://gitee.com/zhangjzm/smbms.git
  • 前置知識,Servlet JSP

結構圖

搭建maven web專案

  • 1.搭建一個maven web專案

  • 2.配置tomcat

  • 3.測試專案是否能跑起來

  • 4.匯入專案中遇到的jar包

    • jsp,servlet,mysql驅動,jstl,standard
  • 5.建立專案包結構

  • 6.編寫實體類

    • ORM對映:表-類對映
  • 7.編寫基礎公共類

    • 1)資料庫配置檔案
    • 2)編寫資料庫的公共類
  • ------四部曲,1.使用Properties(IO流)獲取連線資料 2.進行連線 3.執行體(ResultSet或int) 4.關閉流

  • Properties物件類似Key Value取值

  • InputStream inputStream = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");

  • 類載入器 .class.getClassLoader().getResourceAsStream取值

  • properties.load(inputStream);//IO流取值

  • 本質----------------獲取資料庫資料

POJO --- 提供一個實體,對物件的基本操作啊,set,get值
Dao --- 提供資料-怎麼提供?--依照你輸入的引數獲取想要的返回(返回物件需new物件)
Service --- 資料處理--怎麼處理?--引入dao,拿到dao的資料封裝一下(這麼做的意義?Controller直接拿dao不好嗎?)
作用:---實現本層資料共享(不同controller都可以呼叫Service)---1.獲取資料---2.對資料進行處理,如:判別,對資料進行計算
怎麼處理的? 通過入參啊,然後呼叫dao的進行處理啊。。。

  • 答:1.從引入dao來說,如果你直接由controller來進行,那麼DAO發生替換(比如從oracle遷移mysql),需要找到所有controller裡的呼叫點,逐一修改。
  • 2.如果每個判別,操作都由controller來進行,那麼同層的controller並不能互通(處理資料),比如:折扣計算,反作弊判定

Controller

  package com.zjz.dao;
  
  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 {
          Properties properties = new Properties();
          //通過類載入器讀取對應的資源
          InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
          try {
              properties.load(is);
          } catch (IOException e) {
              e.printStackTrace();
          }
  
          driver = properties.getProperty("driver");
          url = properties.getProperty("url");
          username = properties.getProperty("username");
          password = properties.getProperty("password");
  
      }
  
      //獲取資料的連線
      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,String sql,Object[] params,ResultSet resultSet, PreparedStatement preparedStatement) throws SQLException {
          preparedStatement = connection.prepareStatement(sql);
          int len = params.length;
          for(int i = 0;i<len;i++){
              //setObject 佔位符從1開始,陣列是從0開始
              preparedStatement.setObject(i+1,params[i]);
          }
          resultSet = preparedStatement.executeQuery();
          return resultSet;
      }
  
  
      //編寫增刪改公共方法
      public static int execute(Connection connection,String sql,Object[] params, PreparedStatement preparedStatement) throws SQLException {
          preparedStatement = connection.prepareStatement(sql);
          int len = params.length;
          for(int i = 0;i<len;i++){
              //setObject 佔位符從1開始,陣列是從0開始
              preparedStatement.setObject(i+1,params[i]);
          }
          int updateRows = preparedStatement.executeUpdate();
          return updateRows;
      }
  
      //釋放資源
      public static boolean closeResource(Connection connection,ResultSet resultSet, PreparedStatement preparedStatement){
          boolean flag = true;
          if(resultSet!=null){
              try {
                  resultSet.close();
                  //GC回收
                  resultSet = null;
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
                  flag = false;
              }
          }
  
          if(connection!=null){
              try {
                  connection.close();
                  //GC回收
                  connection = null;
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
                  flag = false;
              }
          }
  
  
          if(preparedStatement!=null){
              try {
                  preparedStatement.close();
                  //GC回收
                  preparedStatement = null;
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
                  flag = false;
              }
          }
  
      return flag; 
      }
  
  }

  • 8.編寫字元編碼過濾器
    • Filter類
    • web配置

功能一 登入功能的實現

編寫

  • 1.編寫前端
  • 2.設定首頁,web.xml
  <!--設定歡迎頁面-->
    <welcome-file-list>
        <welcome-file>/login.jsp</welcome-file>
    </welcome-file-list>
  • 3.編寫dao層,使用者登入的介面
  public interface UserDao {
      //得到要登入的使用者
      public User getLoginUser(Connection connection,String userCode) throws SQLException;
  }

  • 4.編寫dao介面實現類
  public class UserDaoImpl implements UserDao{
    public User getLoginUser(Connection connection, String userCode) throws SQLException {

        PreparedStatement pstm = null;
        ResultSet rs = null;
        User user = null;
        if(connection != null){
            String  sql = "select * from smbms_user where userCode = ?";
            Object[] params = {userCode};

            rs = BaseDao.execute(connection, pstm, 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.getTimestamp("creationDate"));
                user.setModifyBy(rs.getInt("modifyBy"));
                user.setModifyDate(rs.getTimestamp("modifyDate"));

            }
            BaseDao.closeResource(null,pstm,rs);

        }
        return user;
    }
 }

  • 5.業務層介面
      public interface UserService {
      //使用者登入
      public User login(String userCode, String password);
    }
    
    
  • 6.業務層實現類
  public class UserServiceImpl implements UserService{
  
      //業務層都會呼叫dao層,所以我們要引入dao層
      private UserDao userDao;
      public UserServiceImpl() {
          userDao = new UserDaoImpl();
      }
      public User login(String userCode, String password) {
          Connection connection = null;
          User user = null;
          try {
              connection = BaseDao.getConnection();
              //通過業務層呼叫具體的資料庫操作
              user = userDao.getLoginUser(connection,userCode);
          } catch (SQLException throwables) {
              throwables.printStackTrace();
          }finally {
              BaseDao.closeResource(connection,null,null);
          }
          return user;
      }
  
      @Test
      public void test(){
          UserServiceImpl userService = new UserServiceImpl();
          User wen = userService.login("wen", "123");
          System.out.println("密碼為:" + wen.getUserPassword());
  
  
      }
  }
  • 7.servlet層實現
  public class LoginServlet extends HttpServlet {
  
      //Servlet:控制層,呼叫業務層程式碼
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          System.out.println("LoginServlet---start");
          //獲取使用者的使用者名稱和密碼
          String userCode = req.getParameter("userCode");
          String userPassword = req.getParameter("userPassword");
  
          //和使用者資料庫中的密碼對比,呼叫業務層
          UserService userService = new UserServiceImpl();
          User user = userService.login(userCode, userPassword);//登入的人查出來
  
            if(user != null&&(user.getUserPassword().equals(userPassword))){//查到有這個人
              //將使用者的資訊放到session中
              req.getSession().setAttribute(Constants.USER_SESSION,user);
              //跳轉到主頁
              resp.sendRedirect("jsp/frame.jsp");
          }else {//查無此人
              //轉發回登入頁面,並提示錯誤
              req.setAttribute("error","使用者名稱,密碼不正確");
              req.getRequestDispatcher("login.jsp").forward(req,resp);
          }
      }
  
      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          doGet(req, resp);
      }
  }

  • 8.註冊servle
     <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.zjz.servlet.user.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>
  • 9.編寫過濾器,攔截沒登入的
  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 request = (HttpServletRequest) servletRequest;
          HttpServletResponse response = (HttpServletResponse)servletResponse;
          //從session中獲取使用者
          User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
          if(user==null){//說明已經登出了
              response.sendRedirect("/error.jsp");
          }else {
              filterChain.doFilter(servletRequest,servletResponse);
          }
      }
  
      public void destroy() {
      }
  }

  <!--使用者登入過濾器-->
    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.zjz.Filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <url-pattern>/jsp/*</url-pattern>
    </filter-mapping>
  • 10.由底層向上層寫

功能二,修改密碼-修當前的

修改所有的,還是修改當前的---兩個可以呼叫同一個DAO(修改),但業務就不一樣了吧,修當前的id需要通過session獲取吧。

編寫

  • 設定文字型別
    resp.setContentType("application/json"); // setContentType 設定文字的型別

功能三,使用者介面

編寫

看到的頁面顯示多少條,當前頁碼,都得與當前的使用者list繫結
每次點選切換的時候也就是再次執行SQL進行分頁的處理,並不是同一批資料分割開。。。(可利用前端進行分割--)
所以總數量的獲取需要單獨寫一個SQL
總數量的作用就是,幫助我們顯示有幾頁
跳轉由前端獲取頁數,或者上一頁,下一頁由前端引數直接控制

  • 總體思路,使用者展示
    • List<User> userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
    • 總數量--返回一個總數量
    • 分頁Bean 專用於分頁。。也就是一個服務類,利用總數量服務currentPageNo動態變化

  • 1.匯入分頁的工具類

  • 2.使用者列表的匯入

    • userlist.jsp
  • 1.獲取使用者數量

    • UserDao UserDaoImpl UserService UserServiceImpl
  • 2.分頁的邏輯

    • 在資料庫中分頁使用 Limit startIndex,pageSize; 總數
    • 0,5--第1頁-- 6,5--第2頁-- 11,5--第3頁----每頁五個
    • 當前頁 (當前頁-1) * 頁面大小
  • 3.獲取使用者列表

    • userdao
    
          public List<User> getUserList(Connection connection,String username,int userRole,int currentPageNo,int pageSize)throws Exception;
    
    
    • userdaoImpl UserService UserServiceImpl
  • 4.使用者顯示的servlet

    • 1.獲取使用者前端的資料(查詢)
    • 2.判斷請求是否需要執行,看引數的值判斷
    • 3.為了實現分頁,需要計算當前頁面的總頁面,以及頁面大小
    • 4.使用者前端展示
    • 5.返回前端

              -------- 更多學習  https://zhangjzm.gitee.io/self_study

相關文章